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:
Bennet Bo Fenner 2024-09-03 12:32:53 +02:00 committed by GitHub
parent b41ddbd018
commit 64a8b14e49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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
}