diff options
author | Josh Rahm <rahm@google.com> | 2022-08-23 12:31:13 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-08-23 12:31:13 -0600 |
commit | 5e5cc5189d53443e82100d85926e5856e6506866 (patch) | |
tree | 6d8db9c84d3349787d9a050d05296896f8e0c1f5 | |
parent | 17703b92b44e5afd12e4bca418f61cadb50ac91d (diff) | |
download | fieldmarshal.vim-5e5cc5189d53443e82100d85926e5856e6506866.tar.gz fieldmarshal.vim-5e5cc5189d53443e82100d85926e5856e6506866.tar.bz2 fieldmarshal.vim-5e5cc5189d53443e82100d85926e5856e6506866.zip |
Add casefmt. This adds bindings to change the case format of text objects.
-rw-r--r-- | plugin/casefmt.vim | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/plugin/casefmt.vim b/plugin/casefmt.vim new file mode 100644 index 0000000..ed85fb3 --- /dev/null +++ b/plugin/casefmt.vim @@ -0,0 +1,113 @@ +" Mappings for changing the case type of a text object. These mappings are invoked with <C-c>. +" +" This way, to change the case format of a word to snake_case, one can run: +" +" <C-c>siw +" +" The format of this command is +" +" <C-c><target_casefmt><text_object> +" +" valid case formats are +" +" s - snake_case +" S - Upper_Snake_Case +" c - camelCase +" C - UpperCamelCase +" k - KONSTANT_CASE + +noremap <silent> <C-c>s :<C-u>let g:CaseFmtFunction=function("<SID>to_snake")<cr>:<C-u>set operatorfunc=<SID>casefmt_do<cr>g@ +vnoremap <silent> <C-c>s :<C-u>let g:CaseFmtFunction=function("<SID>to_snake")<cr>:<C-u>call <SID>casefmt_do(visualmode(), 1)<cr> +nmap <C-c>ss ^<C-c>s$ + +noremap <silent> <C-c>S :<C-u>let g:CaseFmtFunction=function("<SID>to_upper_snake")<cr>:<C-u>set operatorfunc=<SID>casefmt_do<cr>g@ +vnoremap <silent> <C-c>S :<C-u>let g:CaseFmtFunction=function("<SID>to_upper_snake")<cr>:<C-u>call <SID>casefmt_do(visualmode(), 1)<cr> +nmap <C-c>SS ^<C-c>S$ + +noremap <silent> <C-c>c :<C-u>let g:CaseFmtFunction=function("<SID>to_camel")<cr>:<C-u>set operatorfunc=<SID>casefmt_do<cr>g@ +vnoremap <silent> <C-c>c :<C-u>let g:CaseFmtFunction=function("<SID>to_camel")<cr>:<C-u>call <SID>casefmt_do(visualmode(), 1)<cr> +nmap <C-c>cc ^<C-c>c$ + +noremap <silent> <C-c>C :<C-u>let g:CaseFmtFunction=function("<SID>to_Camel")<cr>:<C-u>set operatorfunc=<SID>casefmt_do<cr>g@ +vnoremap <silent> <C-c>C :<C-u>let g:CaseFmtFunction=function("<SID>to_Camel")<cr>:<C-u>call <SID>casefmt_do(visualmode(), 1)<cr> +nmap <C-c>CC ^<C-c>C$ + +noremap <silent> <C-c>k :<C-u>let g:CaseFmtFunction=function("<SID>to_CONSTANT")<cr>:<C-u>set operatorfunc=<SID>casefmt_do<cr>g@ +vnoremap <silent> <C-c>k :<C-u>let g:CaseFmtFunction=function("<SID>to_CONSTANT")<cr>:<C-u>call <SID>casefmt_do(visualmode(), 1)<cr> +nmap <C-c>kk ^<C-c>k$ + +" CamelCaseStuff + +" what_about_this +" test_camel_case + +function! s:casefmt_do(type, ...) abort + if a:0 + silent exe "norm! gvy" + elseif a:type == 'line' + " yank the text described by the motion + silent exe "norm! '[V']y" + else + silent exe "norm! `[v`]y" + endif + + let yanked = getreg('"', 1, v:true) + let yankedtype = getregtype('"') + + let changed = [] + for n in yanked + let split = split(n, '\<\|\>') " Split by word boundaries + let new_split = [] + + for s in split " Iterate by words. + if s =~ "[a-zA-Z_0-9]*" " Is s an identifier? + call add(new_split, call(g:CaseFmtFunction, [s])) + else + call add(new_split, s) + endif + endfor + + call add(changed, join(new_split, '')) + endfor + + call setreg('"', changed, yankedtype) + + norm gvp + + " Reset the yanked text to what it was originally. + call setreg('"', yanked, yankedtype) +endfunction + +" snake_case is the platonic form that all other forms build from. This function +" tries to be smart about detecting the current case format and converting it +" properly. +function! s:to_snake(s) abort + if a:s =~ '^[A-Z_]*$' || a:s =~ '_' + " This is in constant case or is already in some flavor of snake_case. + " return whatever it is, but to lower. + return tolower(a:s) + endif + + if a:s =~ '[a-z][A-Z]' + " a:s has a camel case boundary in it. + return tolower(substitute(a:s, '\%([a-zA-Z]\)\zs\ze\([A-Z0-9]\)', '_', "g")) + endif + + return a:s +endfunction + +function s:to_upper_snake(s) abort + return substitute(s:to_snake(a:s), '\%(_\|\<\)\zs\w\ze', '\u\0', 'g') +endfunction + +function! s:to_camel(s) abort + return substitute(s:to_snake(a:s), '_\([a-z]\)', '\u\1', "g") +endfunction + +function! s:to_Camel(s) abort + return substitute(s:to_camel(a:s), '\<\w', '\u\0', 'g') +endfunction + +function! s:to_CONSTANT(s) abort + return toupper(s:to_snake(a:s)) +endfunction |