From c35a92650237c533396415460d9cddbe480d2c9a Mon Sep 17 00:00:00 2001 From: Margus Kerma Date: Fri, 5 Nov 2021 23:08:41 +0200 Subject: [PATCH 1/2] POC for #3319 - add fzf wrap for GoImplements --- autoload/fzf/decls.vim | 33 +------------------- autoload/fzf/fzf.vim | 43 +++++++++++++++++++++++++ autoload/fzf/implements.vim | 62 +++++++++++++++++++++++++++++++++++++ autoload/go/implements.vim | 6 ++++ 4 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 autoload/fzf/fzf.vim create mode 100644 autoload/fzf/implements.vim diff --git a/autoload/fzf/decls.vim b/autoload/fzf/decls.vim index 6182e0ee33..ee97e757b4 100644 --- a/autoload/fzf/decls.vim +++ b/autoload/fzf/decls.vim @@ -25,37 +25,6 @@ function! s:color(str, group) abort return printf("\x1b[%sm%s\x1b[m", color, a:str) endfunction -function! s:sink(str) abort - if len(a:str) < 2 - return - endif - try - " we jump to the file directory so we can get the fullpath via fnamemodify - " below - let l:dir = go#util#Chdir(s:current_dir) - - let vals = matchlist(a:str[1], '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') - - " i.e: main.go - let filename = vals[1] - let line = vals[2] - let col = vals[3] - - " i.e: /Users/fatih/vim-go/main.go - let filepath = fnamemodify(filename, ":p") - - let cmd = get({'ctrl-x': 'split', - \ 'ctrl-v': 'vertical split', - \ 'ctrl-t': 'tabe'}, a:str[0], 'e') - execute cmd fnameescape(filepath) - call cursor(line, col) - silent! norm! zvzz - finally - "jump back to old dir - call go#util#Chdir(l:dir) - endtry -endfunction - function! s:source(mode,...) abort let s:current_dir = expand('%:p:h') let ret_decls = [] @@ -144,7 +113,7 @@ function! fzf#decls#cmd(...) abort call fzf#run(fzf#wrap('GoDecls', { \ 'source': call('source', a:000), \ 'options': printf('-n 1 --with-nth 1,2 --delimiter=$''\t'' --preview "echo {3}" --preview-window "wrap" --ansi --prompt "GoDecls> " --expect=ctrl-t,ctrl-v,ctrl-x%s', colors), - \ 'sink*': function('s:sink') + \ 'sink*': function('fzf#fzf#sink') \ })) endfunction diff --git a/autoload/fzf/fzf.vim b/autoload/fzf/fzf.vim new file mode 100644 index 0000000000..dc3ebc58b3 --- /dev/null +++ b/autoload/fzf/fzf.vim @@ -0,0 +1,43 @@ +" don't spam the user when Vim is started in Vi compatibility mode +let s:cpo_save = &cpo +set cpo&vim + +function! fzf#fzf#sink(str) abort + if len(a:str) < 2 + return + endif + + let s:current_dir = expand('%:p:h') + + try + " we jump to the file directory so we can get the fullpath via fnamemodify + " below + let l:dir = go#util#Chdir(s:current_dir) + + let vals = matchlist(a:str[1], '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') + + " i.e: main.go + let filename = vals[1] + let line = vals[2] + let col = vals[3] + + " i.e: /Users/fatih/vim-go/main.go + let filepath = fnamemodify(filename, ":p") + + let cmd = get({'ctrl-x': 'split', + \ 'ctrl-v': 'vertical split', + \ 'ctrl-t': 'tabe'}, a:str[0], 'e') + execute cmd fnameescape(filepath) + call cursor(line, col) + silent! norm! zvzz + finally + "jump back to old dir + call go#util#Chdir(l:dir) + endtry +endfunction + +" restore Vi compatibility settings +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: sw=2 ts=2 et diff --git a/autoload/fzf/implements.vim b/autoload/fzf/implements.vim new file mode 100644 index 0000000000..d3664fc5e0 --- /dev/null +++ b/autoload/fzf/implements.vim @@ -0,0 +1,62 @@ +" don't spam the user when Vim is started in Vi compatibility mode +let s:cpo_save = &cpo +set cpo&vim + +function! s:source(...) abort + let ret_files = [] + + let l:bin = "gopls" + let l:fname = expand('%:p') + let [l:line, l:col] = getpos('.')[1:2] + let pos = printf("%s:%s:%s", + \ l:fname, + \ l:line, + \ l:col + \) + + let bin_path = go#path#CheckBinPath(l:bin) + if empty(bin_path) + return + endif + + call go#cmd#autowrite() + + let [l:out, l:err] = go#util#Exec([l:bin, 'implementation', l:pos]) + if l:err + call go#util#EchoError(l:out) + return + endif + + for line in split(out, '\n') + let vals = matchlist(line, '\(.\{-}\):\(\d\+\):\(\d\+\)-\(\d\+\)') + let filename = fnamemodify(expand(vals[1]), ":~:.") + let pos = printf("|%s:%s:%s|", + \ l:filename, + \ l:vals[2], + \ l:vals[3] + \) + call add(ret_files, printf("%s:%s\t%s", + \ l:filename, + \ l:vals[2], + \ pos + \)) + endfor + return sort(ret_files) +endfunc + + +function! fzf#implements#cmd(...) abort + let l:spec = { + \ 'source': call('source', [a:000]), + \ 'sink*': function('fzf#fzf#sink'), + \ 'options': printf('-n 1 --with-nth 1 --delimiter=$''\t'' --ansi --prompt "GoImplements> " --expect=ctrl-t,ctrl-v,ctrl-x') + \ } + call fzf#run(fzf#wrap("GoImplements", fzf#vim#with_preview(l:spec, 'right:50%:nohidden'))) +endfunc + + +" restore Vi compatibility settings +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: sw=2 ts=2 et diff --git a/autoload/go/implements.vim b/autoload/go/implements.vim index 0d25f8c2e4..477d82ef76 100644 --- a/autoload/go/implements.vim +++ b/autoload/go/implements.vim @@ -16,6 +16,12 @@ function! go#implements#Implements(selected) abort let l:fname = expand('%:p') call go#lsp#Implements(l:fname, l:line, l:col, funcref('s:parse_output')) return + elseif l:mode == 'fzf' + if !go#config#GoplsEnabled() + call go#util#EchoError("go_implements_mode is 'fzf', but gopls is disabled") + endif + call fzf#implements#cmd() + return else call go#util#EchoWarning('unknown value for g:go_implements_mode') endif From e028fd80c5b3c2aa4c31bc67bcb8e0f03500d0dc Mon Sep 17 00:00:00 2001 From: Margus Kerma Date: Sun, 7 Nov 2021 14:29:40 +0200 Subject: [PATCH 2/2] Change GoImplements view configuration from mode to listtype #3319 --- autoload/go/implements.vim | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/autoload/go/implements.vim b/autoload/go/implements.vim index 477d82ef76..e3cb2cd707 100644 --- a/autoload/go/implements.vim +++ b/autoload/go/implements.vim @@ -11,17 +11,16 @@ function! go#implements#Implements(selected) abort if !go#config#GoplsEnabled() call go#util#EchoError("go_implements_mode is 'gopls', but gopls is disabled") endif + let l:listtype = go#list#Type("GoImplements") + if l:listtype == "fzf" + call fzf#implements#cmd() + return + endif let [l:line, l:col] = getpos('.')[1:2] let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col) let l:fname = expand('%:p') call go#lsp#Implements(l:fname, l:line, l:col, funcref('s:parse_output')) return - elseif l:mode == 'fzf' - if !go#config#GoplsEnabled() - call go#util#EchoError("go_implements_mode is 'fzf', but gopls is disabled") - endif - call fzf#implements#cmd() - return else call go#util#EchoWarning('unknown value for g:go_implements_mode') endif