diff options
-rw-r--r-- | plugin/casefmt.vim | 139 |
1 files changed, 102 insertions, 37 deletions
diff --git a/plugin/casefmt.vim b/plugin/casefmt.vim index 4824092..e2d0480 100644 --- a/plugin/casefmt.vim +++ b/plugin/casefmt.vim @@ -4,9 +4,11 @@ " " <C-c>siw " -" The format of this command is +" the format of this command is " -" <C-c><target_casefmt><text_object> +" <C-c>[j]<target_casefmt><text_object> +" +" if the j is included the text object is joined using the case format. " " valid case formats are " @@ -15,31 +17,56 @@ " c - camelCase " C - UpperCamelCase " k - KONSTANT_CASE +" K - KONSTANT CASE (toupper(title case)) +" t - title case +" T - Title Case +" - - dashed-case + +if ! exists('g:casefmt_include_bindings') + let g:casefmt_include_bindings = 1 +endif + +if ! exists('g:casefmt_leader') + let g:casefmt_leader = '<C-c>' +endif + +let s:case_fmts = { + \ 's': 'to_snake', + \ '_': 'to_snake', + \ 'S': 'to_Snake', + \ 'c': 'to_camel', + \ 'C': 'to_Camel', + \ 'k': 'to_CONSTANT', + \ 'K': 'to_CONSTANT_space', + \ 't': 'to_title', + \ 'T': 'to_Title', + \ '-': 'to_dashed' + \ } + +function! CaseFmt_AddFormat(key, funcname) abort + exec printf("noremap <silent> <Plug>(casefmt-leader-no-set)%s " + \ . ":\<C-u>let g:CaseFmtFunction=function(\"\<SID>%s\")<cr>" + \ . ":\<C-u>set operatorfunc=\<SID>casefmt_do<cr>g@", a:key, a:funcname) + + exec printf("vnoremap <silent> <Plug>(casefmt-leader-no-set)%s " + \ . ":\<C-u>let g:CaseFmtFunction=function(\"\<SID>%s\")<cr>" + \ . ":\<C-u>call \<SID>casefmt_do(visualmode(), 1)<cr>", a:key, a:funcname) +endfunction -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> <Plug>(casefmt-leader) :<C-u>set g:CaseFmtProcessor=function("<SID>casefmt_default_processor")<cr><Plug>(casefmt-leader-no-set) +vnoremap <silent> <Plug>(casefmt-leader) :<C-u>set g:CaseFmtProcessor=function("<SID>casefmt_default_processor")<cr>gv<Plug>(casefmt-leader-no-set) -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$ +for [k, v] in items(s:case_fmts) + call CaseFmt_AddFormat(k, v) +endfor -" CamelCaseStuff +if g:casefmt_include_bindings + exec printf("nmap <silent> %s <Plug>(casefmt-leader)", g:casefmt_leader) + exec printf("vmap <silent> %s <Plug>(casefmt-leader)", g:casefmt_leader) +endif -" what_about_this -" test_camel_case +nnoremap <silent> <Plug>(casefmt-leader)j :<C-u>let g:CaseFmtProcessor=function("<SID>casefmt_joiner")<cr><Plug>(casefmt-leader-no-set) +vnoremap <silent> <Plug>(casefmt-leader)j :<C-u>let g:CaseFmtProcessor=function("<SID>casefmt_joiner")<cr>gv<Plug>(casefmt-leader-no-set) function! s:casefmt_do(type, ...) abort if a:0 @@ -54,14 +81,30 @@ function! s:casefmt_do(type, ...) abort let yanked = getreg('"', 1, v:true) let yankedtype = getregtype('"') + if !exists('g:CaseFmtProcessor') + let g:CaseFmtProcessor = function("\<SID>casefmt_default_processor") + endif + + let changed = g:CaseFmtProcessor(yanked, yankedtype) + + call setreg('"', changed, yankedtype) + + norm gvp + + " Reset the yanked text to what it was originally. + call setreg('"', yanked, yankedtype) +endfunction + +" Default processor. Calls change case fmt on each word. +function! s:casefmt_default_processor(yanked, type) let changed = [] - for n in yanked + for n in a: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])) + call add(new_split, g:CaseFmtFunction(s:normalize(s))) else call add(new_split, s) endif @@ -69,19 +112,21 @@ function! s:casefmt_do(type, ...) abort call add(changed, join(new_split, '')) endfor + return changed +endfunction - call setreg('"', changed, yankedtype) - - norm gvp - - " Reset the yanked text to what it was originally. - call setreg('"', yanked, yankedtype) +function! s:casefmt_joiner(yanked, type) abort + let changed = [] + for n in a:yanked + call add(changed, g:CaseFmtFunction(tolower(substitute(n, '\s\+', '_', 'g')))) + endfor + return changed 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 +" tries to be SmartAboutDetecting_the current case format and converting it " properly. -function! s:to_snake(s) abort +function! s:normalize(s) abort 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")) @@ -90,12 +135,16 @@ function! s:to_snake(s) abort return tolower(a:s) endfunction -function s:to_upper_snake(s) abort - return substitute(s:to_snake(a:s), '\%(_\|\<\)\zs\w\ze', '\u\0', 'g') +function! s:to_snake(s) abort + return a:s +endfunction + +function! s:to_Snake(s) abort + return substitute(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") + return substitute(a:s, '_\([a-z]\)', '\u\1', "g") endfunction function! s:to_Camel(s) abort @@ -103,5 +152,21 @@ function! s:to_Camel(s) abort endfunction function! s:to_CONSTANT(s) abort - return toupper(s:to_snake(a:s)) + return toupper(a:s) +endfunction + +function! s:to_CONSTANT_space(s) abort + return toupper(s:to_title(a:s)) +endfunction + +function! s:to_title(s) abort + return substitute(a:s, '_', ' ', 'g') +endfunction + +function! s:to_Title(s) abort + return substitute(s:to_title(a:s), '\<[a-z]', '\u\0', 'g') +endfunction + +function! s:to_dashed(s) abort + return substitute(a:s, '_', '-', 'g') endfunction |