Compare commits

...

2 Commits

Author SHA1 Message Date
Conrad Irwin
2275565438 TEMP 2024-10-29 20:00:54 -06:00
Conrad Irwin
e17150b34f remove workspace from slash commands 2024-10-29 16:53:03 -06:00
23 changed files with 91 additions and 166 deletions

2
Cargo.lock generated
View File

@@ -466,7 +466,7 @@ dependencies = [
"pretty_assertions",
"serde",
"serde_json",
"workspace",
"ui",
]
[[package]]

View File

@@ -1583,7 +1583,6 @@ impl ContextEditor {
&command.arguments,
false,
false,
self.workspace.clone(),
cx,
);
}
@@ -1727,7 +1726,6 @@ impl ContextEditor {
let selections = self.editor.read(cx).selections.disjoint_anchors();
let mut commands_by_range = HashMap::default();
let workspace = self.workspace.clone();
self.context.update(cx, |context, cx| {
context.reparse(cx);
for selection in selections.iter() {
@@ -1751,7 +1749,6 @@ impl ContextEditor {
&command.arguments,
true,
false,
workspace.clone(),
cx,
);
}
@@ -1767,7 +1764,6 @@ impl ContextEditor {
arguments: &[String],
ensure_trailing_newline: bool,
expand_result: bool,
workspace: WeakView<Workspace>,
cx: &mut ViewContext<Self>,
) {
if let Some(command) = SlashCommandRegistry::global(cx).command(name) {
@@ -1783,7 +1779,6 @@ impl ContextEditor {
arguments,
&sections,
snapshot,
workspace,
self.lsp_adapter_delegate.clone(),
cx,
);
@@ -1943,7 +1938,6 @@ impl ContextEditor {
let crease_ids = editor.insert_creases(
updated.iter().map(|command| {
let workspace = self.workspace.clone();
let confirm_command = Arc::new({
let context_editor = context_editor.clone();
let command = command.clone();
@@ -1956,7 +1950,6 @@ impl ContextEditor {
&command.arguments,
false,
false,
workspace.clone(),
cx,
);
})
@@ -2074,7 +2067,6 @@ impl ContextEditor {
&command.arguments,
false,
false,
self.workspace.clone(),
cx,
);
}

View File

@@ -112,7 +112,6 @@ impl SlashCommandCompletionProvider {
let command_name = mat.string.clone();
let command_range = command_range.clone();
let editor = editor.clone();
let workspace = workspace.clone();
Arc::new(
move |intent: CompletionIntent, cx: &mut WindowContext| {
if !requires_argument
@@ -126,7 +125,6 @@ impl SlashCommandCompletionProvider {
&[],
true,
false,
workspace.clone(),
cx,
);
})
@@ -168,61 +166,48 @@ impl SlashCommandCompletionProvider {
*flag = new_cancel_flag.clone();
let commands = SlashCommandRegistry::global(cx);
if let Some(command) = commands.command(command_name) {
let completions = command.complete_argument(
arguments,
new_cancel_flag.clone(),
self.workspace.clone(),
cx,
);
let completions = command.complete_argument(arguments, new_cancel_flag.clone(), cx);
let command_name: Arc<str> = command_name.into();
let editor = self.editor.clone();
let workspace = self.workspace.clone();
let arguments = arguments.to_vec();
cx.background_executor().spawn(async move {
Ok(completions
.await?
.into_iter()
.map(|new_argument| {
let confirm =
editor
.clone()
.zip(workspace.clone())
.map(|(editor, workspace)| {
Arc::new({
let mut completed_arguments = arguments.clone();
if new_argument.replace_previous_arguments {
completed_arguments.clear();
} else {
completed_arguments.pop();
}
completed_arguments.push(new_argument.new_text.clone());
let confirm = editor.clone().map(|editor| {
Arc::new({
let mut completed_arguments = arguments.clone();
if new_argument.replace_previous_arguments {
completed_arguments.clear();
} else {
completed_arguments.pop();
}
completed_arguments.push(new_argument.new_text.clone());
let command_range = command_range.clone();
let command_name = command_name.clone();
move |intent: CompletionIntent, cx: &mut WindowContext| {
if new_argument.after_completion.run()
|| intent.is_complete()
{
editor
.update(cx, |editor, cx| {
editor.run_command(
command_range.clone(),
&command_name,
&completed_arguments,
true,
false,
workspace.clone(),
cx,
);
})
.ok();
false
} else {
!new_argument.after_completion.run()
}
}
}) as Arc<_>
});
let command_range = command_range.clone();
let command_name = command_name.clone();
move |intent: CompletionIntent, cx: &mut WindowContext| {
if new_argument.after_completion.run() || intent.is_complete() {
editor
.update(cx, |editor, cx| {
editor.run_command(
command_range.clone(),
&command_name,
&completed_arguments,
true,
false,
cx,
);
})
.ok();
false
} else {
!new_argument.after_completion.run()
}
}
}) as Arc<_>
});
let mut new_text = new_argument.new_text.clone();
if new_argument.after_completion == AfterCompletion::Continue {

View File

@@ -5,7 +5,7 @@ use assistant_slash_command::{
};
use feature_flags::FeatureFlag;
use futures::StreamExt;
use gpui::{AppContext, AsyncAppContext, Task, WeakView};
use gpui::{AppContext, AsyncAppContext, Task};
use language::{CodeLabel, LspAdapterDelegate};
use language_model::{
LanguageModelCompletionEvent, LanguageModelRegistry, LanguageModelRequest,
@@ -49,7 +49,6 @@ impl SlashCommand for AutoCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
// There's no autocomplete for a prompt, since it's arbitrary text.
@@ -57,7 +56,7 @@ impl SlashCommand for AutoCommand {
// That way, it can hopefully be done resummarizing by the time we've actually
// typed out our prompt. This re-runs on every keystroke during autocomplete,
// but in the future, we could instead do it only once, when /auto is first entered.
let Some(workspace) = workspace.and_then(|ws| ws.upgrade()) else {
let Some(workspace) = Workspace::in_window(cx) else {
log::warn!("workspace was dropped or unavailable during /auto autocomplete");
return Task::ready(Ok(Vec::new()));
@@ -92,11 +91,10 @@ impl SlashCommand for AutoCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: language::BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow::anyhow!("workspace was dropped")));
};
if arguments.is_empty() {

View File

@@ -4,7 +4,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use fs::Fs;
use gpui::{AppContext, Model, Task, WeakView};
use gpui::{AppContext, Model, Task};
use language::{BufferSnapshot, LspAdapterDelegate};
use project::{Project, ProjectPath};
use std::{
@@ -107,7 +107,6 @@ impl SlashCommand for CargoWorkspaceSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Err(anyhow!("this command does not require argument")))
@@ -122,11 +121,13 @@ impl SlashCommand for CargoWorkspaceSlashCommand {
_arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let output = workspace.update(cx, |workspace, cx| {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};
workspace.update(cx, |workspace, cx| {
let project = workspace.project().clone();
let fs = workspace.project().read(cx).fs().clone();
let path = Self::path_to_cargo_toml(project, cx);
@@ -150,7 +151,6 @@ impl SlashCommand for CargoWorkspaceSlashCommand {
}
.to_event_stream())
})
});
output.unwrap_or_else(|error| Task::ready(Err(error)))
})
}
}

View File

@@ -8,13 +8,12 @@ use context_servers::{
manager::{ContextServer, ContextServerManager},
types::Prompt,
};
use gpui::{AppContext, Task, WeakView, WindowContext};
use gpui::{AppContext, Task, WindowContext};
use language::{BufferSnapshot, CodeLabel, LspAdapterDelegate};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use text::LineEnding;
use ui::{IconName, SharedString};
use workspace::Workspace;
use crate::slash_command::create_label_for_command;
@@ -71,7 +70,6 @@ impl SlashCommand for ContextServerSlashCommand {
self: Arc<Self>,
arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let server_id = self.server_id.clone();
@@ -126,7 +124,6 @@ impl SlashCommand for ContextServerSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -4,14 +4,13 @@ use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
SlashCommandResult,
};
use gpui::{Task, WeakView};
use gpui::Task;
use language::{BufferSnapshot, LspAdapterDelegate};
use std::{
fmt::Write,
sync::{atomic::AtomicBool, Arc},
};
use ui::prelude::*;
use workspace::Workspace;
pub(crate) struct DefaultSlashCommand;
@@ -36,7 +35,6 @@ impl SlashCommand for DefaultSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancellation_flag: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Err(anyhow!("this command does not require argument")))
@@ -47,7 +45,6 @@ impl SlashCommand for DefaultSlashCommand {
_arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -6,11 +6,10 @@ use assistant_slash_command::{
};
use collections::HashSet;
use futures::future;
use gpui::{Task, WeakView, WindowContext};
use gpui::{Task, WindowContext};
use language::{BufferSnapshot, LspAdapterDelegate};
use std::sync::{atomic::AtomicBool, Arc};
use text::OffsetRangeExt;
use workspace::Workspace;
pub(crate) struct DeltaSlashCommand;
@@ -35,7 +34,6 @@ impl SlashCommand for DeltaSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancellation_flag: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Err(anyhow!("this command does not require argument")))
@@ -46,7 +44,6 @@ impl SlashCommand for DeltaSlashCommand {
_arguments: &[String],
context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
@@ -69,7 +66,6 @@ impl SlashCommand for DeltaSlashCommand {
&[metadata.path.clone()],
context_slash_command_output_sections,
context_buffer.clone(),
workspace.clone(),
delegate.clone(),
cx,
));

View File

@@ -4,7 +4,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use fuzzy::{PathMatch, StringMatchCandidate};
use gpui::{AppContext, Model, Task, View, WeakView};
use gpui::{AppContext, Model, Task, View};
use language::{
Anchor, BufferSnapshot, DiagnosticEntry, DiagnosticSeverity, LspAdapterDelegate,
OffsetRangeExt, ToOffset,
@@ -114,10 +114,9 @@ impl SlashCommand for DiagnosticsSlashCommand {
self: Arc<Self>,
arguments: &[String],
cancellation_flag: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let Some(workspace) = workspace.and_then(|workspace| workspace.upgrade()) else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};
let query = arguments.last().cloned().unwrap_or_default();
@@ -168,11 +167,10 @@ impl SlashCommand for DiagnosticsSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};

View File

@@ -8,7 +8,7 @@ use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
SlashCommandResult,
};
use gpui::{AppContext, BackgroundExecutor, Model, Task, WeakView};
use gpui::{AppContext, BackgroundExecutor, Model, Task};
use indexed_docs::{
DocsDotRsProvider, IndexedDocsRegistry, IndexedDocsStore, LocalRustdocProvider, PackageName,
ProviderId,
@@ -41,21 +41,14 @@ impl DocsSlashCommand {
///
/// Ideally we would do this sooner, but we need to wait until we're able to
/// access the workspace so we can read the project.
fn ensure_rust_doc_providers_are_registered(
&self,
workspace: Option<WeakView<Workspace>>,
cx: &mut AppContext,
) {
fn ensure_rust_doc_providers_are_registered(&self, cx: &mut WindowContext) {
let indexed_docs_registry = IndexedDocsRegistry::global(cx);
if indexed_docs_registry
.get_provider_store(LocalRustdocProvider::id())
.is_none()
{
let index_provider_deps = maybe!({
let workspace = workspace.clone().ok_or_else(|| anyhow!("no workspace"))?;
let workspace = workspace
.upgrade()
.ok_or_else(|| anyhow!("workspace was dropped"))?;
let workspace = Workspace::in_window(cx).ok_or_else(|| anyhow!("no workspace"))?;
let project = workspace.read(cx).project().clone();
let fs = project.read(cx).fs().clone();
let cargo_workspace_root = Self::path_to_cargo_toml(project, cx)
@@ -78,10 +71,7 @@ impl DocsSlashCommand {
.is_none()
{
let http_client = maybe!({
let workspace = workspace.ok_or_else(|| anyhow!("no workspace"))?;
let workspace = workspace
.upgrade()
.ok_or_else(|| anyhow!("workspace was dropped"))?;
let workspace = Workspace::in_window(cx).ok_or_else(|| anyhow!("no workspace"))?;
let project = workspace.read(cx).project().clone();
anyhow::Ok(project.read(cx).client().http_client().clone())
});
@@ -164,10 +154,9 @@ impl SlashCommand for DocsSlashCommand {
self: Arc<Self>,
arguments: &[String],
_cancel: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
self.ensure_rust_doc_providers_are_registered(workspace, cx);
self.ensure_rust_doc_providers_are_registered(cx);
let indexed_docs_registry = IndexedDocsRegistry::global(cx);
let args = DocsSlashCommandArgs::parse(arguments);
@@ -272,7 +261,6 @@ impl SlashCommand for DocsSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -9,7 +9,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use futures::AsyncReadExt;
use gpui::{Task, WeakView};
use gpui::Task;
use html_to_markdown::{convert_html_to_markdown, markdown, TagHandler};
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
use language::{BufferSnapshot, LspAdapterDelegate};
@@ -120,7 +120,6 @@ impl SlashCommand for FetchSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Ok(Vec::new()))
@@ -131,14 +130,13 @@ impl SlashCommand for FetchSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(argument) = arguments.first() else {
return Task::ready(Err(anyhow!("missing URL")));
};
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};

View File

@@ -6,7 +6,7 @@ use assistant_slash_command::{
use futures::channel::mpsc;
use futures::Stream;
use fuzzy::PathMatch;
use gpui::{AppContext, Model, Task, View, WeakView};
use gpui::{AppContext, Model, Task, View};
use language::{BufferSnapshot, CodeLabel, HighlightId, LineEnding, LspAdapterDelegate};
use project::{PathMatchCandidateSet, Project};
use serde::{Deserialize, Serialize};
@@ -132,10 +132,9 @@ impl SlashCommand for FileSlashCommand {
self: Arc<Self>,
arguments: &[String],
cancellation_flag: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let Some(workspace) = workspace.and_then(|workspace| workspace.upgrade()) else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};
@@ -185,11 +184,10 @@ impl SlashCommand for FileSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow!("workspace was dropped")));
};

View File

@@ -7,10 +7,9 @@ use assistant_slash_command::{
SlashCommandResult,
};
use chrono::Local;
use gpui::{Task, WeakView};
use gpui::Task;
use language::{BufferSnapshot, LspAdapterDelegate};
use ui::prelude::*;
use workspace::Workspace;
pub(crate) struct NowSlashCommand;
@@ -35,7 +34,6 @@ impl SlashCommand for NowSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Ok(Vec::new()))
@@ -46,7 +44,6 @@ impl SlashCommand for NowSlashCommand {
_arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
_cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -6,7 +6,7 @@ use crate::PromptBuilder;
use anyhow::{anyhow, Result};
use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection, SlashCommandResult};
use feature_flags::FeatureFlag;
use gpui::{AppContext, Task, WeakView, WindowContext};
use gpui::{AppContext, Task, WindowContext};
use language::{Anchor, CodeLabel, LspAdapterDelegate};
use language_model::{LanguageModelRegistry, LanguageModelTool};
use schemars::JsonSchema;
@@ -62,7 +62,6 @@ impl SlashCommand for ProjectSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Ok(Vec::new()))
@@ -73,7 +72,6 @@ impl SlashCommand for ProjectSlashCommand {
_arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<Anchor>],
context_buffer: language::BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
@@ -81,7 +79,7 @@ impl SlashCommand for ProjectSlashCommand {
let current_model = model_registry.active_model();
let prompt_builder = self.prompt_builder.clone();
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow::anyhow!("workspace was dropped")));
};
let project = workspace.read(cx).project().clone();

View File

@@ -4,11 +4,10 @@ use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
SlashCommandResult,
};
use gpui::{Task, WeakView};
use gpui::Task;
use language::{BufferSnapshot, LspAdapterDelegate};
use std::sync::{atomic::AtomicBool, Arc};
use ui::prelude::*;
use workspace::Workspace;
pub(crate) struct PromptSlashCommand;
@@ -33,7 +32,6 @@ impl SlashCommand for PromptSlashCommand {
self: Arc<Self>,
arguments: &[String],
_cancellation_flag: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let store = PromptStore::global(cx);
@@ -60,7 +58,6 @@ impl SlashCommand for PromptSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -4,7 +4,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use feature_flags::FeatureFlag;
use gpui::{AppContext, Task, WeakView};
use gpui::{AppContext, Task};
use language::{CodeLabel, LspAdapterDelegate};
use semantic_index::{LoadedSearchResult, SemanticDb};
use std::{
@@ -50,7 +50,6 @@ impl SlashCommand for SearchSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Ok(Vec::new()))
@@ -61,11 +60,10 @@ impl SlashCommand for SearchSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: language::BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow::anyhow!("workspace was dropped")));
};
if arguments.is_empty() {

View File

@@ -4,7 +4,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use editor::Editor;
use gpui::{Task, WeakView};
use gpui::Task;
use language::{BufferSnapshot, LspAdapterDelegate};
use std::sync::Arc;
use std::{path::Path, sync::atomic::AtomicBool};
@@ -30,7 +30,6 @@ impl SlashCommand for OutlineSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Err(anyhow!("this command does not require argument")))
@@ -45,10 +44,12 @@ impl SlashCommand for OutlineSlashCommand {
_arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
return Task::ready(Err(anyhow!("no workspace")));
};
let output = workspace.update(cx, |workspace, cx| {
let Some(active_item) = workspace.active_item(cx) else {
return Task::ready(Err(anyhow!("no active tab")));

View File

@@ -6,7 +6,7 @@ use assistant_slash_command::{
use collections::{HashMap, HashSet};
use editor::Editor;
use futures::future::join_all;
use gpui::{Entity, Task, WeakView};
use gpui::{Entity, Task};
use language::{BufferSnapshot, CodeLabel, HighlightId, LspAdapterDelegate};
use std::{
path::PathBuf,
@@ -47,7 +47,6 @@ impl SlashCommand for TabSlashCommand {
self: Arc<Self>,
arguments: &[String],
cancel: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let mut has_all_tabs_completion_item = false;
@@ -67,18 +66,14 @@ impl SlashCommand for TabSlashCommand {
return Task::ready(Ok(Vec::new()));
}
let active_item_path = workspace.as_ref().and_then(|workspace| {
workspace
.update(cx, |workspace, cx| {
let snapshot = active_item_buffer(workspace, cx).ok()?;
snapshot.resolve_file_path(cx, true)
})
.ok()
.flatten()
let active_item_path = Workspace::in_window(cx).and_then(|workspace| {
workspace.update(cx, |workspace, cx| {
let snapshot = active_item_buffer(workspace, cx).ok()?;
snapshot.resolve_file_path(cx, true)
})
});
let current_query = arguments.last().cloned().unwrap_or_default();
let tab_items_search =
tab_items_for_queries(workspace, &[current_query], cancel, false, cx);
let tab_items_search = tab_items_for_queries(&[current_query], cancel, false, cx);
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
cx.spawn(|_| async move {
@@ -133,17 +128,11 @@ impl SlashCommand for TabSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let tab_items_search = tab_items_for_queries(
Some(workspace),
arguments,
Arc::new(AtomicBool::new(false)),
true,
cx,
);
let tab_items_search =
tab_items_for_queries(arguments, Arc::new(AtomicBool::new(false)), true, cx);
cx.background_executor().spawn(async move {
let mut output = SlashCommandOutput::default();
@@ -156,7 +145,6 @@ impl SlashCommand for TabSlashCommand {
}
fn tab_items_for_queries(
workspace: Option<WeakView<Workspace>>,
queries: &[String],
cancel: Arc<AtomicBool>,
strict_match: bool,
@@ -164,6 +152,7 @@ fn tab_items_for_queries(
) -> Task<anyhow::Result<Vec<(Option<PathBuf>, BufferSnapshot, usize)>>> {
let empty_query = queries.is_empty() || queries.iter().all(|query| query.trim().is_empty());
let queries = queries.to_owned();
let workspace = Workspace::in_window(cx);
cx.spawn(|mut cx| async move {
let mut open_buffers =
workspace

View File

@@ -6,7 +6,7 @@ use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
SlashCommandResult,
};
use gpui::{AppContext, Task, View, WeakView};
use gpui::{AppContext, Task, View};
use language::{BufferSnapshot, CodeLabel, LspAdapterDelegate};
use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
use ui::prelude::*;
@@ -49,7 +49,6 @@ impl SlashCommand for TerminalSlashCommand {
self: Arc<Self>,
_arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Ok(Vec::new()))
@@ -60,11 +59,10 @@ impl SlashCommand for TerminalSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
_delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {
let Some(workspace) = workspace.upgrade() else {
let Some(workspace) = Workspace::in_window(cx) else {
return Task::ready(Err(anyhow::anyhow!("workspace was dropped")));
};

View File

@@ -21,9 +21,8 @@ language.workspace = true
parking_lot.workspace = true
serde.workspace = true
serde_json.workspace = true
workspace.workspace = true
ui.workspace = true
[dev-dependencies]
gpui = { workspace = true, features = ["test-support"] }
pretty_assertions.workspace = true
workspace = { workspace = true, features = ["test-support"] }

View File

@@ -3,7 +3,7 @@ mod slash_command_registry;
use anyhow::Result;
use futures::stream::{self, BoxStream};
use futures::StreamExt;
use gpui::{AnyElement, AppContext, ElementId, SharedString, Task, WeakView, WindowContext};
use gpui::{AnyElement, AppContext, ElementId, SharedString, Task, WindowContext};
use language::{BufferSnapshot, CodeLabel, LspAdapterDelegate, OffsetRangeExt};
use serde::{Deserialize, Serialize};
pub use slash_command_registry::*;
@@ -11,7 +11,7 @@ use std::{
ops::Range,
sync::{atomic::AtomicBool, Arc},
};
use workspace::{ui::IconName, Workspace};
use ui::IconName;
pub fn init(cx: &mut AppContext) {
SlashCommandRegistry::default_global(cx);
@@ -71,7 +71,6 @@ pub trait SlashCommand: 'static + Send + Sync {
self: Arc<Self>,
arguments: &[String],
cancel: Arc<AtomicBool>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>>;
fn requires_argument(&self) -> bool;
@@ -83,7 +82,6 @@ pub trait SlashCommand: 'static + Send + Sync {
arguments: &[String],
context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
context_buffer: BufferSnapshot,
workspace: WeakView<Workspace>,
// TODO: We're just using the `LspAdapterDelegate` here because that is
// what the extension API is already expecting.
//

View File

@@ -6,11 +6,10 @@ use assistant_slash_command::{
SlashCommandResult,
};
use futures::FutureExt;
use gpui::{Task, WeakView, WindowContext};
use gpui::{Task, WindowContext};
use language::{BufferSnapshot, LspAdapterDelegate};
use ui::prelude::*;
use wasmtime_wasi::WasiView;
use workspace::Workspace;
use crate::wasm_host::{WasmExtension, WasmHost};
@@ -42,7 +41,6 @@ impl SlashCommand for ExtensionSlashCommand {
self: Arc<Self>,
arguments: &[String],
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
let arguments = arguments.to_owned();
@@ -85,7 +83,6 @@ impl SlashCommand for ExtensionSlashCommand {
arguments: &[String],
_context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
_context_buffer: BufferSnapshot,
_workspace: WeakView<Workspace>,
delegate: Option<Arc<dyn LspAdapterDelegate>>,
cx: &mut WindowContext,
) -> Task<SlashCommandResult> {

View File

@@ -1230,6 +1230,12 @@ impl Workspace {
})
}
pub fn in_window(cx: &mut WindowContext) -> Option<View<Self>> {
cx.window_handle()
.downcast::<Self>()
.and_then(|w| w.root(cx).ok())
}
pub fn weak_handle(&self) -> WeakView<Self> {
self.weak_self.clone()
}