Disable forceful sorting of the slash command argument completions (#16240)
Also bubble up the current active tab's path in the \tab argument completions. Release Notes: - N/A
This commit is contained in:
parent
b55e8383c8
commit
e8bae839ed
3 changed files with 113 additions and 68 deletions
|
@ -346,6 +346,10 @@ impl CompletionProvider for SlashCommandCompletionProvider {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sort_completions(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlashCommandLine {
|
impl SlashCommandLine {
|
||||||
|
|
|
@ -62,6 +62,16 @@ impl SlashCommand for TabSlashCommand {
|
||||||
if has_all_tabs_completion_item {
|
if has_all_tabs_completion_item {
|
||||||
return Task::ready(Ok(Vec::new()));
|
return Task::ready(Ok(Vec::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let active_item_path = workspace.as_ref().and_then(|workspace| {
|
||||||
|
workspace
|
||||||
|
.update(cx, |workspace, cx| {
|
||||||
|
let snapshot = active_item_buffer(workspace, cx).ok()?;
|
||||||
|
snapshot.resolve_file_path(cx, true)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
});
|
||||||
let current_query = arguments.last().cloned().unwrap_or_default();
|
let current_query = arguments.last().cloned().unwrap_or_default();
|
||||||
let tab_items_search =
|
let tab_items_search =
|
||||||
tab_items_for_queries(workspace, &[current_query], cancel, false, cx);
|
tab_items_for_queries(workspace, &[current_query], cancel, false, cx);
|
||||||
|
@ -73,6 +83,9 @@ impl SlashCommand for TabSlashCommand {
|
||||||
if argument_set.contains(&path_string) {
|
if argument_set.contains(&path_string) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
if active_item_path.is_some() && active_item_path == path {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
Some(ArgumentCompletion {
|
Some(ArgumentCompletion {
|
||||||
label: path_string.clone().into(),
|
label: path_string.clone().into(),
|
||||||
new_text: path_string,
|
new_text: path_string,
|
||||||
|
@ -81,15 +94,26 @@ impl SlashCommand for TabSlashCommand {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Some(ArgumentCompletion {
|
let active_item_completion = active_item_path.as_deref().map(|active_item_path| {
|
||||||
|
let path_string = active_item_path.to_string_lossy().to_string();
|
||||||
|
ArgumentCompletion {
|
||||||
|
label: path_string.clone().into(),
|
||||||
|
new_text: path_string,
|
||||||
|
replace_previous_arguments: false,
|
||||||
|
run_command,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(active_item_completion
|
||||||
|
.into_iter()
|
||||||
|
.chain(Some(ArgumentCompletion {
|
||||||
label: ALL_TABS_COMPLETION_ITEM.into(),
|
label: ALL_TABS_COMPLETION_ITEM.into(),
|
||||||
new_text: ALL_TABS_COMPLETION_ITEM.to_owned(),
|
new_text: ALL_TABS_COMPLETION_ITEM.to_owned(),
|
||||||
replace_previous_arguments: false,
|
replace_previous_arguments: false,
|
||||||
run_command: true,
|
run_command: true,
|
||||||
})
|
}))
|
||||||
.into_iter()
|
|
||||||
.chain(tab_completion_items)
|
.chain(tab_completion_items)
|
||||||
.collect::<Vec<_>>())
|
.collect())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,19 +186,7 @@ fn tab_items_for_queries(
|
||||||
.context("no workspace")?
|
.context("no workspace")?
|
||||||
.update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
if strict_match && empty_query {
|
if strict_match && empty_query {
|
||||||
let active_editor = workspace
|
let snapshot = active_item_buffer(workspace, cx)?;
|
||||||
.active_item(cx)
|
|
||||||
.context("no active item")?
|
|
||||||
.downcast::<Editor>()
|
|
||||||
.context("active item is not an editor")?;
|
|
||||||
let snapshot = active_editor
|
|
||||||
.read(cx)
|
|
||||||
.buffer()
|
|
||||||
.read(cx)
|
|
||||||
.as_singleton()
|
|
||||||
.context("active editor is not a singleton buffer")?
|
|
||||||
.read(cx)
|
|
||||||
.snapshot();
|
|
||||||
let full_path = snapshot.resolve_file_path(cx, true);
|
let full_path = snapshot.resolve_file_path(cx, true);
|
||||||
return anyhow::Ok(vec![(full_path, snapshot, 0)]);
|
return anyhow::Ok(vec![(full_path, snapshot, 0)]);
|
||||||
}
|
}
|
||||||
|
@ -279,3 +291,23 @@ fn tab_items_for_queries(
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn active_item_buffer(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
cx: &mut ui::ViewContext<Workspace>,
|
||||||
|
) -> anyhow::Result<BufferSnapshot> {
|
||||||
|
let active_editor = workspace
|
||||||
|
.active_item(cx)
|
||||||
|
.context("no active item")?
|
||||||
|
.downcast::<Editor>()
|
||||||
|
.context("active item is not an editor")?;
|
||||||
|
let snapshot = active_editor
|
||||||
|
.read(cx)
|
||||||
|
.buffer()
|
||||||
|
.read(cx)
|
||||||
|
.as_singleton()
|
||||||
|
.context("active editor is not a singleton buffer")?
|
||||||
|
.read(cx)
|
||||||
|
.snapshot();
|
||||||
|
Ok(snapshot)
|
||||||
|
}
|
||||||
|
|
|
@ -900,6 +900,7 @@ enum ContextMenuOrigin {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct CompletionsMenu {
|
struct CompletionsMenu {
|
||||||
id: CompletionId,
|
id: CompletionId,
|
||||||
|
sort_completions: bool,
|
||||||
initial_position: Anchor,
|
initial_position: Anchor,
|
||||||
buffer: Model<Buffer>,
|
buffer: Model<Buffer>,
|
||||||
completions: Arc<RwLock<Box<[Completion]>>>,
|
completions: Arc<RwLock<Box<[Completion]>>>,
|
||||||
|
@ -1225,6 +1226,7 @@ impl CompletionsMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
let completions = self.completions.read();
|
let completions = self.completions.read();
|
||||||
|
if self.sort_completions {
|
||||||
matches.sort_unstable_by_key(|mat| {
|
matches.sort_unstable_by_key(|mat| {
|
||||||
// We do want to strike a balance here between what the language server tells us
|
// We do want to strike a balance here between what the language server tells us
|
||||||
// to sort by (the sort_text) and what are "obvious" good matches (i.e. when you type
|
// to sort by (the sort_text) and what are "obvious" good matches (i.e. when you type
|
||||||
|
@ -1274,6 +1276,7 @@ impl CompletionsMenu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for mat in &mut matches {
|
for mat in &mut matches {
|
||||||
let completion = &completions[mat.candidate_id];
|
let completion = &completions[mat.candidate_id];
|
||||||
|
@ -4105,6 +4108,7 @@ impl Editor {
|
||||||
trigger_kind,
|
trigger_kind,
|
||||||
};
|
};
|
||||||
let completions = provider.completions(&buffer, buffer_position, completion_context, cx);
|
let completions = provider.completions(&buffer, buffer_position, completion_context, cx);
|
||||||
|
let sort_completions = provider.sort_completions();
|
||||||
|
|
||||||
let id = post_inc(&mut self.next_completion_id);
|
let id = post_inc(&mut self.next_completion_id);
|
||||||
let task = cx.spawn(|this, mut cx| {
|
let task = cx.spawn(|this, mut cx| {
|
||||||
|
@ -4116,6 +4120,7 @@ impl Editor {
|
||||||
let menu = if let Some(completions) = completions {
|
let menu = if let Some(completions) = completions {
|
||||||
let mut menu = CompletionsMenu {
|
let mut menu = CompletionsMenu {
|
||||||
id,
|
id,
|
||||||
|
sort_completions,
|
||||||
initial_position: position,
|
initial_position: position,
|
||||||
match_candidates: completions
|
match_candidates: completions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -12045,6 +12050,10 @@ pub trait CompletionProvider {
|
||||||
trigger_in_words: bool,
|
trigger_in_words: bool,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
|
fn sort_completions(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snippet_completions(
|
fn snippet_completions(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue