-
-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for rust-analyzer's SnippetTextEdits #235
Comments
What exactly would have to be added to luasnip to enable snippet-textedits? |
@simrat39 would that be enough to add this to rust-tools? |
umm not really, rust analyzer's snippet text edits are more like normal lsp text edits, they send a location and stuff as well, but I afaik most snippet plugins only support snippet expansion at the current cursor position, so it wouldn't work. It would need a completely separate implementation of TextEdits. |
Expanding at any position shouldn't be a problem, I could add that. I wouldn't implement lsp-communication in luasnip, but that part could be handled by rust-tools? |
I believe that would be the end goal. Providing the API to call from lsp handlers. |
@L3MON4D3 yes the lsp communication will be handled by rust-tools. We override vim.lsp.utils.apply_text_edit, not ideal but it works so it's whatever, just need the snippet plugin to apply the snippets |
I added functionality to expand lsp-snippets at any position, check here. |
Just realized that link doesn't actually get you anywhere, just scroll all the way down and look for |
i'll play around with it, thanks for the support |
This works mostly, but one thing missing is that TextEdits give back a range, which can be used for example replacing multiple lines of text with something else, idk if it's in the scope of this plugin to support that but we would need that. This is how neovim does it https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/util.lua#L329 |
Ah, no I wouldn't like to implement that in Luasnip, srry. |
that's fair, i'll try to see what I can do on rust-tools' side then |
Hi @simrat39, is there a follow-up to this? I found simrat39/rust-tools.nvim#74 which is closed, does it mean that you won't be able to support the feature? P.S. I love the amount of quality profile pics in this issue |
I'm going to backtrack on my stance here, it doesn't make sense to require each plugin that wants to utilize luasnip for I'll add an implementation for applying a single |
(Taking a closer look, the main problem with applying multiple textEdits is that applying them in any order may cause the lines in the textEdit to no longer correspond to the correct position, but I think I know how to make that work properly) |
Implemented a first version in branch |
Thanks for this, I'll check it out and point out issues if any! Would be nice if we finally get this into luasnip and rust-tools |
Ok so this works pretty good, thanks for the work. One small issue though, for some reason rust-analyzer sends multiple snippet text edits in one call, even though their docs say that they won't do that, but the extra ones they sent all had empty |
Btw i pushed a separate branch if anyone wants to test it out. Use it like this: rt.setup({
tools = {
snippet_func = function(edits, bufnr, offset_encoding, old_func)
require("luasnip.extras.lsp").apply_text_edits(
edits,
bufnr,
offset_encoding,
old_func
)
end,
... |
Nice, you're welcome :D
Mhmmm that's annoying, I guess we could filter it here, but would be nicer to accommodate for languageserver-quirks in their respective plugins imo. Wdyt?
Sounds good👍 |
Oh we could also just handle multiple snippetTextEdits by inserting the into the jump list one after the other, and then jumping back into the first placeholder of the first snippet. |
Yeah for sure, but I still think it should be clarified upstream first, their docs and their implementation should match. |
Oh yeah, no question there 👍 |
For the reference, the rust-analyzer's VSCode client implements applySnippetTextEdit. https://github.com/rust-lang/rust-analyzer/blob/master/editors/code/src/snippets.ts#L38 |
Oh, thank you for sharing! But at least they'll allow multiple snippetTextEdits, I'll look into accomodating that here. |
The VSCode seems to now support https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/snippet/browser/snippetController2.ts#L91 I think the time has come to support these functionality in the snippet engine side. |
True! Are you aware of a formal specification of the snippetTextEdits vscode expects, and how it handles them? |
@simrat39 Would you test #577 again? Multiple snippetTextEdits in one should now work.
require("luasnip.extras.lsp").apply_text_edits(
{ {
insertTextFormat = 2,
newText = "${1: lolo} adsffff ${2: lele}",
range = {
["end"] = {
character = 16,
line = 2
},
start = {
character = 0,
line = 2
}
}
}, {
insertTextFormat = 2,
newText = "${1: lolo} adsffff ${2: lele}",
range = {
["end"] = {
character = 0,
line = 3
},
start = {
character = 16,
line = 2
}
}
}, {
insertTextFormat = 2,
newText = "\n\nimpl std::fmt::Debug for Bruh {\n $0fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n f.debug_struct(\"Bruh\").field(\"a\", &self.a).finish()\n }\n}",
range = {
["end"] = {
character = 1,
line = 5
},
start = {
character = 1,
line = 5
}
}
} }, 1, "utf-8", vim.lsp.util.apply_text_edits) (stolen from that issue you opened :D) One problem is: if the server sends a snippetTextEdit with |
Oh, or the call you have in your plugin, that should still work |
So now 3.18 has brought SnippetTextEdit into the core lsp protocol. I wonder what is the best way to make sure LuaSnip is always handling them? |
I think it's okay to consider this situation as a server bug and just treat it like a regular text edit? In rust-analyzer's case, that came from always making every
3.18 represents |
Oh cool, thanks for letting me know!
Mhmm, yeah that seems reasonable.. just look for $0, if it doesn't exist -> regular text edit :) I can look into handling the new format, but it'll take a while :/ |
Hey 👋 I've just ported the changes from the rust-tools branch (which has been archived) to rustaceanvim: mrcjkb/rustaceanvim#420 My initial impression is that it works well. Please let me know if there's anything else you would like me to test 😄 |
Since the rust-analyzer implementation is experimental, it's likely that it will be replaced to the upstream one soon: rust-lang/rust-analyzer#16604 |
Oh, great! |
Afaict, Neovim doesn't support them yet and there's no issues or PRs.
Agreed. @MariaSolOs I hope you don't mind me tagging you, since you implemented snippets in core and might be interested 😃 |
Related: neovim/neovim#25696 |
@mrcjkb I wouldn't say that this is exactly part of the snippet roadmap. I haven't read the entire discussion but I believe all we need is Neovim being able to handle snippet workspace edits as documented in microsoft/vscode-languageserver-node#1343. If you want, I would suggest creating a separate issue in Neovim to track the work. To do this we would need to update the client's capabilities and expand snippets when returned as the workspace edit of a code action. As long as |
That's not what I was implying 😃 I will look into opening an issue in Nvim later.
Its snippets are "legit", but the current implementation is off-spec. |
Got it, I didn't mean my reply to sound snappy <3
Absolutely. Sticking to the LSP as much as possible and avoiding extension or server specific hacks will definitely makes everyone's jobs much easier. |
As requested for vim-snip (hrsh7th/vim-vsnip#225), I think it should be nice to be supported in LuaSnip as well...
Reference: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#snippet-textedit
Reference: hrsh7th/nvim-cmp#353 (comment)
Reference: simrat39/rust-tools.nvim#74
The text was updated successfully, but these errors were encountered: