diff options
author | Josh Rahm <rahm@google.com> | 2022-09-12 18:23:45 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-09-12 18:23:45 -0600 |
commit | 2f99407cd2ce0d0ffbe3f62bc31407033c06d7f7 (patch) | |
tree | 159e3f95b19834754115cff0f2e1dc13cfd17977 | |
parent | e3716c7ae015a5ea960c47d2aa4e975e93d66151 (diff) | |
download | fieldmarshal.vim-2f99407cd2ce0d0ffbe3f62bc31407033c06d7f7.tar.gz fieldmarshal.vim-2f99407cd2ce0d0ffbe3f62bc31407033c06d7f7.tar.bz2 fieldmarshal.vim-2f99407cd2ce0d0ffbe3f62bc31407033c06d7f7.zip |
commenter.vim: add commenter to comment out chunks of text
this uses a new operator 'cd' which can be thought of as 'comment-y
delete'
-rw-r--r-- | plugin/commenter.vim | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/plugin/commenter.vim b/plugin/commenter.vim new file mode 100644 index 0000000..351e2dc --- /dev/null +++ b/plugin/commenter.vim @@ -0,0 +1,105 @@ +" Function for commenting out blocks of text. + +noremap cd <cmd>set operatorfunc=<sid>comment<cr>g@ +noremap cdd <cmd>set operatorfunc=<sid>comment<cr>g@_ + +noremap cD <cmd>set operatorfunc=<sid>uncomment<cr>g@ +noremap cDD <cmd>set operatorfunc=<sid>uncomment<cr>g@_ + + " filetype, linecomment, block start, block continue, blockend, blockpad, + " inline_support +let s:comment_style = { + \ 'java': ['//', '/*', ' *', '*/', 1, 1], + \ 'c': ['//', '/*', ' *', '*/', 1, 1], + \ 'cpp': ['//', '/*', ' *', '*/', 1, 1], + \ 'vim': ['"', '"', '"', '"', 0, 0] + \ } + +function! s:modifyreg(arg, cb) abort + let save_a = getreg('a') + let save_a_type = getregtype('a') + + if a:arg == 'line' + let vis = "'[V']" + elseif a:arg == 'block' + let vis = "`[\<C-v>`]" + else + let vis = "`[v`]" + endif + silent! exec printf("norm! %s\"ay", vis) + + let ls = getreg('a', 1, 1) + let regtype = getregtype('a') + + let ls = a:cb.operate(ls) + + call setreg('a', ls, regtype) + silent! exec "norm! gv\"ap" + call setreg('a', save_a, save_a_type) +endfunction + +function! s:uncomment(arg, ...) abort + + let [line_com, bstart, bcont, bend, bpad, inl] = get(s:comment_style, &ft, ['#', '#', '#', '#', 0, 0]) + let l1 = line("'[") + let l2 = line("']") + + if inl + silent exec printf('silent! %s,%s s/\V\zs%s\s\?\ze//', l1, l2, escape(bstart, '/')) + silent exec printf('silent! %s,%s s/\V\zs\s\?%s\ze//', l1, l2, escape(bend, '/')) + endif + + silent exec printf('silent! %s,%s s/\V\^\s\*\zs%s\s\?\ze//', l1, l2, escape(line_com, '/')) + silent exec printf('silent! %s,%s s/\V\^\s\*\zs%s\s\?\ze//', l1, l2, escape(bcont, '/')) +endfunction + +function! s:comment(arg, ...) abort + let cb = { 'arg': a:arg } + + function! cb.operate(ls) dict abort + let [line_com, bstart, bcont, bend, bpad, inl] = get(s:comment_style, &ft, ['#', '#', '#', '#', 0, 0]) + let smallest = 100 + let ls = a:ls + + if self.arg != 'line' && !inl + throw "Inline comments not allowed" + endif + + if self.arg == 'line' || len(ls) > 1 + for l in ls + if ! (l =~ '^\s*$') + let sz = match(l, '^\(\s\+\)\zs\S\ze') + 1 + if sz <= 0 + let sz = 1 + endif + + if sz < smallest && sz > 0 + let smallest = sz + endif + endif + endfor + + if self.arg == 'line' + let i = 0 + while i < len(ls) + let ls[i] = substitute(ls[i], printf('\%%%dc', smallest), line_com . ' ', '') + let i += 1 + endwhile + else + let ls[0] = substitute(ls[0], '^', bstart . ' ', '') + let ls[-1] = substitute(ls[-1], '$', ' ' . bend, '') + endif + + else + let i = 0 + while i < len(ls) + let ls[i] = printf("%s %s %s", bstart, ls[i], bend) + let i += 1 + endwhile + endif + + return ls + endfunction + + call s:modifyreg(a:arg, cb) +endfunction |