diff options
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/subwords.vim | 222 |
1 files changed, 22 insertions, 200 deletions
diff --git a/plugin/subwords.vim b/plugin/subwords.vim index a8a38ee..067eb2c 100644 --- a/plugin/subwords.vim +++ b/plugin/subwords.vim @@ -8,10 +8,10 @@ " of snake_case identifier will include the underscores (_). The 'i_' references " the ci_ -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> +onoremap <silent> <Plug>(inner-sub-word) :<c-u>exec "norm " . subwords#visual(v:true, v:false)<cr> +vnoremap <silent> <Plug>(inner-sub-word) :<c-u>exec "norm " . subwords#visual(v:true, v:false)<cr> +onoremap <silent> <Plug>(around-sub-word) :<c-u>exec "norm " . subwords#visual(v:true, v:true)<cr> +vnoremap <silent> <Plug>(around-sub-word) :<c-u>exec "norm " . subwords#visual(v:true, v:true)<cr> if ! exists('g:subwords_include_bindings') let g:subwords_include_bindings = 1 @@ -19,206 +19,28 @@ 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> <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> +onoremap <silent> <Plug>(inner-sub-word-prefer-snake) :<c-u>exec "norm " . subwords#visual(v:false, v:false)<cr> +vnoremap <silent> <Plug>(inner-sub-word-prefer-snake) :<c-u>exec "norm " . subwords#visual(v:false, v:false)<cr> +onoremap <silent> <Plug>(around-sub-word-prefer-snake) :<c-u>exec "norm " . subwords#visual(v:false, v:true)<cr> +vnoremap <silent> <Plug>(around-sub-word-prefer-snake) :<c-u>exec "norm " . subwords#visual(v:false, v:true)<cr> " 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> <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``" - -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 <expr> <silent> <Plug>(subwords-replace-;) <SID>subword_repeat(';') -noremap <expr> <silent> <Plug>(subwords-replace-,) <SID>subword_repeat(',') -vnoremap <expr> <silent> <Plug>(subwords-replace-;) <SID>subword_repeat(';') -vnoremap <expr> <silent> <Plug>(subwords-replace-,) <SID>subword_repeat(',') - -noremap <expr> <silent> <Plug>(subwords-replace-t) <SID>clear_subword_mark() . "t" -noremap <expr> <silent> <Plug>(subwords-replace-f) <SID>clear_subword_mark() . "f" -noremap <expr> <silent> <Plug>(subwords-replace-T) <SID>clear_subword_mark() . "T" -noremap <expr> <silent> <Plug>(subwords-replace-F) <SID>clear_subword_mark() . "F" - -let s:subword_motion = "" -let s:subword_nosave = 0 - -" 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_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 - if a:word =~ '[a-z][A-Z]' - let is_camel = 1 - - if a:prefer_camel - " The word contains a camelCase boundary. - return 'camel' - endif - endif - - if a:word =~ '_' - " The word contains a sake_case boundary. - return 'snake' - endif - - if is_camel - return 'camel' - endif - - " There is not discernible type, it's probably just a single word. - return 'word' -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. -function! s:v_subword(prefer_camel, around) - - " Detect the type of the word. - let word = expand("<cword>") - let t = s:detect_word_type(a:prefer_camel, word) - - let expr = '' - - if t == 'camel' - let expr = 'v' - - let line = getline('.') - let c = col('.') - 1 - let i = 0 - - while line[c] =~ '[a-z]' && c >= 0 - let c -= 1 - let i += 1 - endwhile - - " camelCase - - if c >= 0 && ! (line[c] =~ '[A-Z_]') - " If we are at the beginning of the meta word, the don't go back too far. - let i -= 1 - endif - - if i > 0 - let expr .= printf("%dh", i) - endif - - let expr .= 'o' - - let c = col('.') - 1 - let i = 0 - - if line[c] =~ '[A-Z_]' - " Actually on the starting capital letter, include it, but start counting - " from the next character. - let i += 1 - let c += 1 - endif - - while c < len(line) && line[c] =~ '[a-z]' - let c += 1 - let i += 1 - endwhile - - if i > 1 - let expr .= printf("%dl", i - 1) - endif - - elseif t == "snake" - let expr = 'v' - - let line = getline('.') - let c = col('.') - 1 - let i = 0 - - while c >= 0 && !( line[c] =~ '\W' ) && line[c] != '_' - let c -= 1 - let i += 1 - endwhile - - let lhs_under = c >= 0 && line[c] == '_' - - let i -= 1 - let c += 1 - - if i > 0 - let expr .= printf('%dho', i) - endif - - let c = col('.') - 1 - let i = 0 - - while c < len(line) && !(line[c] =~ '\W') && line[c] != '_' - let c += 1 - let i += 1 - endwhile - - let rhs_under = c < len(line) && line[c] == '_' - - let i -= 1 - let c -= 1 - - if i > 0 - let expr .= printf('%dl', i) - endif - - if a:around - if rhs_under - let expr .= 'l' - elseif lhs_under - let expr .= 'oho' - endif - endif - - - elseif t == "word" - " Just a word? Easy peasy. - let expr = 'viw' - endif - - return expr -endfunction! +noremap <silent> <Plug>(next-subword) :<c-u>silent! call subwords#next(v:false, v:true)<cr> +noremap <silent> <Plug>(prev-subword) :<c-u>silent! call subwords#next(v:false, v:false)<cr> +vnoremap <expr> <silent> <Plug>(next-subword) visualmode() . ":\<c-u>silent! call subwords#next(visualmode(), v:true)\<cr>m'gv``" +vnoremap <expr> <silent> <Plug>(prev-subword) visualmode() . ":\<c-u>silent! call subwords#next(visualmode(), v:false)<cr>m'gv``" + +noremap <expr> <silent> <Plug>(subwords-replace-;) subwords#repeat(';') +noremap <expr> <silent> <Plug>(subwords-replace-,) subwords#repeat(',') +vnoremap <expr> <silent> <Plug>(subwords-replace-;) subwords#repeat(';') +vnoremap <expr> <silent> <Plug>(subwords-replace-,) subwords#repeat(',') + +noremap <expr> <silent> <Plug>(subwords-replace-t) subwords#clear_mark() . "t" +noremap <expr> <silent> <Plug>(subwords-replace-f) subwords#clear_mark() . "f" +noremap <expr> <silent> <Plug>(subwords-replace-T) subwords#clear_mark() . "T" +noremap <expr> <silent> <Plug>(subwords-replace-F) subwords#clear_mark() . "F" if g:subwords_include_bindings onoremap <silent> i_ <Plug>(inner-sub-word-prefer-snake) |