DNLHC/glance.nvim

How to integrate special server command to retrieve references?

Closed this issue ยท 8 comments

Hey ๐Ÿ‘‹๐Ÿพ

First of all, thanks for this cool plugin! ๐Ÿ™๐Ÿพ

I have a weird request. I'm working with VueJS projects. And the language server for Vue SFCs has a not standardized LSP method that can give you "additional" references.
In case you are not familiar with VueJS, I try to sum it up a little. In Vue you can write so call single-file-components. They are a single file and include template, styling, logic and more for a web component. Anyway, there is a lot of "magic" happening under-the-hood by the Vue TypeScript Compiler. In the end, this file makes a (default) export that is "invisible". With invisible I mean that there is no piece of text/code in this whole file I could call textDocument/reference on to figure out where this component is used.
To solve this problem, the language server added a new special method (not even a workspace/executeCommand). It takes the same parameters as a textDocument/reference request (though, the position gets ignored). The result is also the same format with a list of LSP locations.

My question is now what would be the best way to integrate this into this plugin somehow. By configuration or similar I mean. Not a first-level support for this special case ofc. Do you have an idea? ๐Ÿ™ˆ
Thanks for the help!

DNLHC commented

Hey, I'll think about introducing a way to pass a custom LSP method request. If the result is the same format it shouldn't be a problem.
Btw, I didn't get from your message, which "special" method should be called in Vue instead of the regular textDocument/reference, so I could perhaps test it?

Sorry. The method is called volar/client/findFileReference. ๐Ÿ™‚

Btw, can I somehow help with this?

DNLHC commented

A new function was added glance.register_method which allows you to register your non-standard lsp methods.
important: this function should be called before glance setup.

local glance = require('glance')
glance.register_method({
  name = 'vue_references', -- by which name this method will be called in glance e.g. <cmd>Glance vue_references<cr>
  method = 'volar/client/findFileReference', -- LSP method
  label = 'references', -- displayed name in the UI
})
glance.setup(opts)

Now in your LSP on_attach hook you can conditionally setup a keymap for your new custom method, depending on whether LSP client supports it.

function on_attach(client, bufnr)
  if client.supports_method('volar/client/findFileReference') then
    vim.keymap.set('n', 'gr', '<CMD>Glance vue_references<CR>' { buffer = bufnr })
  else
    vim.keymap.set('n', 'gr', '<CMD>Glance references<CR>', { buffer = bufnr })
  end
end

Or just use a different keymap

DNLHC commented

Let me know if this works for you.

That is so amazing. Works really well. Thank you very much!

Though one issue I have remaining: I think Glance tries to call this function for every attached language server. So for example on Vue files I also have TailwindCSS, ESLint, null-ls, ... language servers running. These do now all report errors that they don't know this function (which causes multiple error notification on my screen).
Could that be resolved somehow? Either by checking the server (dunno if that actually works) or maybe by adding another optional property to the register_method to define (a list of) server name(s) that supports it. An automatic detection would be great, but if that isn't possible...

DNLHC commented

An automatic detection isn't really gonna work. Apparently some LSPs respond true for any method support detection, even for those they don't actually support.
I suppressed these errors for non-standard methods as a temporary fix.

Nice. Works very well for me. Even a little faster because the notifications caused some UI lag. ๐Ÿคท๐Ÿพ
Thank you very much! ๐Ÿ™๐Ÿพ