Keep and filter word completions on input, if the menu is open (#26979)
Follow-up of https://github.com/zed-industries/zed/pull/26410 Release Notes: - N/A
This commit is contained in:
@@ -180,6 +180,7 @@ pub struct CompletionsMenu {
|
||||
scroll_handle: UniformListScrollHandle,
|
||||
resolve_completions: bool,
|
||||
show_completion_documentation: bool,
|
||||
pub(super) ignore_completion_provider: bool,
|
||||
last_rendered_range: Rc<RefCell<Option<Range<usize>>>>,
|
||||
markdown_element: Option<Entity<Markdown>>,
|
||||
}
|
||||
@@ -189,6 +190,7 @@ impl CompletionsMenu {
|
||||
id: CompletionId,
|
||||
sort_completions: bool,
|
||||
show_completion_documentation: bool,
|
||||
ignore_completion_provider: bool,
|
||||
initial_position: Anchor,
|
||||
buffer: Entity<Buffer>,
|
||||
completions: Box<[Completion]>,
|
||||
@@ -205,6 +207,7 @@ impl CompletionsMenu {
|
||||
initial_position,
|
||||
buffer,
|
||||
show_completion_documentation,
|
||||
ignore_completion_provider,
|
||||
completions: RefCell::new(completions).into(),
|
||||
match_candidates,
|
||||
entries: RefCell::new(Vec::new()).into(),
|
||||
@@ -266,6 +269,7 @@ impl CompletionsMenu {
|
||||
scroll_handle: UniformListScrollHandle::new(),
|
||||
resolve_completions: false,
|
||||
show_completion_documentation: false,
|
||||
ignore_completion_provider: false,
|
||||
last_rendered_range: RefCell::new(None).into(),
|
||||
markdown_element: None,
|
||||
}
|
||||
|
||||
@@ -3546,7 +3546,21 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.is_completion_trigger(text, trigger_in_words, cx) {
|
||||
let ignore_completion_provider = self
|
||||
.context_menu
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|menu| match menu {
|
||||
CodeContextMenu::Completions(completions_menu) => {
|
||||
completions_menu.ignore_completion_provider
|
||||
}
|
||||
CodeContextMenu::CodeActions(_) => false,
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
if ignore_completion_provider {
|
||||
self.show_word_completions(&ShowWordCompletions, window, cx);
|
||||
} else if self.is_completion_trigger(text, trigger_in_words, cx) {
|
||||
self.show_completions(
|
||||
&ShowCompletions {
|
||||
trigger: Some(text.to_owned()).filter(|x| !x.is_empty()),
|
||||
@@ -4183,6 +4197,7 @@ impl Editor {
|
||||
id,
|
||||
sort_completions,
|
||||
show_completion_documentation,
|
||||
ignore_completion_provider,
|
||||
position,
|
||||
buffer.clone(),
|
||||
completions.into(),
|
||||
|
||||
@@ -9212,7 +9212,7 @@ async fn test_completion(cx: &mut TestAppContext) {
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_words_completion(cx: &mut TestAppContext) {
|
||||
async fn test_word_completion(cx: &mut TestAppContext) {
|
||||
let lsp_fetch_timeout_ms = 10;
|
||||
init_test(cx, |language_settings| {
|
||||
language_settings.defaults.completions = Some(CompletionSettings {
|
||||
@@ -9354,7 +9354,7 @@ async fn test_word_completions_do_not_duplicate_lsp_ones(cx: &mut TestAppContext
|
||||
cx.executor().run_until_parked();
|
||||
cx.condition(|editor, _| editor.context_menu_visible())
|
||||
.await;
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
cx.update_editor(|editor, _, _| {
|
||||
if let Some(CodeContextMenu::Completions(menu)) = editor.context_menu.borrow_mut().as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
@@ -9365,7 +9365,78 @@ async fn test_word_completions_do_not_duplicate_lsp_ones(cx: &mut TestAppContext
|
||||
} else {
|
||||
panic!("expected completion menu to be open");
|
||||
}
|
||||
editor.cancel(&Cancel, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_word_completions_continue_on_typing(cx: &mut TestAppContext) {
|
||||
init_test(cx, |language_settings| {
|
||||
language_settings.defaults.completions = Some(CompletionSettings {
|
||||
words: WordsCompletionMode::Disabled,
|
||||
lsp: true,
|
||||
lsp_fetch_timeout_ms: 0,
|
||||
});
|
||||
});
|
||||
|
||||
let mut cx = EditorLspTestContext::new_rust(
|
||||
lsp::ServerCapabilities {
|
||||
completion_provider: Some(lsp::CompletionOptions {
|
||||
trigger_characters: Some(vec![".".to_string(), ":".to_string()]),
|
||||
..lsp::CompletionOptions::default()
|
||||
}),
|
||||
signature_help_provider: Some(lsp::SignatureHelpOptions::default()),
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
|
||||
let _completion_requests_handler =
|
||||
cx.lsp
|
||||
.server
|
||||
.on_request::<lsp::request::Completion, _, _>(move |_, _| async move {
|
||||
panic!("LSP completions should not be queried when dealing with word completions")
|
||||
});
|
||||
|
||||
cx.set_state(indoc! {"ˇ
|
||||
first
|
||||
last
|
||||
second
|
||||
"});
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
editor.show_word_completions(&ShowWordCompletions, window, cx);
|
||||
});
|
||||
cx.executor().run_until_parked();
|
||||
cx.condition(|editor, _| editor.context_menu_visible())
|
||||
.await;
|
||||
cx.update_editor(|editor, _, _| {
|
||||
if let Some(CodeContextMenu::Completions(menu)) = editor.context_menu.borrow_mut().as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
completion_menu_entries(&menu),
|
||||
&["first", "last", "second"],
|
||||
"`ShowWordCompletions` action should show word completions"
|
||||
);
|
||||
} else {
|
||||
panic!("expected completion menu to be open");
|
||||
}
|
||||
});
|
||||
|
||||
cx.simulate_keystroke("s");
|
||||
cx.executor().run_until_parked();
|
||||
cx.condition(|editor, _| editor.context_menu_visible())
|
||||
.await;
|
||||
cx.update_editor(|editor, _, _| {
|
||||
if let Some(CodeContextMenu::Completions(menu)) = editor.context_menu.borrow_mut().as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
completion_menu_entries(&menu),
|
||||
&["second"],
|
||||
"After showing word completions, further editing should filter them and not query the LSP"
|
||||
);
|
||||
} else {
|
||||
panic!("expected completion menu to be open");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user