Created
September 8, 2024 23:12
-
-
Save mike-clark-8192/ef997fc42a4527e42012dba44f8434b6 to your computer and use it in GitHub Desktop.
Modification of commentary-vim that allows for case-insensitive matching of comment delimiters (e.g., `rem` is no different from `REM` in dosbatch)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" commentary.vim - Comment stuff out | |
" Maintainer: Tim Pope <http://tpo.pe/> | |
" Version: 1.3 | |
" echomsg "commentary.vim: before g:loaded_commentary=" . get(g:, 'loaded_commentary', 0) | |
echom a | |
if exists("g:loaded_commentary") || v:version < 703 | |
finish | |
endif | |
let g:loaded_commentary = 1 | |
" echomsg "commentary.vim: after g:loaded_commentary=" . get(g:, 'loaded_commentary', 0) | |
function! s:surroundings() abort | |
return split(get(b:, 'commentary_format', substitute(substitute(substitute( | |
\ &commentstring, '^$', '%s', ''), '\S\zs%s',' %s', '') ,'%s\ze\S', '%s ', '')), '%s', 1) | |
endfunction | |
" Case-insensitive or case-sensitive equality comparison. | |
function! s:cased_eq(l, r) abort | |
if exists('b:commentary_caseinsensitive') && b:commentary_caseinsensitive | |
return a:l ==? a:r | |
else | |
return a:l ==# a:r | |
endif | |
endfunction | |
" Case-insensitive or case-sensitive regex match. | |
function! s:cased_match(line, pattern) abort | |
if exists('b:commentary_caseinsensitive') && b:commentary_caseinsensitive | |
return a:line =~? a:pattern | |
else | |
return a:line =~# a:pattern | |
endif | |
endfunction | |
function! s:cased_stridx(haystack, needle) abort | |
let haystack = a:haystack | |
let needle = a:needle | |
if exists('b:commentary_caseinsensitive') && b:commentary_caseinsensitive | |
let haystack = tolower(a:haystack) | |
let needle = tolower(a:needle) | |
endif | |
return stridx(haystack, needle) | |
endfunction | |
function! s:strip_white_space(l, r, line) abort | |
let [l, r] = [a:l, a:r] | |
if s:cased_eq(l[-1:], ' ') && s:cased_stridx(a:line, l) == -1 && s:cased_stridx(a:line, l[0:-2]) == 0 | |
let l = l[:-2] | |
endif | |
if s:cased_eq(r[0], ' ') && (' ' . a:line)[-strlen(r)-1:] != r && a:line[-strlen(r):] == r[1:] | |
let r = r[1:] | |
endif | |
return [l, r] | |
endfunction | |
function! s:go(...) abort | |
if !a:0 | |
" echom "s:go() a:0==0; operatorfunc + g@" | |
let &operatorfunc = matchstr(expand('<sfile>'), '[^. ]*$') | |
return 'g@' | |
elseif a:0 > 1 | |
" echom "s:go() a:0>1; a:1=" . a:1 . " a:2=" . a:2 . " a:3=" . a:3 | |
let [lnum1, lnum2] = [a:1, a:2] | |
else | |
" echom "s:go() a:0==1; line('[')=" . line("["). " line(']')=" . line("]") | |
let [lnum1, lnum2] = [line("'["), line("']")] | |
endif | |
let [l, r] = s:surroundings() | |
let uncomment = 2 | |
let force_uncomment = a:0 > 2 && a:3 | |
for lnum in range(lnum1, lnum2) | |
let line = matchstr(getline(lnum), '\S.*\s\@<!') | |
let [l, r] = s:strip_white_space(l, r, line) | |
if len(line) && (s:cased_stridx(line, l) || line[strlen(line) - strlen(r) : -1] != r) | |
let uncomment = 0 | |
endif | |
endfor | |
if get(b:, 'commentary_startofline') | |
let indent = '^' | |
else | |
let indent = '^\s*' | |
endif | |
let lines = [] | |
for lnum in range(lnum1, lnum2) | |
let line = getline(lnum) | |
if strlen(r) > 2 && !s:cased_match(l.r, '\\') | |
let line = substitute(line, | |
\ '\M' . substitute(l, '\ze\S\s*$', '\\zs\\d\\*\\ze', '') . '\|' . substitute(r, '\S\zs', '\\zs\\d\\*\\ze', ''), | |
\ '\=substitute(submatch(0)+1-uncomment,"^0$\\|^-\\d*$","","")', 'g') | |
endif | |
if force_uncomment | |
if s:cased_match(line, '^\s*' . l) | |
let line = substitute(line,'\S.*\s\@<!','\=submatch(0)[strlen(l):-strlen(r)-1]','') | |
endif | |
elseif uncomment | |
let line = substitute(line,'\S.*\s\@<!','\=submatch(0)[strlen(l):-strlen(r)-1]','') | |
else | |
let line = substitute(line,'^\%('.matchstr(getline(lnum1),indent).'\|\s*\)\zs.*\S\@<=','\=l.submatch(0).r','') | |
endif | |
call add(lines, line) | |
endfor | |
call setline(lnum1, lines) | |
let modelines = &modelines | |
try | |
set modelines=0 | |
silent doautocmd User CommentaryPost | |
finally | |
let &modelines = modelines | |
endtry | |
return '' | |
endfunction | |
function! s:textobject(inner) abort | |
let [l, r] = s:surroundings() | |
let lnums = [line('.')+1, line('.')-2] | |
for [index, dir, bound, line] in [[0, -1, 1, ''], [1, 1, line('$'), '']] | |
while lnums[index] != bound && line ==# '' || !(s:cased_stridx(line,l) || line[strlen(line)-strlen(r) : -1] != r) | |
let lnums[index] += dir | |
let line = matchstr(getline(lnums[index]+dir),'\S.*\s\@<!') | |
let [l, r] = s:strip_white_space(l,r,line) | |
endwhile | |
endfor | |
while (a:inner || lnums[1] != line('$')) && empty(getline(lnums[0])) | |
let lnums[0] += 1 | |
endwhile | |
while a:inner && empty(getline(lnums[1])) | |
let lnums[1] -= 1 | |
endwhile | |
if lnums[0] <= lnums[1] | |
execute 'normal! 'lnums[0].'GV'.lnums[1].'G' | |
endif | |
endfunction | |
command! -range -bar -bang Commentary call s:go(<line1>,<line2>,<bang>0) | |
xnoremap <expr> <Plug>Commentary <SID>go() | |
nnoremap <expr> <Plug>Commentary <SID>go() | |
nnoremap <expr> <Plug>CommentaryLine <SID>go() . '_' | |
onoremap <silent> <Plug>Commentary :<C-U>call <SID>textobject(get(v:, 'operator', '') ==# 'c')<CR> | |
nnoremap <silent> <Plug>ChangeCommentary c:<C-U>call <SID>textobject(1)<CR> | |
if !hasmapto('<Plug>Commentary') || maparg('gc','n') ==# '' | |
xmap gc <Plug>Commentary | |
nmap gc <Plug>Commentary | |
omap gc <Plug>Commentary | |
nmap gcc <Plug>CommentaryLine | |
nmap gcu <Plug>Commentary<Plug>Commentary | |
endif | |
nmap <silent> <Plug>CommentaryUndo :echoerr "Change your <Plug>CommentaryUndo map to <Plug>Commentary<Plug>Commentary"<CR> | |
" vim:set et sw=2: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment