From 8bc5bcf0a676982e52807b14891cecbad3820171 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 8 Nov 2024 11:35:39 -0500 Subject: [PATCH] assistant: Fix completions for slash commands provided by context servers (#20423) This PR fixes an issue introduced in #20372 that was causing slash commands provided by context servers to not show up in the completions menu. Release Notes: - N/A --- crates/assistant/src/assistant_panel.rs | 1 + crates/assistant/src/prompt_library.rs | 7 ++++++- crates/assistant/src/slash_command.rs | 12 ++++++++---- .../src/slash_command_working_set.rs | 19 ++++++++++++++++--- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index 227a666a67ac4be9b45eed88e7f904abde619a86..9bcba4a5efe378a11e13140a4e597653c2704f5c 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -1547,6 +1547,7 @@ impl ContextEditor { cx: &mut ViewContext, ) -> Self { let completion_provider = SlashCommandCompletionProvider::new( + context.read(cx).slash_commands.clone(), Some(cx.view().downgrade()), Some(workspace.clone()), ); diff --git a/crates/assistant/src/prompt_library.rs b/crates/assistant/src/prompt_library.rs index 298bb322265c5f70134a42e0d54c2a9e3885f134..71750925def721d8757cbcb4cd5317b4ed2d1a29 100644 --- a/crates/assistant/src/prompt_library.rs +++ b/crates/assistant/src/prompt_library.rs @@ -1,3 +1,4 @@ +use crate::SlashCommandWorkingSet; use crate::{slash_command::SlashCommandCompletionProvider, AssistantPanel, InlineAssistant}; use anyhow::{anyhow, Result}; use chrono::{DateTime, Utc}; @@ -522,7 +523,11 @@ impl PromptLibrary { editor.set_use_modal_editing(false); editor.set_current_line_highlight(Some(CurrentLineHighlight::None)); editor.set_completion_provider(Some(Box::new( - SlashCommandCompletionProvider::new(None, None), + SlashCommandCompletionProvider::new( + Arc::new(SlashCommandWorkingSet::default()), + None, + None, + ), ))); if focus { editor.focus(cx); diff --git a/crates/assistant/src/slash_command.rs b/crates/assistant/src/slash_command.rs index 44641701b2246f7a789ea925e404090b7c457e61..833b42e7566e0d9c99cb5d87627b50188810dfdd 100644 --- a/crates/assistant/src/slash_command.rs +++ b/crates/assistant/src/slash_command.rs @@ -1,4 +1,5 @@ use crate::assistant_panel::ContextEditor; +use crate::SlashCommandWorkingSet; use anyhow::Result; use assistant_slash_command::AfterCompletion; pub use assistant_slash_command::{SlashCommand, SlashCommandOutput, SlashCommandRegistry}; @@ -39,6 +40,7 @@ pub mod terminal_command; pub(crate) struct SlashCommandCompletionProvider { cancel_flag: Mutex>, + slash_commands: Arc, editor: Option>, workspace: Option>, } @@ -52,11 +54,13 @@ pub(crate) struct SlashCommandLine { impl SlashCommandCompletionProvider { pub fn new( + slash_commands: Arc, editor: Option>, workspace: Option>, ) -> Self { Self { cancel_flag: Mutex::new(Arc::new(AtomicBool::new(false))), + slash_commands, editor, workspace, } @@ -69,9 +73,9 @@ impl SlashCommandCompletionProvider { name_range: Range, cx: &mut WindowContext, ) -> Task>> { - let commands = SlashCommandRegistry::global(cx); - let candidates = commands - .command_names() + let slash_commands = self.slash_commands.clone(); + let candidates = slash_commands + .command_names(cx) .into_iter() .enumerate() .map(|(ix, def)| StringMatchCandidate { @@ -98,7 +102,7 @@ impl SlashCommandCompletionProvider { matches .into_iter() .filter_map(|mat| { - let command = commands.command(&mat.string)?; + let command = slash_commands.command(&mat.string, cx)?; let mut new_text = mat.string.clone(); let requires_argument = command.requires_argument(); let accepts_arguments = command.accepts_arguments(); diff --git a/crates/assistant/src/slash_command_working_set.rs b/crates/assistant/src/slash_command_working_set.rs index 93979557c177c267c7ee79d569b3601087c18252..b9611c14e640755e15a687187e55c1e40e0b1306 100644 --- a/crates/assistant/src/slash_command_working_set.rs +++ b/crates/assistant/src/slash_command_working_set.rs @@ -4,7 +4,7 @@ use gpui::AppContext; use parking_lot::Mutex; use std::sync::Arc; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Default)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)] pub struct SlashCommandId(usize); /// A working set of slash commands for use in one instance of the Assistant Panel. @@ -16,7 +16,7 @@ pub struct SlashCommandWorkingSet { #[derive(Default)] struct WorkingSetState { context_server_commands_by_id: HashMap>, - context_server_commands_by_name: HashMap>, + context_server_commands_by_name: HashMap, Arc>, next_command_id: SlashCommandId, } @@ -30,6 +30,19 @@ impl SlashCommandWorkingSet { .or_else(|| SlashCommandRegistry::global(cx).command(name)) } + pub fn command_names(&self, cx: &AppContext) -> Vec> { + let mut command_names = SlashCommandRegistry::global(cx).command_names(); + command_names.extend( + self.state + .lock() + .context_server_commands_by_name + .keys() + .cloned(), + ); + + command_names + } + pub fn featured_command_names(&self, cx: &AppContext) -> Vec> { SlashCommandRegistry::global(cx).featured_command_names() } @@ -60,7 +73,7 @@ impl WorkingSetState { self.context_server_commands_by_name.extend( self.context_server_commands_by_id .values() - .map(|command| (command.name(), command.clone())), + .map(|command| (command.name().into(), command.clone())), ); } }