From 8a1c3a51721c2beb0f3bee92589ffbe88b8d3cbc Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Sat, 27 Aug 2022 13:11:02 -0600 Subject: subwords.vim: More features * Add ability to repeat motion with ,/; * Add ability to disable bindings * Change motions to +/- --- plugin/subwords.vim | 95 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 13 deletions(-) (limited to 'plugin') 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 i- :exec "norm " . v_subword(v:true, v:false) -vnoremap i- :exec "norm " . v_subword(v:true, v:false) -onoremap a- :exec "norm " . v_subword(v:true, v:true) -vnoremap a- :exec "norm " . v_subword(v:true, v:true) +onoremap (inner-sub-word) :exec "norm " . v_subword(v:true, v:false) +vnoremap (inner-sub-word) :exec "norm " . v_subword(v:true, v:false) +onoremap (around-sub-word) :exec "norm " . v_subword(v:true, v:true) +vnoremap (around-sub-word) :exec "norm " . v_subword(v:true, v:true) + +if ! exists('g:subwords_include_bindings') + let g:subwords_include_bindings = 1 +endif + +if g:subwords_include_bindings + onoremap i- (inner-sub-word) + vnoremap i- (inner-sub-word) + onoremap a- (around-sub-word) + vnoremap a- (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 i_ :exec "norm " . v_subword(v:false, v:false) -vnoremap i_ :exec "norm " . v_subword(v:false, v:false) -onoremap a_ :exec "norm " . v_subword(v:false, v:true) -vnoremap a_ :exec "norm " . v_subword(v:false, v:true) +onoremap (inner-sub-word-prefer-snake) :exec "norm " . v_subword(v:false, v:false) +vnoremap (inner-sub-word-prefer-snake) :exec "norm " . v_subword(v:false, v:false) +onoremap (around-sub-word-prefer-snake) :exec "norm " . v_subword(v:false, v:true) +vnoremap (around-sub-word-prefer-snake) :exec "norm " . v_subword(v:false, v:true) + +if g:subwords_include_bindings + onoremap i_ (inner-sub-word-prefer-snake) + vnoremap i_ (inner-sub-wor-prefer-snaked) + onoremap a_ (around-sub-wor-prefer-snaked) + vnoremap a_ (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! call next_subword(v:false, v:true) -noremap :silent! call next_subword(v:false, v:false) -vnoremap v:silent! call next_subword(v:true, v:true)m'gv`` -vnoremap v:silent! call next_subword(v:true, v:false)m'gv`` +noremap (next-subword) :silent! call next_subword(v:false, v:true) +noremap (prev-subword) :silent! call next_subword(v:false, v:false) +vnoremap (next-subword) visualmode() . ":\silent! call \next_subword(visualmode(), v:true)\m'gv``" +vnoremap (prev-subword) visualmode() . ":\silent! call \next_subword(visualmode(), v:false)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 "\(next-subword)" + else + return "\(prev-subword)" + endif + endfunction + + noremap + (next-subword) + vnoremap + (next-subword) + noremap - (prev-subword) + vnoremap - (prev-subword) + + " tetetetetetetete_tetete_tetesasa + + noremap ; subword_repeat(';') + noremap , subword_repeat(',') + vnoremap ; subword_repeat(';') + vnoremap , subword_repeat(',') + + noremap t clear_subword_mark() . "t" + noremap f 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. -- cgit