Skip to content

Commit

Permalink
POC for fatih#3319 - add fzf wrap for GoImplements
Browse files Browse the repository at this point in the history
  • Loading branch information
kerma committed Nov 5, 2021
1 parent 2831f48 commit d0ff853
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
109 changes: 109 additions & 0 deletions autoload/fzf/implements.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim

function! s:code(group, attr) abort
let code = synIDattr(synIDtrans(hlID(a:group)), a:attr, "cterm")
if code =~ '^[0-9]\+$'
return code
endif
endfunction

let s:temp_output = []

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(output) abort
let s:current_dir = expand('%:p:h')
let ret_decls = []

for line in a:output
let vals = matchlist(line, '\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
let filename = fnamemodify(expand(vals[1]), ":~:.")
let pos = printf("|%s:%s:%s|",
\ l:filename,
\ l:vals[2],
\ l:vals[3]
\)
call add(ret_decls, printf("%s\t%s\t%s\t%s",
\ l:filename,
\ l:vals[2],
\ l:vals[4],
\ pos
\))
endfor
return ret_decls
endfunc

function! s:parse_output(exit_val, output, title) abort
if a:exit_val
call go#util#EchoError(a:output)
return
endif

let normal_fg = s:code("Normal", "fg")
let normal_bg = s:code("Normal", "bg")
let cursor_fg = s:code("CursorLine", "fg")
let cursor_bg = s:code("CursorLine", "bg")
let colors = printf(" --color %s%s%s%s%s",
\ &background,
\ empty(normal_fg) ? "" : (",fg:".normal_fg),
\ empty(normal_bg) ? "" : (",bg:".normal_bg),
\ empty(cursor_fg) ? "" : (",fg+:".cursor_fg),
\ empty(cursor_bg) ? "" : (",bg+:".cursor_bg),
\)
call fzf#run(fzf#wrap('GoImplements', {
\ 'source': call('<sid>source', [a:output]),
\ 'options': printf('-n 1 --with-nth 1 --delimiter=$''\t'' --preview "bat {1} -r {2}: --color=always" --preview-window "right,nohidden" --ansi --prompt "GoImplements> " --expect=ctrl-t,ctrl-v,ctrl-x%s', colors),
\ 'sink*': function('s:sink')
\ }))
endfunc

function! fzf#implements#cmd(...) abort
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'))

" test output
"let test_output = ['~/src/kerma/vim-go-implements/interface.go:5:15 func (i *impl) Implements() error {',
" \ '~/src/kerma/vim-go-implements/other_interface.go:6:18 func (i *second) Implements() error {']
"call s:parse_output(0, l:test_output, "title")
endfunction



" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save

" vim: sw=2 ts=2 et
6 changes: 6 additions & 0 deletions autoload/go/implements.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d0ff853

Please sign in to comment.