From ae428bff031abe75779515101dd1665b2c542c7c Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Thu, 15 Sep 2022 12:42:52 -0600 Subject: move.vim: add some more movements anb and friends. Like ib, except always go to the next body regardless of if already in one. similar mappings for an<, anB, an[ --- plugin/move.vim | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/plugin/move.vim b/plugin/move.vim index 8d11d22..88680cd 100644 --- a/plugin/move.vim +++ b/plugin/move.vim @@ -1,7 +1,65 @@ onoremap a% Vcall search('{') normal! % -onoremap i% call search('{') normal! v%o +onoremap i% call search() normal! v%o vnoremap a% V/{% vnoremap i% /{v%oo -onoremap gv gv +" +" anb, anB, an<, an[ +" +" "Next" objects. These objects are like ab, aB, a<, a[, etc. but will always go to the next body +" regardless of if it is nested or not. +" +" If outside an expression, the behavior is the +" +onoremap anb call inner_next(v:operator, 'a', '(', ')') +onoremap inb call inner_next(v:operator, 'i', '(', ')') +vnoremap anb call inner_next(v:operator, 'a', '(', ')') +vnoremap inb call inner_next(v:operator, 'i', '(', ')') + +onoremap anB call inner_next(v:operator, 'a', '{', '}') +onoremap inB call inner_next(v:operator, 'i', '{', '}') +vnoremap anB call inner_next(v:operator, 'a', '{', '}') +vnoremap inB call inner_next(v:operator, 'i', '{', '}') + +onoremap an< call inner_next(v:operator, 'a', '<', '>') +onoremap in< call inner_next(v:operator, 'i', '<', '>') +vnoremap an< call inner_next(v:operator, 'a', '<', '>') +vnoremap in< call inner_next(v:operator, 'i', '<', '>') + +onoremap an[ call inner_next(v:operator, 'a', '\[', '\]') +onoremap in[ call inner_next(v:operator, 'i', '\[', '\]') +vnoremap an[ call inner_next(v:operator, 'a', '\[', '\]') +vnoremap in[ call inner_next(v:operator, 'i', '\[', '\]') + +function! s:inner_next(operator, ai, open, close) abort + let opos = getpos('.') + let i = 0 + + while i < v:count + 1 + call search(a:open) + let i += 1 + endwhile + + normal! % + if (getline('.')[col('.')-1] =~ a:open) + normal! % + endif + + if col('.') > 1 && (getline('.')[col('.')-2] =~ a:open) && a:ai == 'i' + if v:operator =~ "[cd]" + " Cheese a 0-width by inserting a space to then immediately delete for d and c operators. + exec "normal! i \v" + else + " Other operations, just reset the position to what it was before. + call setpos('.', opos) + endif + return + endif + + if a:ai == 'i' + exec "normal! \v%\o\" + else + exec "normal! \v%" + endif +endfunction -- cgit