From a0e7a3a03ba5693901fe462d8b81420ad12acfea Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Fri, 24 Nov 2017 00:52:21 +0000 Subject: [PATCH] Fix :GoImpl completion Fixes #1554 The problem is that `:GoImpl somethingInvalid` would set `v:shell_error`, and on the next `:GoImpl ` the `go#util#env()` call in `s:root_dirs()` would use the cache, so the `v:shell_error` is "stuck". Fix it by not checking this here; `go#util#env()` already shows an error so that should be fine. Long-term fix is to use `go#util#Exec()` everywhere which returns `v:shell_error` instead of relying on a global value. While I'm here also add a basic test and use `Exec()` in a few places. --- autoload/go/impl.vim | 26 +++++++++----------------- autoload/go/impl_test.vim | 37 +++++++++++++++++++++++++++++++++++++ autoload/gotest.vim | 2 +- ftplugin/go/commands.vim | 2 +- 4 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 autoload/go/impl_test.vim diff --git a/autoload/go/impl.vim b/autoload/go/impl.vim index 2a10437f10..73707fa10a 100644 --- a/autoload/go/impl.vim +++ b/autoload/go/impl.vim @@ -1,16 +1,11 @@ function! go#impl#Impl(...) abort - let binpath = go#path#CheckBinPath('impl') - if empty(binpath) - return - endif - let recv = "" let iface = "" let interactive = 0 let pos = getpos('.') - if a:0 == 0 + if a:0 is 0 " Interactive mode if user didn't pass any arguments. let recv = s:getReceiver() let iface = input("vim-go: generating method stubs for interface: ") @@ -19,7 +14,7 @@ function! go#impl#Impl(...) abort call go#util#EchoError('usage: interface type is not provided') return endif - elseif a:0 == 1 + elseif a:0 is 1 " we assume the user only passed the interface type, " i.e: ':GoImpl io.Writer' let recv = s:getReceiver() @@ -41,19 +36,19 @@ function! go#impl#Impl(...) abort try let dirname = fnameescape(expand('%:p:h')) - let result = go#util#System(join(go#util#Shelllist([binpath, '-dir', dirname, recv, iface], ' '))) + let [result, err] = go#util#Exec(['impl', '-dir', dirname, recv, iface]) let result = substitute(result, "\n*$", "", "") - if go#util#ShellError() != 0 + if err call go#util#EchoError(result) return endif - if result ==# '' + if result is# '' return end put ='' - put =result + silent put =result finally call setpos('.', pos) endtry @@ -99,10 +94,6 @@ function! s:root_dirs() abort endif let paths = map(split(go#util#env("gopath"), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')") - if go#util#ShellError() - return [] - endif - if !empty(filter(paths, 'isdirectory(v:val)')) call extend(dirs, paths) endif @@ -120,11 +111,12 @@ function! s:go_packages(dirs) abort endfunction function! s:interface_list(pkg) abort - let contents = split(go#util#System('go doc ' . a:pkg), "\n") - if go#util#ShellError() + let [contents, err] = go#util#Exec(['go', 'doc', a:pkg]) + if err return [] endif + let contents = split(contents, "\n") call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''') return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')') endfunction diff --git a/autoload/go/impl_test.vim b/autoload/go/impl_test.vim new file mode 100644 index 0000000000..c417cd4fb8 --- /dev/null +++ b/autoload/go/impl_test.vim @@ -0,0 +1,37 @@ +func! Test_impl() abort + try + let l:tmp = gotest#write_file('a/a.go', [ + \ 'package a', + \ '', + \ '']) + + call go#impl#Impl('r', 'reader', 'io.Reader') + call gotest#assert_buffer(1, [ + \ 'func (r reader) Read(p []byte) (n int, err error) {', + \ ' panic("not implemented")', + \ '}']) + finally + call delete(l:tmp, 'rf') + endtry +endfunc + +func! Test_impl_get() abort + try + let l:tmp = gotest#write_file('a/a.go', [ + \ 'package a', + \ '', + \ 'type reader struct {}']) + + call go#impl#Impl('io.Reader') + call gotest#assert_buffer(0, [ + \ 'package a', + \ '', + \ 'type reader struct {}', + \ '', + \ 'func (r *reader) Read(p []byte) (n int, err error) {', + \ ' panic("not implemented")', + \ '}']) + finally + call delete(l:tmp, 'rf') + endtry +endfunc diff --git a/autoload/gotest.vim b/autoload/gotest.vim index 5a4df1f2af..9ae81a3df2 100644 --- a/autoload/gotest.vim +++ b/autoload/gotest.vim @@ -15,7 +15,7 @@ fun! gotest#write_file(path, contents) abort call mkdir(fnamemodify(l:full_path, ':h'), 'p') call writefile(a:contents, l:full_path) exe 'cd ' . l:dir . '/src' - silent exe 'e ' . a:path + silent exe 'e! ' . a:path " Set cursor. let l:lnum = 1 diff --git a/ftplugin/go/commands.vim b/ftplugin/go/commands.vim index 0ab6d25ad7..9b983ef56f 100644 --- a/ftplugin/go/commands.vim +++ b/ftplugin/go/commands.vim @@ -87,7 +87,7 @@ command! -nargs=? -complete=file GoDecls call go#decls#Decls(0, ) command! -nargs=? -complete=dir GoDeclsDir call go#decls#Decls(1, ) " -- impl -command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl() +command! -nargs=* -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl() " -- template command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate()