assistant: Use code label for tab slash command completions (#17296)
This adopts the same approach we use for the `/file` command, which has the benefit that, even if the path is long, the filename is always visible. | Before | After | |--------|-------| | <img width="564" alt="image" src="https://github.com/user-attachments/assets/a43574af-e4c1-4f11-be70-49d6020557c4"> | <img width="567" alt="image" src="https://github.com/user-attachments/assets/4db383b9-5039-4f35-b821-e1cc1a4ea7e8"> | Release Notes: - Improved UX of tab slash command completions
This commit is contained in:
parent
b41ddbd018
commit
64a8b14e49
1 changed files with 37 additions and 11 deletions
|
@ -9,13 +9,13 @@ use collections::{HashMap, HashSet};
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use gpui::{Entity, Task, WeakView};
|
use gpui::{Entity, Task, WeakView};
|
||||||
use language::{BufferSnapshot, LspAdapterDelegate};
|
use language::{BufferSnapshot, CodeLabel, HighlightId, LspAdapterDelegate};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Write,
|
fmt::Write,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
};
|
};
|
||||||
use ui::WindowContext;
|
use ui::{ActiveTheme, WindowContext};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
pub(crate) struct TabSlashCommand;
|
pub(crate) struct TabSlashCommand;
|
||||||
|
@ -79,6 +79,8 @@ impl SlashCommand for TabSlashCommand {
|
||||||
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);
|
||||||
|
|
||||||
|
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
|
||||||
cx.spawn(|_| async move {
|
cx.spawn(|_| async move {
|
||||||
let tab_items = tab_items_search.await?;
|
let tab_items = tab_items_search.await?;
|
||||||
let run_command = tab_items.len() == 1;
|
let run_command = tab_items.len() == 1;
|
||||||
|
@ -90,8 +92,9 @@ impl SlashCommand for TabSlashCommand {
|
||||||
if active_item_path.is_some() && active_item_path == path {
|
if active_item_path.is_some() && active_item_path == path {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
let label = create_tab_completion_label(path.as_ref()?, comment_id);
|
||||||
Some(ArgumentCompletion {
|
Some(ArgumentCompletion {
|
||||||
label: path_string.clone().into(),
|
label,
|
||||||
new_text: path_string,
|
new_text: path_string,
|
||||||
replace_previous_arguments: false,
|
replace_previous_arguments: false,
|
||||||
after_completion: run_command.into(),
|
after_completion: run_command.into(),
|
||||||
|
@ -100,14 +103,17 @@ impl SlashCommand for TabSlashCommand {
|
||||||
|
|
||||||
let active_item_completion = active_item_path
|
let active_item_completion = active_item_path
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.map(|active_item_path| active_item_path.to_string_lossy().to_string())
|
.map(|active_item_path| {
|
||||||
.filter(|path_string| !argument_set.contains(path_string))
|
let path_string = active_item_path.to_string_lossy().to_string();
|
||||||
.map(|path_string| ArgumentCompletion {
|
let label = create_tab_completion_label(active_item_path, comment_id);
|
||||||
label: path_string.clone().into(),
|
ArgumentCompletion {
|
||||||
new_text: path_string,
|
label,
|
||||||
replace_previous_arguments: false,
|
new_text: path_string,
|
||||||
after_completion: run_command.into(),
|
replace_previous_arguments: false,
|
||||||
});
|
after_completion: run_command.into(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(|completion| !argument_set.contains(&completion.new_text));
|
||||||
|
|
||||||
Ok(active_item_completion
|
Ok(active_item_completion
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -319,3 +325,23 @@ fn active_item_buffer(
|
||||||
.snapshot();
|
.snapshot();
|
||||||
Ok(snapshot)
|
Ok(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_tab_completion_label(
|
||||||
|
path: &std::path::Path,
|
||||||
|
comment_id: Option<HighlightId>,
|
||||||
|
) -> CodeLabel {
|
||||||
|
let file_name = path
|
||||||
|
.file_name()
|
||||||
|
.map(|f| f.to_string_lossy())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let parent_path = path
|
||||||
|
.parent()
|
||||||
|
.map(|p| p.to_string_lossy())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut label = CodeLabel::default();
|
||||||
|
label.push_str(&file_name, None);
|
||||||
|
label.push_str(" ", None);
|
||||||
|
label.push_str(&parent_path, comment_id);
|
||||||
|
label.filter_range = 0..file_name.len();
|
||||||
|
label
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue