diff --git a/crates/assistant/src/context.rs b/crates/assistant/src/context.rs index d337606dfa..d2b80ca224 100644 --- a/crates/assistant/src/context.rs +++ b/crates/assistant/src/context.rs @@ -7,7 +7,7 @@ use crate::{ }; use anyhow::{anyhow, Context as _, Result}; use assistant_slash_command::{ - SlashCommandOutput, SlashCommandOutputSection, SlashCommandRegistry, + SlashCommandOutputSection, SlashCommandRegistry, SlashCommandResult, }; use assistant_tool::ToolRegistry; use client::{self, proto, telemetry::Telemetry}; @@ -1677,7 +1677,7 @@ impl Context { pub fn insert_command_output( &mut self, command_range: Range, - output: Task>, + output: Task, ensure_trailing_newline: bool, expand_result: bool, cx: &mut ModelContext, diff --git a/crates/assistant/src/context/context_tests.rs b/crates/assistant/src/context/context_tests.rs index a11cfc375d..4d866b4d8b 100644 --- a/crates/assistant/src/context/context_tests.rs +++ b/crates/assistant/src/context/context_tests.rs @@ -6,7 +6,7 @@ use crate::{ use anyhow::Result; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, - SlashCommandRegistry, + SlashCommandRegistry, SlashCommandResult, }; use collections::HashSet; use fs::FakeFs; @@ -1416,7 +1416,7 @@ impl SlashCommand for FakeSlashCommand { _workspace: WeakView, _delegate: Option>, _cx: &mut WindowContext, - ) -> Task> { + ) -> Task { Task::ready(Ok(SlashCommandOutput { text: format!("Executed fake command: {}", self.0), sections: vec![], diff --git a/crates/assistant/src/slash_command/auto_command.rs b/crates/assistant/src/slash_command/auto_command.rs index 14bbb7c841..352b5a3ac9 100644 --- a/crates/assistant/src/slash_command/auto_command.rs +++ b/crates/assistant/src/slash_command/auto_command.rs @@ -1,7 +1,8 @@ -use super::create_label_for_command; -use super::{SlashCommand, SlashCommandOutput}; use anyhow::{anyhow, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use feature_flags::FeatureFlag; use futures::StreamExt; use gpui::{AppContext, AsyncAppContext, Task, WeakView}; @@ -17,6 +18,8 @@ use ui::{BorrowAppContext, WindowContext}; use util::ResultExt; use workspace::Workspace; +use crate::slash_command::create_label_for_command; + pub struct AutoSlashCommandFeatureFlag; impl FeatureFlag for AutoSlashCommandFeatureFlag { @@ -92,7 +95,7 @@ impl SlashCommand for AutoCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(workspace) = workspace.upgrade() else { return Task::ready(Err(anyhow::anyhow!("workspace was dropped"))); }; diff --git a/crates/assistant/src/slash_command/cargo_workspace_command.rs b/crates/assistant/src/slash_command/cargo_workspace_command.rs index baf16d7f01..04fa408717 100644 --- a/crates/assistant/src/slash_command/cargo_workspace_command.rs +++ b/crates/assistant/src/slash_command/cargo_workspace_command.rs @@ -1,6 +1,8 @@ -use super::{SlashCommand, SlashCommandOutput}; use anyhow::{anyhow, Context, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use fs::Fs; use gpui::{AppContext, Model, Task, WeakView}; use language::{BufferSnapshot, LspAdapterDelegate}; @@ -123,7 +125,7 @@ impl SlashCommand for CargoWorkspaceSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let output = workspace.update(cx, |workspace, cx| { let project = workspace.project().clone(); let fs = workspace.project().read(cx).fs().clone(); diff --git a/crates/assistant/src/slash_command/context_server_command.rs b/crates/assistant/src/slash_command/context_server_command.rs index 9e6c4b7718..b749f9e4cd 100644 --- a/crates/assistant/src/slash_command/context_server_command.rs +++ b/crates/assistant/src/slash_command/context_server_command.rs @@ -1,8 +1,7 @@ -use super::create_label_for_command; use anyhow::{anyhow, Result}; use assistant_slash_command::{ AfterCompletion, ArgumentCompletion, SlashCommand, SlashCommandOutput, - SlashCommandOutputSection, + SlashCommandOutputSection, SlashCommandResult, }; use collections::HashMap; use context_servers::{ @@ -17,6 +16,8 @@ use text::LineEnding; use ui::{IconName, SharedString}; use workspace::Workspace; +use crate::slash_command::create_label_for_command; + pub struct ContextServerSlashCommand { server_id: String, prompt: Prompt, @@ -128,7 +129,7 @@ impl SlashCommand for ContextServerSlashCommand { _workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let server_id = self.server_id.clone(); let prompt_name = self.prompt.name.clone(); diff --git a/crates/assistant/src/slash_command/default_command.rs b/crates/assistant/src/slash_command/default_command.rs index 4199840300..2c956f8ca6 100644 --- a/crates/assistant/src/slash_command/default_command.rs +++ b/crates/assistant/src/slash_command/default_command.rs @@ -1,7 +1,9 @@ -use super::{SlashCommand, SlashCommandOutput}; use crate::prompt_library::PromptStore; use anyhow::{anyhow, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use gpui::{Task, WeakView}; use language::{BufferSnapshot, LspAdapterDelegate}; use std::{ @@ -48,7 +50,7 @@ impl SlashCommand for DefaultSlashCommand { _workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let store = PromptStore::global(cx); cx.background_executor().spawn(async move { let store = store.await?; diff --git a/crates/assistant/src/slash_command/delta_command.rs b/crates/assistant/src/slash_command/delta_command.rs index 6f697ecbb9..a17c5d739c 100644 --- a/crates/assistant/src/slash_command/delta_command.rs +++ b/crates/assistant/src/slash_command/delta_command.rs @@ -2,6 +2,7 @@ use crate::slash_command::file_command::{FileCommandMetadata, FileSlashCommand}; use anyhow::Result; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use collections::HashSet; use futures::future; @@ -48,7 +49,7 @@ impl SlashCommand for DeltaSlashCommand { workspace: WeakView, delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let mut paths = HashSet::default(); let mut file_command_old_outputs = Vec::new(); let mut file_command_new_outputs = Vec::new(); diff --git a/crates/assistant/src/slash_command/diagnostics_command.rs b/crates/assistant/src/slash_command/diagnostics_command.rs index 146a4e5d36..54be2219ff 100644 --- a/crates/assistant/src/slash_command/diagnostics_command.rs +++ b/crates/assistant/src/slash_command/diagnostics_command.rs @@ -1,6 +1,8 @@ -use super::{create_label_for_command, SlashCommand, SlashCommandOutput}; use anyhow::{anyhow, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use fuzzy::{PathMatch, StringMatchCandidate}; use gpui::{AppContext, Model, Task, View, WeakView}; use language::{ @@ -19,6 +21,8 @@ use util::paths::PathMatcher; use util::ResultExt; use workspace::Workspace; +use crate::slash_command::create_label_for_command; + pub(crate) struct DiagnosticsSlashCommand; impl DiagnosticsSlashCommand { @@ -167,7 +171,7 @@ impl SlashCommand for DiagnosticsSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(workspace) = workspace.upgrade() else { return Task::ready(Err(anyhow!("workspace was dropped"))); }; diff --git a/crates/assistant/src/slash_command/docs_command.rs b/crates/assistant/src/slash_command/docs_command.rs index 399ede9d99..92c3cd1977 100644 --- a/crates/assistant/src/slash_command/docs_command.rs +++ b/crates/assistant/src/slash_command/docs_command.rs @@ -6,6 +6,7 @@ use std::time::Duration; use anyhow::{anyhow, bail, Result}; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use gpui::{AppContext, BackgroundExecutor, Model, Task, WeakView}; use indexed_docs::{ @@ -274,7 +275,7 @@ impl SlashCommand for DocsSlashCommand { _workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { if arguments.is_empty() { return Task::ready(Err(anyhow!("missing an argument"))); }; diff --git a/crates/assistant/src/slash_command/fetch_command.rs b/crates/assistant/src/slash_command/fetch_command.rs index 3a01bb645a..9b61c547db 100644 --- a/crates/assistant/src/slash_command/fetch_command.rs +++ b/crates/assistant/src/slash_command/fetch_command.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use anyhow::{anyhow, bail, Context, Result}; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use futures::AsyncReadExt; use gpui::{Task, WeakView}; @@ -133,7 +134,7 @@ impl SlashCommand for FetchSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(argument) = arguments.first() else { return Task::ready(Err(anyhow!("missing URL"))); }; diff --git a/crates/assistant/src/slash_command/file_command.rs b/crates/assistant/src/slash_command/file_command.rs index 6da56d0641..51d0b33ba2 100644 --- a/crates/assistant/src/slash_command/file_command.rs +++ b/crates/assistant/src/slash_command/file_command.rs @@ -1,6 +1,8 @@ -use super::{diagnostics_command::collect_buffer_diagnostics, SlashCommand, SlashCommandOutput}; use anyhow::{anyhow, Context as _, Result}; -use assistant_slash_command::{AfterCompletion, ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + AfterCompletion, ArgumentCompletion, SlashCommand, SlashCommandOutput, + SlashCommandOutputSection, SlashCommandResult, +}; use fuzzy::PathMatch; use gpui::{AppContext, Model, Task, View, WeakView}; use language::{BufferSnapshot, CodeLabel, HighlightId, LineEnding, LspAdapterDelegate}; @@ -16,6 +18,8 @@ use ui::prelude::*; use util::ResultExt; use workspace::Workspace; +use crate::slash_command::diagnostics_command::collect_buffer_diagnostics; + pub(crate) struct FileSlashCommand; impl FileSlashCommand { @@ -181,7 +185,7 @@ impl SlashCommand for FileSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(workspace) = workspace.upgrade() else { return Task::ready(Err(anyhow!("workspace was dropped"))); }; @@ -198,7 +202,7 @@ fn collect_files( project: Model, glob_inputs: &[String], cx: &mut AppContext, -) -> Task> { +) -> Task { let Ok(matchers) = glob_inputs .into_iter() .map(|glob_input| { diff --git a/crates/assistant/src/slash_command/now_command.rs b/crates/assistant/src/slash_command/now_command.rs index 221ba05caf..40bc29f27d 100644 --- a/crates/assistant/src/slash_command/now_command.rs +++ b/crates/assistant/src/slash_command/now_command.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use anyhow::Result; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use chrono::Local; use gpui::{Task, WeakView}; @@ -48,7 +49,7 @@ impl SlashCommand for NowSlashCommand { _workspace: WeakView, _delegate: Option>, _cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let now = Local::now(); let text = format!("Today is {now}.", now = now.to_rfc2822()); let range = 0..text.len(); diff --git a/crates/assistant/src/slash_command/project_command.rs b/crates/assistant/src/slash_command/project_command.rs index 58fef8f338..e55699b026 100644 --- a/crates/assistant/src/slash_command/project_command.rs +++ b/crates/assistant/src/slash_command/project_command.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::PromptBuilder; use anyhow::{anyhow, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection, SlashCommandResult}; use feature_flags::FeatureFlag; use gpui::{AppContext, Task, WeakView, WindowContext}; use language::{Anchor, CodeLabel, LspAdapterDelegate}; @@ -76,7 +76,7 @@ impl SlashCommand for ProjectSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let model_registry = LanguageModelRegistry::read_global(cx); let current_model = model_registry.active_model(); let prompt_builder = self.prompt_builder.clone(); diff --git a/crates/assistant/src/slash_command/prompt_command.rs b/crates/assistant/src/slash_command/prompt_command.rs index 978c6d7504..dc80329382 100644 --- a/crates/assistant/src/slash_command/prompt_command.rs +++ b/crates/assistant/src/slash_command/prompt_command.rs @@ -1,7 +1,9 @@ -use super::{SlashCommand, SlashCommandOutput}; use crate::prompt_library::PromptStore; use anyhow::{anyhow, Context, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use gpui::{Task, WeakView}; use language::{BufferSnapshot, LspAdapterDelegate}; use std::sync::{atomic::AtomicBool, Arc}; @@ -61,7 +63,7 @@ impl SlashCommand for PromptSlashCommand { _workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let title = arguments.to_owned().join(" "); if title.trim().is_empty() { return Task::ready(Err(anyhow!("missing prompt name"))); diff --git a/crates/assistant/src/slash_command/search_command.rs b/crates/assistant/src/slash_command/search_command.rs index c7183e95bb..999fe252be 100644 --- a/crates/assistant/src/slash_command/search_command.rs +++ b/crates/assistant/src/slash_command/search_command.rs @@ -1,10 +1,8 @@ -use super::{ - create_label_for_command, - file_command::{build_entry_output_section, codeblock_fence_for_path}, - SlashCommand, SlashCommandOutput, -}; use anyhow::Result; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use feature_flags::FeatureFlag; use gpui::{AppContext, Task, WeakView}; use language::{CodeLabel, LspAdapterDelegate}; @@ -16,6 +14,9 @@ use std::{ use ui::{prelude::*, IconName}; use workspace::Workspace; +use crate::slash_command::create_label_for_command; +use crate::slash_command::file_command::{build_entry_output_section, codeblock_fence_for_path}; + pub(crate) struct SearchSlashCommandFeatureFlag; impl FeatureFlag for SearchSlashCommandFeatureFlag { @@ -63,7 +64,7 @@ impl SlashCommand for SearchSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(workspace) = workspace.upgrade() else { return Task::ready(Err(anyhow::anyhow!("workspace was dropped"))); }; diff --git a/crates/assistant/src/slash_command/symbols_command.rs b/crates/assistant/src/slash_command/symbols_command.rs index 887b57ba99..d28b53c1a1 100644 --- a/crates/assistant/src/slash_command/symbols_command.rs +++ b/crates/assistant/src/slash_command/symbols_command.rs @@ -1,6 +1,8 @@ -use super::{SlashCommand, SlashCommandOutput}; use anyhow::{anyhow, Context as _, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use editor::Editor; use gpui::{Task, WeakView}; use language::{BufferSnapshot, LspAdapterDelegate}; @@ -46,7 +48,7 @@ impl SlashCommand for OutlineSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let output = workspace.update(cx, |workspace, cx| { let Some(active_item) = workspace.active_item(cx) else { return Task::ready(Err(anyhow!("no active tab"))); diff --git a/crates/assistant/src/slash_command/tab_command.rs b/crates/assistant/src/slash_command/tab_command.rs index 0bff4730d8..23c3b64b38 100644 --- a/crates/assistant/src/slash_command/tab_command.rs +++ b/crates/assistant/src/slash_command/tab_command.rs @@ -1,6 +1,8 @@ -use super::{file_command::append_buffer_to_output, SlashCommand, SlashCommandOutput}; use anyhow::{Context, Result}; -use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection}; +use assistant_slash_command::{ + ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, +}; use collections::{HashMap, HashSet}; use editor::Editor; use futures::future::join_all; @@ -14,6 +16,8 @@ use ui::{ActiveTheme, WindowContext}; use util::ResultExt; use workspace::Workspace; +use crate::slash_command::file_command::append_buffer_to_output; + pub(crate) struct TabSlashCommand; const ALL_TABS_COMPLETION_ITEM: &str = "all"; @@ -132,7 +136,7 @@ impl SlashCommand for TabSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let tab_items_search = tab_items_for_queries( Some(workspace), arguments, diff --git a/crates/assistant/src/slash_command/terminal_command.rs b/crates/assistant/src/slash_command/terminal_command.rs index 1d4959fb19..7516b275ac 100644 --- a/crates/assistant/src/slash_command/terminal_command.rs +++ b/crates/assistant/src/slash_command/terminal_command.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use anyhow::Result; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use gpui::{AppContext, Task, View, WeakView}; use language::{BufferSnapshot, CodeLabel, LspAdapterDelegate}; @@ -62,7 +63,7 @@ impl SlashCommand for TerminalSlashCommand { workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let Some(workspace) = workspace.upgrade() else { return Task::ready(Err(anyhow::anyhow!("workspace was dropped"))); }; diff --git a/crates/assistant/src/slash_command/workflow_command.rs b/crates/assistant/src/slash_command/workflow_command.rs index 50c0e6cbc6..1379eb5e80 100644 --- a/crates/assistant/src/slash_command/workflow_command.rs +++ b/crates/assistant/src/slash_command/workflow_command.rs @@ -1,18 +1,18 @@ -use crate::prompts::PromptBuilder; -use std::sync::Arc; - use std::sync::atomic::AtomicBool; +use std::sync::Arc; use anyhow::Result; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use gpui::{Task, WeakView}; use language::{BufferSnapshot, LspAdapterDelegate}; use ui::prelude::*; - use workspace::Workspace; +use crate::prompts::PromptBuilder; + pub(crate) struct WorkflowSlashCommand { prompt_builder: Arc, } @@ -60,7 +60,7 @@ impl SlashCommand for WorkflowSlashCommand { _workspace: WeakView, _delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let prompt_builder = self.prompt_builder.clone(); cx.spawn(|_cx| async move { let text = prompt_builder.generate_workflow_prompt()?; diff --git a/crates/assistant_slash_command/src/assistant_slash_command.rs b/crates/assistant_slash_command/src/assistant_slash_command.rs index 36e229d49a..90e47690a8 100644 --- a/crates/assistant_slash_command/src/assistant_slash_command.rs +++ b/crates/assistant_slash_command/src/assistant_slash_command.rs @@ -56,6 +56,8 @@ pub struct ArgumentCompletion { pub replace_previous_arguments: bool, } +pub type SlashCommandResult = Result; + pub trait SlashCommand: 'static + Send + Sync { fn name(&self) -> String; fn label(&self, _cx: &AppContext) -> CodeLabel { @@ -87,7 +89,7 @@ pub trait SlashCommand: 'static + Send + Sync { // perhaps another kind of delegate is needed here. delegate: Option>, cx: &mut WindowContext, - ) -> Task>; + ) -> Task; } pub type RenderFoldPlaceholder = Arc< diff --git a/crates/extension/src/extension_slash_command.rs b/crates/extension/src/extension_slash_command.rs index 3dfbc4c03d..e9725f1ae4 100644 --- a/crates/extension/src/extension_slash_command.rs +++ b/crates/extension/src/extension_slash_command.rs @@ -3,6 +3,7 @@ use std::sync::{atomic::AtomicBool, Arc}; use anyhow::{anyhow, Result}; use assistant_slash_command::{ ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection, + SlashCommandResult, }; use futures::FutureExt; use gpui::{Task, WeakView, WindowContext}; @@ -87,7 +88,7 @@ impl SlashCommand for ExtensionSlashCommand { _workspace: WeakView, delegate: Option>, cx: &mut WindowContext, - ) -> Task> { + ) -> Task { let arguments = arguments.to_owned(); let output = cx.background_executor().spawn(async move { self.extension