" Function for commenting out blocks of text. noremap cd set operatorfunc=commentg@ nnoremap cdd set operatorfunc=commentg@_ nnoremap cD set operatorfunc=commentg@$ " Comment out the rest of the line and put the cursor into insert mode nnoremap cdC call change_comment_obj('i') nnoremap cdcc call change_comment_obj('I') onoremap i/ call comment_obj(v:operator, 'i') vnoremap i/ call comment_obj('', 'i') onoremap a/ call comment_obj(v:operator, 'a') vnoremap a/ call comment_obj('', 'a') noremap czd set operatorfunc=uncommentg@ nnoremap czdd set operatorfunc=uncommentg@_ function! s:single_character_style(c) return { \ 'block_start_regex': '\(^\s*\(\(\S\)\(' . a:c . '\)\@ l2 return a:cur elseif l2 > l1 return a:oth elseif c2 > c1 return a:oth else return a:cur endif endfunction function! s:minpos(cur, oth) let [a, l1, c1, b] = a:cur let [_, l2, c2, _] = a:oth if l1 < l2 return a:cur elseif l2 < l1 return a:oth elseif c2 < c1 return a:oth else return a:cur endif endfunction function! s:regex_combine(s1, s2) abort if a:s1 == "" return a:s2 endif if a:s2 == "" return a:s1 endif return printf('\(%s\)\|\(%s\)', a:s1, a:s2) endfunction function! g:GetCommentRegex(ia) abort let style = get(s:comment_style, &ft, s:default_style) let start_regex = s:regex_combine( \ get(style, 'multi_start_regex', ''), \ get(style, 'block_start_regex', '')) let end_regex = s:regex_combine( \ get(style, 'multi_end_regex', ''), \ get(style, 'block_end_regex', '')) \ if a:ia == 'i' let start_regex = \ substitute( \ substitute(start_regex, '\V${i\(\[se]\)}', '\\z\1', 'g'), \ '\V${a\(\[se]\)}', '', 'g') let end_regex = \ substitute( \ substitute(end_regex, '\V${i\(\[se]\)}', '\\z\1', 'g'), \ '\V${a\(\[se]\)}', '', 'g') else let start_regex = \ substitute( \ substitute(start_regex, '\V${a\(\[se]\)}', '\\z\1', 'g'), \ '\V${i\(\[se]\)}', '', 'g') let end_regex = \ substitute( \ substitute(end_regex, '\V${a\(\[se]\)}', '\\z\1', 'g'), \ '\V${i\(\[se]\)}', '', 'g') endif return [start_regex, end_regex] endfunction function! s:comment_obj(op, ia) let [start_regex, end_regex] = g:GetCommentRegex(a:ia) call search(end_regex, 'c') exec "normal! v\m>" call search(start_regex, 'bW') exec "normal! m") if getline(sl)[:sc - 2] =~ '^\s*$' && a:ia == 'a' && ec >= len(getline(el)) exec "normal V" endif endfunction function! s:change_comment_obj(mv) abort let s = get(s:comment_style, &ft, s:default_style) " U allows ,,etc. to show up in the redo buff. call feedkeys(printf( \ "%s %s %s", \ a:mv, \ s.line, \ repeat("\U\", len(s.line) + 2)), 'n') endfunction let s:comment_style = { \ 'java,c,cpp,rust,go': { \ 'multi_start_regex': '${as}\/\*\([*]\|\_s\)*${is}\S', \ 'multi_end_regex': '${is}\S\_s*\*\/${as}', \ 'block_start_regex': '\(^\s*\(\(\S\S\)\(\/\/\)\@ 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), s.line . ' ', '') let i += 1 endwhile else if self.arg != 'line' && !has_key(s, 'multi_start') throw "Inline comments not allowed" endif let ls[0] = substitute(ls[0], '^', s.multi_start . ' ', '') let ls[-1] = substitute(ls[-1], '$', ' ' . s.multi_end, '') endif else let l = getline('.') if l[len(l) - len(ls[0]):] ==# ls[0] let ls[0] = printf("%s %s", s.line, ls[0]) else if !has_key(s, 'multi_start') throw "Inline comments not allowed" endif let ls[0] = printf("%s %s %s", s.multi_start, ls[0], s.multi_end) endif endif return ls endfunction call fieldmarshal#modifytext(a:arg, cb) norm `` endfunction