language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

Auto-import duplication because of redundant `additionalTextEdits` sent by LSP in Zed

Open Blankeos opened this issue 1 year ago • 4 comments

Describe the bug

Whenever I try to import anything from Svelte, the import ... from the autoimport gets duplicated.

More details on the issue at Zed's repo: https://github.com/zed-industries/zed/issues/19214#issue-2588344463

(Video by @ArturGalstyan1)

https://private-user-images.githubusercontent.com/152854677/376570126-f3bb6ea6-50d2-43a0-ab34-2a3b7ab8a0ee.mov?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzM2ODc2NTgsIm5iZiI6MTczMzY4NzM1OCwicGF0aCI6Ii8xNTI4NTQ2NzcvMzc2NTcwMTI2LWYzYmI2ZWE2LTUwZDItNDNhMC1hYjM0LTJhM2I3YWI4YTBlZS5tb3Y_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMjA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTIwOFQxOTQ5MThaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04MGM5OTAwMWY0NzE3MTNiMTEyYzcwODcyZDI0OTJiOTc1MzE2MTc1M2UyZDdkMzk2NGIxYTVjZTY4MTQ1NTM1JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.W7CRGwKQC517kqRuoarE4NK3hh1nKuCkN8_7qADtnC0

I think there's two problems here:

  1. Zed's lack of safeguards against processing redundant additionalTextEdits.
  2. Svelte's LSP sending redundant additionalTextEdits.

Wondering if the Svelte folks know if this is an issue worth fixing or if Zed just needs to tweak their request.

This issue does not exist in VSCode by the way. I compared the logs and Zed just sends additionalTextData when it selects an import under the dropdown.

Reproduction

  1. Install Zed
  2. Install the Svelte Extension in Zed (Cmd + Shift + X)
  3. Go to any .svelte file.
  4. Write any import like page, then ctrl + space to get.

You can also debug the language server by opening the command palette (Cmd + Shift + P), then clicking on RPC Messages under svelte-language-server: image

Expected behaviour

No duplicate imports

System Info

  • OS: macOS 15.1.1
  • IDE: Zed: v0.164.2 (Zed)
  • I unfortunately can't find the Language Server version. I assume latest as of now. This is the code that the Zed Svelte Extension uses to initialize the LSP.

Which package is the issue about?

svelte-language-server

Additional Information, eg. Screenshots

If this is just expected behavior from the LSP, feel free to close! Thank you!

Blankeos avatar Dec 08 '24 19:12 Blankeos

Can you check if Zed sent the resolve request twice? I can't think of another possibility where this might happen. We only have two places where we set additionalTextEdits. One is to split part of TextEdit to additionalTextEdits but I didn't see textEdit in your log. https://github.com/sveltejs/language-tools/blob/02db54de1f2fc44d958d67113a9d0fb41a8f6fe7/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts#L874-L885

The other is to add the edit either to an empty array or existing if any already exists. But since there isn't any other place where we set it, unless the same code ran twice it should always be the former. If this is the case, We could remove the redundant concat but you should still ask why Zed sent the request twice since it's just a waste of time.

https://github.com/sveltejs/language-tools/blob/02db54de1f2fc44d958d67113a9d0fb41a8f6fe7/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts#L983-L985

jasonlyu123 avatar Dec 09 '24 00:12 jasonlyu123

Thanks for getting back! @jasonlyu123. So yeah I think you're 100% right. Thanks for narrowing this down! It is definitely the "Zed sends the request twice" case. I wasn't able to catch it the first time because I assumed that the ctrl + space hotkey only gets suggestions. Not resolve completions. It in-fact resolves completions for every single item in the suggestions.

I honestly don't know why though.

https://github.com/user-attachments/assets/a17c9f4a-49d4-459b-81bb-6d975bc545ac

Blankeos avatar Dec 09 '24 02:12 Blankeos

Thank you for the discussion. From Zed's side, this is indeed a bug and https://github.com/zed-industries/zed/pull/22448 fixes it, in the next release there will be one resolve request per item only.

No strong opinions, but I find this behavior confusing in general, as no other servers (vtsls, rust-analyzer, pyright, etc.) are doing nothing similar.

I see a small hint to this in https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItem

/**
 * A data entry field that is preserved on a completion item between
 * a completion and a completion resolve request.
 */

as something that the language server manages, and can omit in the first resolve response.

SomeoneToIgnore avatar Dec 27 '24 14:12 SomeoneToIgnore

As far as I remember, one of the reasons is that we had additional text edits before resolving to workaround a VSCode behaviour. I can check if it's still needed or if there is another way to solve it.

I just think it still makes sense to ask if it's intentional for Zed to resolve the completion item twice. It's also the first time I saw a client that does this.

jasonlyu123 avatar Dec 27 '24 15:12 jasonlyu123