From 8c82106848a9bd37d8be9e2c5cdb7c545c0af196 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Fri, 16 Sep 2022 20:00:12 +0000 Subject: commenter.vim: add acp and icp text objects. Just like ip and ap, except it excludes commment blocks. --- plugin/commenter.vim | 81 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 5 deletions(-) (limited to 'plugin') diff --git a/plugin/commenter.vim b/plugin/commenter.vim index 1855828..f903fce 100644 --- a/plugin/commenter.vim +++ b/plugin/commenter.vim @@ -13,18 +13,84 @@ vnoremap i/ call comment_obj('', 'i') onoremap a/ call comment_obj(v:operator, 'a') vnoremap a/ call comment_obj('', 'a') +" Objects for paragraphs excluding any comment blocks immediately preceeding or +" Succeeding +onoremap acp call uncommented_paragraph('a') +onoremap icp call uncommented_paragraph('i') + 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:uncommented_paragraph(t) abort + let savepos = getpos('.') + set operatorfunc=s:save_object + exec "normal! g@". a:t . "pv\" + call setpos('.', savepos) + + let [start_regex, end_regex] = g:GetCommentRegex('a') + + call search(end_regex . '\|\%^', 'cb') + exec "normal! j" + call setpos('.', s:maxpos(getpos('.'), s:object.start)) + normal! m< + call setpos('.', savepos) + + call search(start_regex . '\|\%$', 'c') + call setpos('.', s:minpos(getpos('.'), s:object.end)) + exec "normal! k" + + normal! m>gvV +endfunction function! s:regex_combine(s1, s2) abort if a:s1 == "" @@ -38,7 +104,7 @@ function! s:regex_combine(s1, s2) abort return printf('\(%s\)\|\(%s\)', a:s1, a:s2) endfunction -function! s:comment_obj(op, iOrA) +function! g:GetCommentRegex(ia) abort let style = get(s:comment_style, &ft, s:default_style) let start_regex = s:regex_combine( @@ -48,7 +114,7 @@ function! s:comment_obj(op, iOrA) \ get(style, 'multi_end_regex', ''), \ get(style, 'block_end_regex', '')) \ - if a:iOrA == 'i' + if a:ia == 'i' let start_regex = \ substitute( \ substitute(start_regex, '\V${i\(\[se]\)}', '\\z\1', 'g'), @@ -67,6 +133,11 @@ function! s:comment_obj(op, iOrA) \ 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>" @@ -76,7 +147,7 @@ function! s:comment_obj(op, iOrA) let [_, sl, sc, _] = getpos("'<") let [_, el, ec, _] = getpos("'>") - if getline(sl)[:sc - 2] =~ '^\s*$' && a:iOrA == 'a' && ec >= len(getline(el)) + if getline(sl)[:sc - 2] =~ '^\s*$' && a:ia == 'a' && ec >= len(getline(el)) exec "normal V" endif endfunction -- cgit