mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 05:51:14 +00:00
lsp: Fix vtsls completeFunctionCalls setting being ignored (#53285)
Some language servers (notably `vtsls` with `completeFunctionCalls`) update `insertText/textEdit` during `completionItem/resolve` to add snippet content like function call parentheses. Previously, `Completion.new_text` was only set from the initial completion response and never re-derived after resolve, so the snippet text was silently discarded. Re-derive `new_text` from the resolved `lsp_completion`. Only the text content is updated -- replace/insert ranges are left as anchors from the original response since the LSP ranges in the resolved text_edit are stale when completions are cached across keystrokes (re: #34094). Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #53275. Release Notes: - Fixed the `vtsls` `completeFunctionCalls` setting being ignored
This commit is contained in:
parent
9e435c0fd6
commit
96eb05166f
1 changed files with 34 additions and 3 deletions
|
|
@ -6688,9 +6688,6 @@ impl LspStore {
|
|||
.into_response()
|
||||
.context("resolve completion")?;
|
||||
|
||||
// We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
|
||||
// Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
|
||||
|
||||
let mut completions = completions.borrow_mut();
|
||||
let completion = &mut completions[completion_index];
|
||||
if let CompletionSource::Lsp {
|
||||
|
|
@ -6709,6 +6706,40 @@ impl LspStore {
|
|||
);
|
||||
**lsp_completion = resolved_completion;
|
||||
*resolved = true;
|
||||
|
||||
// We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not supposed to change during resolve.
|
||||
// Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
|
||||
//
|
||||
// We still re-derive new_text here as a workaround for the specific
|
||||
// VS Code TypeScript completion resolve flow that vtsls wraps:
|
||||
// https://github.com/microsoft/vscode/blob/838b48504cd9a2338e2ca9e854da9cec990c4d57/extensions/typescript-language-features/src/languageFeatures/completions.ts#L218
|
||||
//
|
||||
// Some servers (e.g. vtsls with completeFunctionCalls) update
|
||||
// insertText/textEdit during resolve to add snippet content like
|
||||
// function call parentheses.
|
||||
//
|
||||
// vtsls resolve flow:
|
||||
// https://github.com/yioneko/vtsls/blob/fecf52324a30e72dfab1537047556076720c1a5f/packages/service/src/service/completion.ts#L228-L244
|
||||
// vtsls converter (isSnippet / insertTextFormat):
|
||||
// https://github.com/yioneko/vtsls/blob/28e075105d7711d635ebf8aefc971bb8e1d2fe65/packages/service/src/utils/converter.ts#L149-L200
|
||||
//
|
||||
// NB: We only update the text content here, NOT the replace/insert
|
||||
// ranges on `Completion`. Those ranges were converted to anchors from
|
||||
// the original response and stay valid across buffer edits. The LSP
|
||||
// ranges in the resolved text_edit are stale when completions are
|
||||
// cached across keystrokes (see #34094).
|
||||
let resolved_new_text = lsp_completion
|
||||
.text_edit
|
||||
.as_ref()
|
||||
.map(|edit| match edit {
|
||||
lsp::CompletionTextEdit::Edit(e) => e.new_text.clone(),
|
||||
lsp::CompletionTextEdit::InsertAndReplace(e) => e.new_text.clone(),
|
||||
})
|
||||
.or_else(|| lsp_completion.insert_text.clone());
|
||||
if let Some(mut resolved_new_text) = resolved_new_text {
|
||||
LineEnding::normalize(&mut resolved_new_text);
|
||||
completion.new_text = resolved_new_text;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue