assistant: Don't require a worktree to run slash commands (#15655)

This PR fixes an issue where slash commands were not able to run when
Zed did not have any worktrees opened.

This requirement was only necessary for slash commands originating from
extensions, and we can enforce the presence of a worktree just for
those:

<img width="378" alt="Screenshot 2024-08-01 at 5 01 58 PM"
src="https://github.com/user-attachments/assets/38bea947-e33b-4c64-853c-c1f36c63d779">

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-08-01 17:14:13 -04:00 committed by GitHub
parent 55fc1f0afb
commit 88f29c8355
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 29 additions and 28 deletions

View File

@ -1596,18 +1596,16 @@ impl ContextEditor {
cx: &mut ViewContext<Self>,
) {
if let Some(command) = SlashCommandRegistry::global(cx).command(name) {
if let Some(lsp_adapter_delegate) = self.lsp_adapter_delegate.clone() {
let argument = argument.map(ToString::to_string);
let output = command.run(argument.as_deref(), workspace, lsp_adapter_delegate, cx);
self.context.update(cx, |context, cx| {
context.insert_command_output(
command_range,
output,
insert_trailing_newline,
cx,
)
});
}
let argument = argument.map(ToString::to_string);
let output = command.run(
argument.as_deref(),
workspace,
self.lsp_adapter_delegate.clone(),
cx,
);
self.context.update(cx, |context, cx| {
context.insert_command_output(command_range, output, insert_trailing_newline, cx)
});
}
}

View File

@ -3414,7 +3414,7 @@ mod tests {
self: Arc<Self>,
_argument: Option<&str>,
_workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
_cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
Task::ready(Ok(SlashCommandOutput {

View File

@ -46,7 +46,7 @@ impl SlashCommand for ActiveSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let output = workspace.update(cx, |workspace, cx| {

View File

@ -44,7 +44,7 @@ impl SlashCommand for DefaultSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
_workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let store = PromptStore::global(cx);

View File

@ -158,7 +158,7 @@ impl SlashCommand for DiagnosticsSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(workspace) = workspace.upgrade() else {

View File

@ -242,7 +242,7 @@ impl SlashCommand for DocsSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
_workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(argument) = argument else {

View File

@ -129,7 +129,7 @@ impl SlashCommand for FetchSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(argument) = argument else {

View File

@ -136,7 +136,7 @@ impl SlashCommand for FileSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(workspace) = workspace.upgrade() else {

View File

@ -44,7 +44,7 @@ impl SlashCommand for NowSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
_workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
_cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let now = Local::now();

View File

@ -119,7 +119,7 @@ impl SlashCommand for ProjectSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let output = workspace.update(cx, |workspace, cx| {

View File

@ -55,7 +55,7 @@ impl SlashCommand for PromptSlashCommand {
self: Arc<Self>,
title: Option<&str>,
_workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(title) = title else {

View File

@ -54,7 +54,7 @@ impl SlashCommand for SearchSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(workspace) = workspace.upgrade() else {

View File

@ -42,7 +42,7 @@ impl SlashCommand for OutlineSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let output = workspace.update(cx, |workspace, cx| {

View File

@ -46,7 +46,7 @@ impl SlashCommand for TabsSlashCommand {
self: Arc<Self>,
_argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let open_buffers = workspace.update(cx, |workspace, cx| {

View File

@ -58,7 +58,7 @@ impl SlashCommand for TermSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let Some(workspace) = workspace.upgrade() else {

View File

@ -49,7 +49,7 @@ pub trait SlashCommand: 'static + Send + Sync {
//
// It may be that `LspAdapterDelegate` needs a more general name, or
// perhaps another kind of delegate is needed here.
delegate: Arc<dyn LspAdapterDelegate>,
delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>>;
}

View File

@ -81,7 +81,7 @@ impl SlashCommand for ExtensionSlashCommand {
self: Arc<Self>,
argument: Option<&str>,
_workspace: WeakView<Workspace>,
delegate: Arc<dyn LspAdapterDelegate>,
delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let argument = argument.map(|arg| arg.to_string());
@ -91,6 +91,9 @@ impl SlashCommand for ExtensionSlashCommand {
let this = self.clone();
move |extension, store| {
async move {
let delegate = delegate.ok_or_else(|| {
anyhow!("no worktree for extension slash command")
})?;
let resource = store.data_mut().table().push(delegate)?;
let output = extension
.call_run_slash_command(