Do not resolve completions if extra edits are available
This commit is contained in:
parent
6d96c6ef51
commit
c732aa1617
3 changed files with 98 additions and 15 deletions
|
@ -7294,6 +7294,92 @@ async fn test_completions_with_extra_edits(cx: &mut gpui::TestAppContext) {
|
||||||
|
|
||||||
request.next().await;
|
request.next().await;
|
||||||
|
|
||||||
|
cx.condition(|editor, _| editor.context_menu_visible())
|
||||||
|
.await;
|
||||||
|
let apply_additional_edits = cx.update_editor(|editor, cx| {
|
||||||
|
editor
|
||||||
|
.confirm_completion(&ConfirmCompletion::default(), cx)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
cx.assert_editor_state(indoc! {"fn main() { let a = 2.Some(2)ˇ; }"});
|
||||||
|
apply_additional_edits.await.unwrap();
|
||||||
|
cx.assert_editor_state(indoc! {"fn main() { let a = Some(2)ˇ; }"});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_completions_with_extra_resolved_edits(cx: &mut gpui::TestAppContext) {
|
||||||
|
init_test(cx, |_| {});
|
||||||
|
|
||||||
|
let mut cx = EditorLspTestContext::new_rust(
|
||||||
|
lsp::ServerCapabilities {
|
||||||
|
completion_provider: Some(lsp::CompletionOptions {
|
||||||
|
trigger_characters: Some(vec![".".to_string()]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
cx.set_state(indoc! {"fn main() { let a = 2ˇ; }"});
|
||||||
|
cx.simulate_keystroke(".");
|
||||||
|
let completion_item = lsp::CompletionItem {
|
||||||
|
label: "some".into(),
|
||||||
|
kind: Some(lsp::CompletionItemKind::SNIPPET),
|
||||||
|
detail: Some("Wrap the expression in an `Option::Some`".to_string()),
|
||||||
|
documentation: Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
|
||||||
|
kind: lsp::MarkupKind::Markdown,
|
||||||
|
value: "```rust\nSome(2)\n```".to_string(),
|
||||||
|
})),
|
||||||
|
deprecated: Some(false),
|
||||||
|
sort_text: Some("fffffff2".to_string()),
|
||||||
|
filter_text: Some("some".to_string()),
|
||||||
|
insert_text_format: Some(lsp::InsertTextFormat::SNIPPET),
|
||||||
|
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
||||||
|
range: lsp::Range {
|
||||||
|
start: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 22,
|
||||||
|
},
|
||||||
|
end: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 22,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new_text: "Some(2)".to_string(),
|
||||||
|
})),
|
||||||
|
additional_text_edits: Some(vec![lsp::TextEdit {
|
||||||
|
range: lsp::Range {
|
||||||
|
start: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 20,
|
||||||
|
},
|
||||||
|
end: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 22,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new_text: "".to_string(),
|
||||||
|
}]),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let closure_completion_item = completion_item.clone();
|
||||||
|
let mut request = cx.handle_request::<lsp::request::Completion, _, _>(move |_, _, _| {
|
||||||
|
let task_completion_item = closure_completion_item.clone();
|
||||||
|
async move {
|
||||||
|
Ok(Some(lsp::CompletionResponse::Array(vec![
|
||||||
|
lsp::CompletionItem {
|
||||||
|
additional_text_edits: None,
|
||||||
|
..task_completion_item
|
||||||
|
},
|
||||||
|
])))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
request.next().await;
|
||||||
|
|
||||||
cx.condition(|editor, _| editor.context_menu_visible())
|
cx.condition(|editor, _| editor.context_menu_visible())
|
||||||
.await;
|
.await;
|
||||||
let apply_additional_edits = cx.update_editor(|editor, cx| {
|
let apply_additional_edits = cx.update_editor(|editor, cx| {
|
||||||
|
|
|
@ -1349,6 +1349,7 @@ impl LspCommand for GetCompletions {
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let completions = buffer.read_with(&cx, |buffer, _| {
|
let completions = buffer.read_with(&cx, |buffer, _| {
|
||||||
let language = buffer.language().cloned();
|
let language = buffer.language().cloned();
|
||||||
let snapshot = buffer.snapshot();
|
let snapshot = buffer.snapshot();
|
||||||
|
@ -1357,17 +1358,6 @@ impl LspCommand for GetCompletions {
|
||||||
completions
|
completions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |mut lsp_completion| {
|
.filter_map(move |mut lsp_completion| {
|
||||||
// TODO kb store these? at least, should only allow this when we have resolve
|
|
||||||
// // For now, we can only handle additional edits if they are returned
|
|
||||||
// // when resolving the completion, not if they are present initially.
|
|
||||||
// if lsp_completion
|
|
||||||
// .additional_text_edits
|
|
||||||
// .as_ref()
|
|
||||||
// .map_or(false, |edits| !edits.is_empty())
|
|
||||||
// {
|
|
||||||
// return None;
|
|
||||||
// }
|
|
||||||
|
|
||||||
let (old_range, mut new_text) = match lsp_completion.text_edit.as_ref() {
|
let (old_range, mut new_text) = match lsp_completion.text_edit.as_ref() {
|
||||||
// If the language server provides a range to overwrite, then
|
// If the language server provides a range to overwrite, then
|
||||||
// check that the range is valid.
|
// check that the range is valid.
|
||||||
|
|
|
@ -4446,11 +4446,18 @@ impl Project {
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let resolved_completion = lang_server
|
let additional_text_edits = if let Some(edits) =
|
||||||
|
completion.lsp_completion.additional_text_edits.as_ref()
|
||||||
|
{
|
||||||
|
Some(edits.clone())
|
||||||
|
} else {
|
||||||
|
lang_server
|
||||||
.request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
|
.request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
|
||||||
.await?;
|
.await?
|
||||||
|
.additional_text_edits
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(edits) = resolved_completion.additional_text_edits {
|
if let Some(edits) = additional_text_edits {
|
||||||
let edits = this
|
let edits = this
|
||||||
.update(&mut cx, |this, cx| {
|
.update(&mut cx, |this, cx| {
|
||||||
this.edits_from_lsp(
|
this.edits_from_lsp(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue