From 5e5cc5189d53443e82100d85926e5856e6506866 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 23 Aug 2022 12:31:13 -0600 Subject: Add casefmt. This adds bindings to change the case format of text objects. --- plugin/casefmt.vim | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 plugin/casefmt.vim (limited to 'plugin/casefmt.vim') 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 . +" +" This way, to change the case format of a word to snake_case, one can run: +" +" siw +" +" The format of this command is +" +" +" +" valid case formats are +" +" s - snake_case +" S - Upper_Snake_Case +" c - camelCase +" C - UpperCamelCase +" k - KONSTANT_CASE + +noremap s :let g:CaseFmtFunction=function("to_snake"):set operatorfunc=casefmt_dog@ +vnoremap s :let g:CaseFmtFunction=function("to_snake"):call casefmt_do(visualmode(), 1) +nmap ss ^s$ + +noremap S :let g:CaseFmtFunction=function("to_upper_snake"):set operatorfunc=casefmt_dog@ +vnoremap S :let g:CaseFmtFunction=function("to_upper_snake"):call casefmt_do(visualmode(), 1) +nmap SS ^S$ + +noremap c :let g:CaseFmtFunction=function("to_camel"):set operatorfunc=casefmt_dog@ +vnoremap c :let g:CaseFmtFunction=function("to_camel"):call casefmt_do(visualmode(), 1) +nmap cc ^c$ + +noremap C :let g:CaseFmtFunction=function("to_Camel"):set operatorfunc=casefmt_dog@ +vnoremap C :let g:CaseFmtFunction=function("to_Camel"):call casefmt_do(visualmode(), 1) +nmap CC ^C$ + +noremap k :let g:CaseFmtFunction=function("to_CONSTANT"):set operatorfunc=casefmt_dog@ +vnoremap k :let g:CaseFmtFunction=function("to_CONSTANT"):call casefmt_do(visualmode(), 1) +nmap kk ^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 -- cgit