vim-lsc
vim-lsc copied to clipboard
about the tagstack
Unfortunately, while we now have settagstack() to add a tag to the stack, LSP definition requests still can't work like native tags. Once <c-t> is used to 'pop' the tagstack, the information needed to return to that tag's target is lost, i.e. a :tag (no arguments) won't work. What vim does when :tag is used is just search by the stored tag name in the tagfile again, as would be done with <c-]>, but there is no hook for that. It would have to be evaluated which functionality is necessary to add to vim.
The biggest issues with integration are
- The assumption of synchronicity, for example the
tselectcommand needs to immediately get a list of tags to operate on. Even if vim can make requests to LSP when pressingg], how can we allow the user to select from alternatives when the response is not instantaneous? - The association of tags with names/patterns. It is expected that the user can type
:tag fooand get filename/locations matching tags with foo. However, this request does not exist in LSP as far as I know. Requests for definition/implementation can only be done from a location source.
Do you have any ideas regarding what addition to vim would make the most sense (e.g., the tagfunc patch, a "TagFailed" autocmd, or something else)? Is it worth generalizing vim's idea of tags or is trying to integrate LSP convention with the tagstack the wrong approach?
#145
Yeah I'd very much like to see an async tagfunc so that we can use a LSP request to satisfy it. On top of proper tagstack handling this would also get us things like <c-w><c-[> for free.
We could also potentially implement something for :tag foo with a workspace/symbol request. We'd need the appropriate hooks in vim for this too.
See my comments on https://github.com/vim/vim/pull/1628
Do you have any thoughts about the patch proposed in vim/vim#4010? Would it cover your plugin's needs?
Note that it's not really necessary to add an "asynchronous" API to the tagfunc since vim processes job callbacks during sleep, and the expectation is that if the language server takes too long to respond, the tag operation will simply fail.
set tagfunc=TagFunc
let s:tags_ready = 0
let s:tag_wait_time = 200
let s:tags = []
function! TagFunc(pat, flag, info) abort
let s:tags = []
let s:tags_ready = 0
" make LSP request which sets s:tags_ready on response
" wait for response from LSP
let tic = reltime()
while 1000*reltimefloat(reltime(tic)) < s:tag_wait_time && !s:tags_ready
sleep 20m
endwhile
return s:tags
endfunction
Of course, this code can be made prettier by using a local dict instead, which is passed in the request and then resolved in the response callback.
One benefit of having the function support callbacks would be that it could be a vim level configuration for things like timeout.
I'd be fine handling the sleep and timeout in this plugin if it gets the support unblocked sooner.