diff options
author | Josh Rahm <rahm@google.com> | 2022-08-27 13:11:02 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-08-27 13:11:02 -0600 |
commit | 8a1c3a51721c2beb0f3bee92589ffbe88b8d3cbc (patch) | |
tree | 3805c8204c32eecb4cb4de99e0372bcf40dd5779 | |
parent | 808365207f49b6c6aba766ffbaa6336a9410a860 (diff) | |
download | fieldmarshal.vim-8a1c3a51721c2beb0f3bee92589ffbe88b8d3cbc.tar.gz fieldmarshal.vim-8a1c3a51721c2beb0f3bee92589ffbe88b8d3cbc.tar.bz2 fieldmarshal.vim-8a1c3a51721c2beb0f3bee92589ffbe88b8d3cbc.zip |
subwords.vim: More features
* Add ability to repeat motion with ,/;
* Add ability to disable bindings
* Change motions to +/-
-rw-r--r-- | plugin/subwords.vim | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/plugin/subwords.vim b/plugin/subwords.vim index e31796c..bab15cf 100644 --- a/plugin/subwords.vim +++ b/plugin/subwords.vim @@ -8,29 +8,88 @@ " of snake_case identifier will include the underscores (_). The 'i_' references " the ci_ -onoremap <silent> i- :<c-u>exec "norm " . <sid>v_subword(v:true, v:false)<cr> -vnoremap <silent> i- :<c-u>exec "norm " . <sid>v_subword(v:true, v:false)<cr> -onoremap <silent> a- :<c-u>exec "norm " . <sid>v_subword(v:true, v:true)<cr> -vnoremap <silent> a- :<c-u>exec "norm " . <sid>v_subword(v:true, v:true)<cr> +onoremap <silent> <Plug>(inner-sub-word) :<c-u>exec "norm " . <sid>v_subword(v:true, v:false)<cr> +vnoremap <silent> <Plug>(inner-sub-word) :<c-u>exec "norm " . <sid>v_subword(v:true, v:false)<cr> +onoremap <silent> <Plug>(around-sub-word) :<c-u>exec "norm " . <sid>v_subword(v:true, v:true)<cr> +vnoremap <silent> <Plug>(around-sub-word) :<c-u>exec "norm " . <sid>v_subword(v:true, v:true)<cr> + +if ! exists('g:subwords_include_bindings') + let g:subwords_include_bindings = 1 +endif + +if g:subwords_include_bindings + onoremap <silent> i- <Plug>(inner-sub-word) + vnoremap <silent> i- <Plug>(inner-sub-word) + onoremap <silent> a- <Plug>(around-sub-word) + vnoremap <silent> a- <Plug>(around-sub-word) +endif " These mappings are the same as above, except prefer_camel is turned off, so " snake case is used in the case of a conflict. -onoremap <silent> i_ :<c-u>exec "norm " . <sid>v_subword(v:false, v:false)<cr> -vnoremap <silent> i_ :<c-u>exec "norm " . <sid>v_subword(v:false, v:false)<cr> -onoremap <silent> a_ :<c-u>exec "norm " . <sid>v_subword(v:false, v:true)<cr> -vnoremap <silent> a_ :<c-u>exec "norm " . <sid>v_subword(v:false, v:true)<cr> +onoremap <silent> <Plug>(inner-sub-word-prefer-snake) :<c-u>exec "norm " . <sid>v_subword(v:false, v:false)<cr> +vnoremap <silent> <Plug>(inner-sub-word-prefer-snake) :<c-u>exec "norm " . <sid>v_subword(v:false, v:false)<cr> +onoremap <silent> <Plug>(around-sub-word-prefer-snake) :<c-u>exec "norm " . <sid>v_subword(v:false, v:true)<cr> +vnoremap <silent> <Plug>(around-sub-word-prefer-snake) :<c-u>exec "norm " . <sid>v_subword(v:false, v:true)<cr> + +if g:subwords_include_bindings + onoremap <silent> i_ <Plug>(inner-sub-word-prefer-snake) + vnoremap <silent> i_ <Plug>(inner-sub-wor-prefer-snaked) + onoremap <silent> a_ <Plug>(around-sub-wor-prefer-snaked) + vnoremap <silent> a_ <Plug>(around-sub-wor-prefer-snaked) +endif " Movement keys for subwords. These all have prefer_camel set to true, the idea " being it's pretty easy to navigate underscores with f_ and t_, but more " difficult to navigate upper case letters. -noremap <silent> <M--> :<c-u>silent! call <SID>next_subword(v:false, v:true)<cr> -noremap <silent> <M-_> :<c-u>silent! call <SID>next_subword(v:false, v:false)<cr> -vnoremap <silent> <M--> v:<c-u>silent! call <SID>next_subword(v:true, v:true)<cr>m'gv`` -vnoremap <silent> <M-_> v:<c-u>silent! call <SID>next_subword(v:true, v:false)<cr>m'gv`` +noremap <silent> <Plug>(next-subword) :<c-u>silent! call <SID>next_subword(v:false, v:true)<cr> +noremap <silent> <Plug>(prev-subword) :<c-u>silent! call <SID>next_subword(v:false, v:false)<cr> +vnoremap <expr> <silent> <Plug>(next-subword) visualmode() . ":\<c-u>silent! call \<SID>next_subword(visualmode(), v:true)\<cr>m'gv``" +vnoremap <expr> <silent> <Plug>(prev-subword) visualmode() . ":\<c-u>silent! call \<SID>next_subword(visualmode(), v:false)<cr>m'gv``" + +let s:subword_motion = "" +let s:subword_nosave = 0 + +if g:subwords_include_bindings + + function! s:clear_subword_mark() + let s:subword_motion = "" + return '' + endfunction + + function! s:subword_repeat(char) + if s:subword_motion == '' + return a:char + endif + + let mot = (s:subword_motion == 'next') != (a:char == ',') + + let s:subword_nosave = 1 + if mot + return "\<Plug>(next-subword)" + else + return "\<Plug>(prev-subword)" + endif + endfunction + + noremap + <Plug>(next-subword) + vnoremap + <Plug>(next-subword) + noremap - <Plug>(prev-subword) + vnoremap - <Plug>(prev-subword) + + " tetetetetetetete_tetete_tetesasa + + noremap <expr> <silent> ; <SID>subword_repeat(';') + noremap <expr> <silent> , <SID>subword_repeat(',') + vnoremap <expr> <silent> ; <SID>subword_repeat(';') + vnoremap <expr> <silent> , <SID>subword_repeat(',') + + noremap <expr> <silent> t <SID>clear_subword_mark() . "t" + noremap <expr> <silent> f <SID>clear_subword_mark() . "f" +endif " Return the type of meta-word (i.e. camelCase, snake_case). If " a:prefer_camel is set, then a word like ThisIs_A_MixOfCamel_And_Snake will -" some_snake_case SomeCamelCase SOME_CONSTANT_CASE +" some_snake_cae SomeCamelCase SOME_CONSTANT_CASE " return 'camel', otherwise it'll return 'snake'. function! s:detect_word_type(prefer_camel, word) abort let is_camel = 0 @@ -57,12 +116,22 @@ function! s:detect_word_type(prefer_camel, word) abort endfunction function! s:next_subword(vis, forward) + if ! s:subword_nosave + if a:forward + let s:subword_motion = 'next' + else + let s:subword_motion = 'prev' + endif + endif + let i = 0 while i < v:count1 call search( \ '\([a-z]\zs[A-Z]\ze\)\|\(\W\|_\)\zs\w\ze', (a:forward ? '' : 'b')) let i += 1 endwhile + + let s:subword_nosave = 0 endfunction " Highlight an inner subword. |