aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-09-12 18:23:45 -0600
committerJosh Rahm <rahm@google.com>2022-09-12 18:23:45 -0600
commit2f99407cd2ce0d0ffbe3f62bc31407033c06d7f7 (patch)
tree159e3f95b19834754115cff0f2e1dc13cfd17977
parente3716c7ae015a5ea960c47d2aa4e975e93d66151 (diff)
downloadfieldmarshal.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.vim105
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