aboutsummaryrefslogtreecommitdiff
path: root/plugin/move.vim
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/move.vim')
-rw-r--r--plugin/move.vim62
1 files changed, 61 insertions, 1 deletions
diff --git a/plugin/move.vim b/plugin/move.vim
index 0ed2e7f..88680cd 100644
--- a/plugin/move.vim
+++ b/plugin/move.vim
@@ -1,5 +1,65 @@
onoremap <silent> a% V<cmd>call search('{') <bar> normal! %<cr>
-onoremap <silent> i% <cmd>call search('{') <bar> normal! v%<bs>o<space><cr>
+onoremap <silent> i% <cmd>call search() <bar> normal! v%<bs>o<space><cr>
vnoremap <silent> a% <esc>V/{<cr>%
vnoremap <silent> i% <esc>/{<cr>v%<bs>o<space>o
+
+"
+" 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 <silent> anb <cmd>call <sid>inner_next(v:operator, 'a', '(', ')')<cr>
+onoremap <silent> inb <cmd>call <sid>inner_next(v:operator, 'i', '(', ')')<cr>
+vnoremap <silent> anb <cmd>call <sid>inner_next(v:operator, 'a', '(', ')')<cr>
+vnoremap <silent> inb <cmd>call <sid>inner_next(v:operator, 'i', '(', ')')<cr>
+
+onoremap <silent> anB <cmd>call <sid>inner_next(v:operator, 'a', '{', '}')<cr>
+onoremap <silent> inB <cmd>call <sid>inner_next(v:operator, 'i', '{', '}')<cr>
+vnoremap <silent> anB <cmd>call <sid>inner_next(v:operator, 'a', '{', '}')<cr>
+vnoremap <silent> inB <cmd>call <sid>inner_next(v:operator, 'i', '{', '}')<cr>
+
+onoremap <silent> an< <cmd>call <sid>inner_next(v:operator, 'a', '<', '>')<cr>
+onoremap <silent> in< <cmd>call <sid>inner_next(v:operator, 'i', '<', '>')<cr>
+vnoremap <silent> an< <cmd>call <sid>inner_next(v:operator, 'a', '<', '>')<cr>
+vnoremap <silent> in< <cmd>call <sid>inner_next(v:operator, 'i', '<', '>')<cr>
+
+onoremap <silent> an[ <cmd>call <sid>inner_next(v:operator, 'a', '\[', '\]')<cr>
+onoremap <silent> in[ <cmd>call <sid>inner_next(v:operator, 'i', '\[', '\]')<cr>
+vnoremap <silent> an[ <cmd>call <sid>inner_next(v:operator, 'a', '\[', '\]')<cr>
+vnoremap <silent> in[ <cmd>call <sid>inner_next(v:operator, 'i', '\[', '\]')<cr>
+
+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 \<esc>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! \<esc>v%\<space>o\<bs>"
+ else
+ exec "normal! \<esc>v%"
+ endif
+endfunction