Closed jacwah closed 4 years ago
This is something I have always wanted to have.
Currently the internal APIs are not locked so I would only depend on commands and not functions. But if you can create a generic tag stack it should be easy to just call push and pop easily.
How will I know if LspDefinition
succeeds using only commands?
@jacwah You need to update this file which will automatically set tags. https://github.com/prabirshrestha/vim-lsp/blob/5ae7a59caa81d37c4aada6c0527e5c9bba064b59/autoload/lsp/ui/vim.vim
Currently I don't want to expose other apis that users will depend on besides commands. I was thining of adding something like let g:lsp_tag_stack = 1
by default so tag stack will automatically work. If the user wants to disable it by default they can set it to 0.
Let me know if you were thininking something different.
Ok, cool! I was originally thinking about creating a separate plugin, but including it in this one is of course more convenient for users if you think it's a good idea as well.
I'll outline my idea for the interface below:
LspDefinition
pushes position before jump to a stack.LspDefinitionPop
, pops the top of the jump stack.Vim's tag stack has more features that probably see less use, but maybe we want.
:tag
. I find this useful sometimes. I don't know if LSP actually has a command for this, looked at the spec but textDocument/definition
only takes a Position
as far as I can tell.If the base implementation looks ok I'll start working on it! We can discuss extra features later, maybe in a separate issue.
I'm also interested in something like a tagstack for lsp. Is there any update on this issue?
And it would be nice to somehow link it to the vim jumplist, so that <Ctrl-O>
and <Ctrl-I>
woudl still work.
I'm not working on this currently, nor do I have the time in the close future. Feel free to pick it up!
If it's not making this too complicated, the ability to specify a split, vsplit or tab for the target for the command (or new commands if targeting is too much) would be really nice.
Just noticing this discussion on StackOverflow https://stackoverflow.com/questions/19195160/push-a-location-to-the-jumplist
If it's not making this too complicated, the ability to specify a split, vsplit or tab for the target for the command (or new commands if targeting is too much) would be really nice.
I think this issue should be about having something to work, and only then we can bikeshed on additional stuff.
@jacwah how would you expect API of such calbacks? I think it is just a matter of calling on_error
function in error handles of https://github.com/mcepl/vim-lsp/blob/11588dae0f0a23048b02f19fda6199cd43ab4639/autoload/lsp/ui/vim.vim#L236 and on_success
when it makes a jump. However, we have to get the pointer to these functions there somehow.
There is nice implementation of such stuff in the LanguageClient-neovim. First argument of functions like lsp#ui#vim#references
is optional callback, like s:handle_location
if argument is nil, there is default callback used, else used callback passed as argument. With such way, you can easy write the wrapper or just the full own implementation of reply.
Such approach is very useful and can be used for standalone unite/denite integration for example, to avoid main code dependence on this plugins.
There is nice implementation of such stuff in the LanguageClient-neovim.
Could you locate the particular function there? I am still not sure what's the problem.
I'm talking about such kind of front end functions interface, here you can see, that callback is configurable.
So behavior which you are looking for, can be obtained with following approach within such interface(pseudocode):
function! my_definition_handler
call s:handle_location(ctx)
call do_some_stuff_after(ctx)
endfunction
" this one can be done by end user
command LspDefinition call lsp#ui#vim#definitions(my_definition_handler)
Other way - is make lsp commands mutable objects, with delegate fields with even handlers. It's more complicated but much agile.
Somewhat like this:
let lsp_definition = {'entry' : lsp#ui#vim#definitions, 'handler' : s:handle_location}
command LspDefinition call lsp_definition['entry'](lsp_definition)
function! lsp#ui#vim#definitions(a:self)
...
let l:callback = a:self['handler']
...
endfunction
" somewhere in plugin code initialization:
let g:wrapee = lsp_definition['handler']
function! wrapper
call g:wrapee(ctx)
" do some additional handling
endfunction
Closing to clean up the issue. This is something I need to think a bit more before we expose public apis since I would like to not avoid breaking the public apis.
In the mean time you can try this.
nmap \gd :LspDefinition<cr>
nmap \gt :tab split<cr>:LspDefinition<cr>
nmap \gs :sp<cr>:LspDefinition<cr>
nmap \gv :vsp<cr>:LspDefinition<cr>
I would like to create a script with a goto-stack like what's built in for ctags. To do this, I would be great to have a way to tell programmatically if
LspDefinition
/lsp#ui#vim#definition
succeeded or not, e.g. anon_success
callback.If you're interested, I'll create a PR proposal.