From 172139cab5de0a1c44433b0ad166140bb860f241 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Mon, 18 Sep 2017 11:10:34 +0100 Subject: [PATCH 1/3] Better prefill and completion for :GoRename 1. Repurpose `g:go_gorename_prefill` to be an expression, which can transform the value that is pre-filled to the most common forms. The default is to use camelCase when the identifiers starts with a lowercase letter, and CamelCase when it starts with an uppercase letter, which sounds like a reasonable guess to me. 2. Add completion support, so you can use `:GoRename ` to get the most common options. Both of these changes make it a bit easier/faster to use, especially if you need to rename a bunch of identifiers in a project that doesn't follow Go standards (like I had to do last week). --- autoload/go/rename.vim | 22 ++++++++++++++++------ autoload/go/util.vim | 24 ++++++++++++++++-------- doc/vim-go.txt | 12 ++++++++---- ftplugin/go/commands.vim | 2 +- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/autoload/go/rename.vim b/autoload/go/rename.vim index 48b90923f1..798c2c53e9 100644 --- a/autoload/go/rename.vim +++ b/autoload/go/rename.vim @@ -3,16 +3,17 @@ if !exists("g:go_gorename_bin") endif if !exists("g:go_gorename_prefill") - let g:go_gorename_prefill = 1 + let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . + \ '? go#util#camelcaseExported(expand(""))' . + \ ': go#util#camelcase(expand(""))' endif function! go#rename#Rename(bang, ...) abort let to_identifier = "" if a:0 == 0 - let from = expand("") - let ask = printf("vim-go: rename '%s' to: ", from) - if g:go_gorename_prefill - let to_identifier = input(ask, from) + let ask = printf("vim-go: rename '%s' to: ", expand("")) + if g:go_gorename_prefill != '' + let to_identifier = input(ask, eval(g:go_gorename_prefill)) else let to_identifier = input(ask) endif @@ -24,7 +25,7 @@ function! go#rename#Rename(bang, ...) abort let to_identifier = a:1 endif - "return with a warning if the bin doesn't exist + " return with a warning if the bin doesn't exist let bin_path = go#path#CheckBinPath(g:go_gorename_bin) if empty(bin_path) return @@ -146,4 +147,13 @@ function s:parse_errors(exit_val, bang, out) silent execute ":e" endfunction +" Commandline completion: original, unexported camelCase, and exported +" CamelCase. +function! go#rename#Complete(lead, cmdline, cursor) + let l:word = expand('') + return filter(uniq(sort( + \ [l:word, go#util#camelcase(l:word), go#util#camelcaseExported(l:word)])), + \ 'strpart(v:val, 0, len(a:lead)) == a:lead') +endfunction + " vim: sw=2 ts=2 et diff --git a/autoload/go/util.vim b/autoload/go/util.vim index fef7e5ed06..294f56f37c 100644 --- a/autoload/go/util.vim +++ b/autoload/go/util.vim @@ -264,25 +264,33 @@ endfunction " snakecase converts a string to snake case. i.e: FooBar -> foo_bar " Copied from tpope/vim-abolish function! go#util#snakecase(word) abort - let word = substitute(a:word,'::','/','g') - let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') - let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g') - let word = substitute(word,'[.-]','_','g') + let word = substitute(a:word, '::', '/', 'g') + let word = substitute(word, '\(\u\+\)\(\u\l\)', '\1_\2', 'g') + let word = substitute(word, '\(\l\|\d\)\(\u\)', '\1_\2', 'g') + let word = substitute(word, '[.-]', '_', 'g') let word = tolower(word) return word endfunction -" camelcase converts a string to camel case. i.e: FooBar -> fooBar -" Copied from tpope/vim-abolish +" camelcase converts a string to camel case. e.g. FooBar or foo_bar will become +" fooBar. +" Copied from tpope/vim-abolish. function! go#util#camelcase(word) abort let word = substitute(a:word, '-', '_', 'g') if word !~# '_' && word =~# '\l' - return substitute(word,'^.','\l&','') + return substitute(word, '^.', '\l&', '') else - return substitute(word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g') + return substitute(word, '\C\(_\)\=\(.\)', '\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g') endif endfunction +" camelcaseExported converts a string to exported camel case. e.g. fooBar or +" foo_bar will become FooBar. +function! go#util#camelcaseExported(word) abort + let word = go#util#camelcase(a:word) + return toupper(word[0]) . word[1:] +endfunction + " Echo a message to the screen and highlight it with the group in a:hi. " " The message can be a list or string; every line with be :echomsg'd separately. diff --git a/doc/vim-go.txt b/doc/vim-go.txt index c1550a2835..64f218405c 100644 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -1468,10 +1468,14 @@ By default it is set to edit. < *'g:go_gorename_prefill'* -Specifies whether |:GoRename| prefills the new identifier name with the -word under the cursor. By default it is enabled. -> - let g:go_gorename_prefill = 1 +Expression to prefill the new identifier when using |:GoRename| without any +arguments. Use an empty string if you don't want to prefill anything. By +default it converts the identifier to camelCase or CamelCase, depending on +whether the identifier is exported. +> + let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . + \ '? go#util#camelcaseExported(expand(""))' . + \ ': go#util#camelcase(expand(""))' < *'g:go_gocode_autobuild'* diff --git a/ftplugin/go/commands.vim b/ftplugin/go/commands.vim index 5b32450b57..0ab6d25ad7 100644 --- a/ftplugin/go/commands.vim +++ b/ftplugin/go/commands.vim @@ -1,5 +1,5 @@ " -- gorename -command! -nargs=? GoRename call go#rename#Rename(0,) +command! -nargs=? -complete=customlist,go#rename#Complete GoRename call go#rename#Rename(0, ) " -- guru command! -nargs=* -complete=customlist,go#package#Complete GoGuruScope call go#guru#Scope() From d3a07e2c30cec2b83af6a30d74f4c860993916cb Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sat, 14 Oct 2017 16:04:14 +0100 Subject: [PATCH 2/3] Address PR feedback - Rename `camelcaseExported` to `pascalcase`. - `g:go_gorename_prefill=1` is an alias for the default, for compatibility reasons. --- autoload/go/rename.vim | 19 +++++++++++++------ autoload/go/util.vim | 6 +++--- doc/vim-go.txt | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/autoload/go/rename.vim b/autoload/go/rename.vim index 798c2c53e9..b8b97de335 100644 --- a/autoload/go/rename.vim +++ b/autoload/go/rename.vim @@ -2,13 +2,20 @@ if !exists("g:go_gorename_bin") let g:go_gorename_bin = "gorename" endif -if !exists("g:go_gorename_prefill") - let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . - \ '? go#util#camelcaseExported(expand(""))' . - \ ': go#util#camelcase(expand(""))' -endif +" Set the default value. A value of "1" is a shortcut for this, for +" compatibility reasons. +function! s:default() abort + if !exists("g:go_gorename_prefill") || g:go_gorename_prefill == 1 + let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . + \ '? go#util#pascalcase(expand(""))' . + \ ': go#util#camelcase(expand(""))' + endif +endfunction +call s:default() function! go#rename#Rename(bang, ...) abort + call s:default() + let to_identifier = "" if a:0 == 0 let ask = printf("vim-go: rename '%s' to: ", expand("")) @@ -152,7 +159,7 @@ endfunction function! go#rename#Complete(lead, cmdline, cursor) let l:word = expand('') return filter(uniq(sort( - \ [l:word, go#util#camelcase(l:word), go#util#camelcaseExported(l:word)])), + \ [l:word, go#util#camelcase(l:word), go#util#pascalcase(l:word)])), \ 'strpart(v:val, 0, len(a:lead)) == a:lead') endfunction diff --git a/autoload/go/util.vim b/autoload/go/util.vim index 294f56f37c..430f4c0184 100644 --- a/autoload/go/util.vim +++ b/autoload/go/util.vim @@ -284,9 +284,9 @@ function! go#util#camelcase(word) abort endif endfunction -" camelcaseExported converts a string to exported camel case. e.g. fooBar or -" foo_bar will become FooBar. -function! go#util#camelcaseExported(word) abort +" pascalcase converts a string to 'PascalCase'. e.g. fooBar or foo_bar will +" become FooBar. +function! go#util#pascalcase(word) abort let word = go#util#camelcase(a:word) return toupper(word[0]) . word[1:] endfunction diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 64f218405c..4093f236ca 100644 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -1474,7 +1474,7 @@ default it converts the identifier to camelCase or CamelCase, depending on whether the identifier is exported. > let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . - \ '? go#util#camelcaseExported(expand(""))' . + \ '? go#util#pascalcase(expand(""))' . \ ': go#util#camelcase(expand(""))' < *'g:go_gocode_autobuild'* From 57d60ff056408d0b6d8017945b0237faf8f81206 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sat, 14 Oct 2017 16:09:27 +0100 Subject: [PATCH 3/3] Also clarify docs a bit --- doc/vim-go.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 4093f236ca..bfaf8a9683 100644 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -1470,8 +1470,9 @@ By default it is set to edit. Expression to prefill the new identifier when using |:GoRename| without any arguments. Use an empty string if you don't want to prefill anything. By -default it converts the identifier to camelCase or CamelCase, depending on -whether the identifier is exported. +default it converts the identifier to camel case but preserves the +capitalisation of the first letter to ensure that the exported state stays the +same. > let g:go_gorename_prefill = 'expand("") =~# "^[A-Z]"' . \ '? go#util#pascalcase(expand(""))' .