aboutsummaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'plugin')
-rw-r--r--plugin/subwords.vim222
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)