Move UI code from assistant_context_editor -> agent_ui (#33289)
This breaks a transitive dependency of `agent` on UI crates. I've also found and eliminated some dead code in assistant_context_editor. Release Notes: - N/A
This commit is contained in:
parent
786e724684
commit
4cd4d28531
31 changed files with 144 additions and 455 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -55,7 +55,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"agent_settings",
|
||||
"anyhow",
|
||||
"assistant_context_editor",
|
||||
"assistant_context",
|
||||
"assistant_tool",
|
||||
"assistant_tools",
|
||||
"chrono",
|
||||
|
@ -138,7 +138,7 @@ dependencies = [
|
|||
"agent",
|
||||
"agent_settings",
|
||||
"anyhow",
|
||||
"assistant_context_editor",
|
||||
"assistant_context",
|
||||
"assistant_slash_command",
|
||||
"assistant_slash_commands",
|
||||
"assistant_tool",
|
||||
|
@ -169,6 +169,7 @@ dependencies = [
|
|||
"jsonschema",
|
||||
"language",
|
||||
"language_model",
|
||||
"languages",
|
||||
"log",
|
||||
"lsp",
|
||||
"markdown",
|
||||
|
@ -203,7 +204,9 @@ dependencies = [
|
|||
"theme",
|
||||
"time",
|
||||
"time_format",
|
||||
"tree-sitter-md",
|
||||
"ui",
|
||||
"unindent",
|
||||
"urlencoding",
|
||||
"util",
|
||||
"uuid",
|
||||
|
@ -557,7 +560,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "assistant_context_editor"
|
||||
name = "assistant_context"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"agent_settings",
|
||||
|
@ -569,31 +572,23 @@ dependencies = [
|
|||
"clock",
|
||||
"collections",
|
||||
"context_server",
|
||||
"editor",
|
||||
"feature_flags",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
"fuzzy",
|
||||
"gpui",
|
||||
"indexed_docs",
|
||||
"indoc",
|
||||
"language",
|
||||
"language_model",
|
||||
"languages",
|
||||
"log",
|
||||
"multi_buffer",
|
||||
"open_ai",
|
||||
"ordered-float 2.10.1",
|
||||
"parking_lot",
|
||||
"paths",
|
||||
"picker",
|
||||
"pretty_assertions",
|
||||
"project",
|
||||
"prompt_store",
|
||||
"proto",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"rope",
|
||||
"rpc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -602,15 +597,12 @@ dependencies = [
|
|||
"smol",
|
||||
"telemetry_events",
|
||||
"text",
|
||||
"theme",
|
||||
"tree-sitter-md",
|
||||
"ui",
|
||||
"unindent",
|
||||
"util",
|
||||
"uuid",
|
||||
"workspace",
|
||||
"workspace-hack",
|
||||
"zed_actions",
|
||||
"zed_llm_client",
|
||||
]
|
||||
|
||||
|
@ -3031,7 +3023,7 @@ version = "0.44.0"
|
|||
dependencies = [
|
||||
"agent_settings",
|
||||
"anyhow",
|
||||
"assistant_context_editor",
|
||||
"assistant_context",
|
||||
"assistant_slash_command",
|
||||
"async-stripe",
|
||||
"async-trait",
|
||||
|
@ -19924,7 +19916,6 @@ dependencies = [
|
|||
"ashpd",
|
||||
"askpass",
|
||||
"assets",
|
||||
"assistant_context_editor",
|
||||
"assistant_tool",
|
||||
"assistant_tools",
|
||||
"audio",
|
||||
|
|
|
@ -8,7 +8,7 @@ members = [
|
|||
"crates/anthropic",
|
||||
"crates/askpass",
|
||||
"crates/assets",
|
||||
"crates/assistant_context_editor",
|
||||
"crates/assistant_context",
|
||||
"crates/assistant_slash_command",
|
||||
"crates/assistant_slash_commands",
|
||||
"crates/assistant_tool",
|
||||
|
@ -221,7 +221,7 @@ ai = { path = "crates/ai" }
|
|||
anthropic = { path = "crates/anthropic" }
|
||||
askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant_context_editor = { path = "crates/assistant_context_editor" }
|
||||
assistant_context = { path = "crates/assistant_context" }
|
||||
assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
|
||||
assistant_tool = { path = "crates/assistant_tool" }
|
||||
|
|
|
@ -21,7 +21,7 @@ test-support = [
|
|||
[dependencies]
|
||||
agent_settings.workspace = true
|
||||
anyhow.workspace = true
|
||||
assistant_context_editor.workspace = true
|
||||
assistant_context.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
chrono.workspace = true
|
||||
client.workspace = true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::thread::Thread;
|
||||
use assistant_context_editor::AssistantContext;
|
||||
use assistant_context::AssistantContext;
|
||||
use assistant_tool::outline;
|
||||
use collections::HashSet;
|
||||
use futures::future;
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
thread_store::ThreadStore,
|
||||
};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_context_editor::AssistantContext;
|
||||
use assistant_context::AssistantContext;
|
||||
use collections::{HashSet, IndexSet};
|
||||
use futures::{self, FutureExt};
|
||||
use gpui::{App, Context, Entity, EventEmitter, Image, SharedString, Task, WeakEntity};
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
thread_store::{SerializedThreadMetadata, ThreadStore},
|
||||
};
|
||||
use anyhow::{Context as _, Result};
|
||||
use assistant_context_editor::SavedContextMetadata;
|
||||
use assistant_context::SavedContextMetadata;
|
||||
use chrono::{DateTime, Utc};
|
||||
use gpui::{App, AsyncApp, Entity, SharedString, Task, prelude::*};
|
||||
use itertools::Itertools;
|
||||
|
@ -62,7 +62,7 @@ enum SerializedRecentOpen {
|
|||
|
||||
pub struct HistoryStore {
|
||||
thread_store: Entity<ThreadStore>,
|
||||
context_store: Entity<assistant_context_editor::ContextStore>,
|
||||
context_store: Entity<assistant_context::ContextStore>,
|
||||
recently_opened_entries: VecDeque<HistoryEntryId>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
_save_recently_opened_entries_task: Task<()>,
|
||||
|
@ -71,7 +71,7 @@ pub struct HistoryStore {
|
|||
impl HistoryStore {
|
||||
pub fn new(
|
||||
thread_store: Entity<ThreadStore>,
|
||||
context_store: Entity<assistant_context_editor::ContextStore>,
|
||||
context_store: Entity<assistant_context::ContextStore>,
|
||||
initial_recent_entries: impl IntoIterator<Item = HistoryEntryId>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
|
|
|
@ -96,7 +96,7 @@ impl SharedProjectContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub type TextThreadStore = assistant_context_editor::ContextStore;
|
||||
pub type TextThreadStore = assistant_context::ContextStore;
|
||||
|
||||
pub struct ThreadStore {
|
||||
project: Entity<Project>,
|
||||
|
|
|
@ -22,7 +22,7 @@ test-support = [
|
|||
agent.workspace = true
|
||||
agent_settings.workspace = true
|
||||
anyhow.workspace = true
|
||||
assistant_context_editor.workspace = true
|
||||
assistant_context.workspace = true
|
||||
assistant_slash_command.workspace = true
|
||||
assistant_slash_commands.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
|
@ -101,7 +101,10 @@ editor = { workspace = true, features = ["test-support"] }
|
|||
gpui = { workspace = true, "features" = ["test-support"] }
|
||||
indoc.workspace = true
|
||||
language = { workspace = true, "features" = ["test-support"] }
|
||||
languages = { workspace = true, features = ["test-support"] }
|
||||
language_model = { workspace = true, "features" = ["test-support"] }
|
||||
pretty_assertions.workspace = true
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
rand.workspace = true
|
||||
tree-sitter-md.workspace = true
|
||||
unindent.workspace = true
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::{
|
||||
ModelUsageContext,
|
||||
language_model_selector::{
|
||||
LanguageModelSelector, ToggleModelSelector, language_model_selector,
|
||||
},
|
||||
};
|
||||
use agent_settings::AgentSettings;
|
||||
use fs::Fs;
|
||||
use gpui::{Entity, FocusHandle, SharedString};
|
||||
use picker::popover_menu::PickerPopoverMenu;
|
||||
|
||||
use crate::ModelUsageContext;
|
||||
use assistant_context_editor::language_model_selector::{
|
||||
LanguageModelSelector, ToggleModelSelector, language_model_selector,
|
||||
};
|
||||
use language_model::{ConfiguredModel, LanguageModelRegistry};
|
||||
use picker::popover_menu::PickerPopoverMenu;
|
||||
use settings::update_settings_file;
|
||||
use std::sync::Arc;
|
||||
use ui::{PopoverMenuHandle, Tooltip, prelude::*};
|
||||
|
|
|
@ -7,17 +7,35 @@ use std::time::Duration;
|
|||
use db::kvp::{Dismissable, KEY_VALUE_STORE};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::language_model_selector::ToggleModelSelector;
|
||||
use crate::{
|
||||
AddContextServer, AgentDiffPane, ContinueThread, ContinueWithBurnMode,
|
||||
DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread,
|
||||
NewThread, OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ResetTrialEndUpsell,
|
||||
ResetTrialUpsell, ToggleBurnMode, ToggleContextPicker, ToggleNavigationMenu, ToggleOptionsMenu,
|
||||
active_thread::{self, ActiveThread, ActiveThreadEvent},
|
||||
agent_configuration::{AgentConfiguration, AssistantConfigurationEvent},
|
||||
agent_diff::AgentDiff,
|
||||
message_editor::{MessageEditor, MessageEditorEvent},
|
||||
slash_command::SlashCommandCompletionProvider,
|
||||
text_thread_editor::{
|
||||
AgentPanelDelegate, TextThreadEditor, humanize_token_count, make_lsp_adapter_delegate,
|
||||
render_remaining_tokens,
|
||||
},
|
||||
thread_history::{HistoryEntryElement, ThreadHistory},
|
||||
ui::AgentOnboardingModal,
|
||||
};
|
||||
use agent::{
|
||||
Thread, ThreadError, ThreadEvent, ThreadId, ThreadSummary, TokenUsageRatio,
|
||||
context_store::ContextStore,
|
||||
history_store::{HistoryEntryId, HistoryStore},
|
||||
thread_store::{TextThreadStore, ThreadStore},
|
||||
};
|
||||
use agent_settings::{AgentDockPosition, AgentSettings, CompletionMode, DefaultView};
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_context_editor::{
|
||||
AgentPanelDelegate, AssistantContext, ContextEditor, ContextEvent, ContextSummary,
|
||||
SlashCommandCompletionProvider, humanize_token_count, make_lsp_adapter_delegate,
|
||||
render_remaining_tokens,
|
||||
};
|
||||
use assistant_context::{AssistantContext, ContextEvent, ContextSummary};
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
|
||||
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
||||
use client::{UserStore, zed_urls};
|
||||
use editor::{Anchor, AnchorRangeExt as _, Editor, EditorEvent, MultiBuffer};
|
||||
use fs::Fs;
|
||||
|
@ -56,25 +74,6 @@ use zed_actions::{
|
|||
};
|
||||
use zed_llm_client::{CompletionIntent, UsageLimit};
|
||||
|
||||
use crate::{
|
||||
AddContextServer, AgentDiffPane, ContinueThread, ContinueWithBurnMode,
|
||||
DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread,
|
||||
NewThread, OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ResetTrialEndUpsell,
|
||||
ResetTrialUpsell, ToggleBurnMode, ToggleContextPicker, ToggleNavigationMenu, ToggleOptionsMenu,
|
||||
active_thread::{self, ActiveThread, ActiveThreadEvent},
|
||||
agent_configuration::{AgentConfiguration, AssistantConfigurationEvent},
|
||||
agent_diff::AgentDiff,
|
||||
message_editor::{MessageEditor, MessageEditorEvent},
|
||||
thread_history::{HistoryEntryElement, ThreadHistory},
|
||||
ui::AgentOnboardingModal,
|
||||
};
|
||||
use agent::{
|
||||
Thread, ThreadError, ThreadEvent, ThreadId, ThreadSummary, TokenUsageRatio,
|
||||
context_store::ContextStore,
|
||||
history_store::{HistoryEntryId, HistoryStore},
|
||||
thread_store::{TextThreadStore, ThreadStore},
|
||||
};
|
||||
|
||||
const AGENT_PANEL_KEY: &str = "agent_panel";
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -179,7 +178,7 @@ enum ActiveView {
|
|||
_subscriptions: Vec<gpui::Subscription>,
|
||||
},
|
||||
TextThread {
|
||||
context_editor: Entity<ContextEditor>,
|
||||
context_editor: Entity<TextThreadEditor>,
|
||||
title_editor: Entity<Editor>,
|
||||
buffer_search_bar: Entity<BufferSearchBar>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
|
@ -260,7 +259,7 @@ impl ActiveView {
|
|||
}
|
||||
|
||||
pub fn prompt_editor(
|
||||
context_editor: Entity<ContextEditor>,
|
||||
context_editor: Entity<TextThreadEditor>,
|
||||
history_store: Entity<HistoryStore>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
window: &mut Window,
|
||||
|
@ -434,7 +433,7 @@ impl AgentPanel {
|
|||
let context_store = workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
let project = workspace.project().clone();
|
||||
assistant_context_editor::ContextStore::new(
|
||||
assistant_context::ContextStore::new(
|
||||
project,
|
||||
prompt_builder.clone(),
|
||||
slash_commands,
|
||||
|
@ -546,7 +545,7 @@ impl AgentPanel {
|
|||
context_store.update(cx, |context_store, cx| context_store.create(cx));
|
||||
let lsp_adapter_delegate = make_lsp_adapter_delegate(&project.clone(), cx).unwrap();
|
||||
let context_editor = cx.new(|cx| {
|
||||
let mut editor = ContextEditor::for_context(
|
||||
let mut editor = TextThreadEditor::for_context(
|
||||
context,
|
||||
fs.clone(),
|
||||
workspace.clone(),
|
||||
|
@ -841,7 +840,7 @@ impl AgentPanel {
|
|||
.flatten();
|
||||
|
||||
let context_editor = cx.new(|cx| {
|
||||
let mut editor = ContextEditor::for_context(
|
||||
let mut editor = TextThreadEditor::for_context(
|
||||
context,
|
||||
self.fs.clone(),
|
||||
self.workspace.clone(),
|
||||
|
@ -933,7 +932,7 @@ impl AgentPanel {
|
|||
.log_err()
|
||||
.flatten();
|
||||
let editor = cx.new(|cx| {
|
||||
ContextEditor::for_context(
|
||||
TextThreadEditor::for_context(
|
||||
context,
|
||||
self.fs.clone(),
|
||||
self.workspace.clone(),
|
||||
|
@ -1321,7 +1320,7 @@ impl AgentPanel {
|
|||
});
|
||||
}
|
||||
|
||||
pub(crate) fn active_context_editor(&self) -> Option<Entity<ContextEditor>> {
|
||||
pub(crate) fn active_context_editor(&self) -> Option<Entity<TextThreadEditor>> {
|
||||
match &self.active_view {
|
||||
ActiveView::TextThread { context_editor, .. } => Some(context_editor.clone()),
|
||||
_ => None,
|
||||
|
@ -2899,7 +2898,7 @@ impl AgentPanel {
|
|||
|
||||
fn render_prompt_editor(
|
||||
&self,
|
||||
context_editor: &Entity<ContextEditor>,
|
||||
context_editor: &Entity<TextThreadEditor>,
|
||||
buffer_search_bar: &Entity<BufferSearchBar>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
@ -3026,7 +3025,7 @@ impl AgentPanel {
|
|||
}
|
||||
ActiveView::TextThread { context_editor, .. } => {
|
||||
context_editor.update(cx, |context_editor, cx| {
|
||||
ContextEditor::insert_dragged_files(
|
||||
TextThreadEditor::insert_dragged_files(
|
||||
context_editor,
|
||||
paths,
|
||||
added_worktrees,
|
||||
|
@ -3205,7 +3204,7 @@ impl AgentPanelDelegate for ConcreteAssistantPanelDelegate {
|
|||
workspace: &mut Workspace,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Option<Entity<ContextEditor>> {
|
||||
) -> Option<Entity<TextThreadEditor>> {
|
||||
let panel = workspace.panel::<AgentPanel>(cx)?;
|
||||
panel.read(cx).active_context_editor()
|
||||
}
|
||||
|
@ -3229,10 +3228,10 @@ impl AgentPanelDelegate for ConcreteAssistantPanelDelegate {
|
|||
fn open_remote_context(
|
||||
&self,
|
||||
_workspace: &mut Workspace,
|
||||
_context_id: assistant_context_editor::ContextId,
|
||||
_context_id: assistant_context::ContextId,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Workspace>,
|
||||
) -> Task<Result<Entity<ContextEditor>>> {
|
||||
) -> Task<Result<Entity<TextThreadEditor>>> {
|
||||
Task::ready(Err(anyhow!("opening remote context not implemented")))
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,16 @@ mod context_strip;
|
|||
mod debug;
|
||||
mod inline_assistant;
|
||||
mod inline_prompt_editor;
|
||||
mod language_model_selector;
|
||||
mod max_mode_tooltip;
|
||||
mod message_editor;
|
||||
mod profile_selector;
|
||||
mod slash_command;
|
||||
mod slash_command_picker;
|
||||
mod slash_command_settings;
|
||||
mod terminal_codegen;
|
||||
mod terminal_inline_assistant;
|
||||
mod text_thread_editor;
|
||||
mod thread_history;
|
||||
mod tool_compatibility;
|
||||
mod ui;
|
||||
|
@ -43,6 +48,7 @@ pub use crate::agent_panel::{AgentPanel, ConcreteAssistantPanelDelegate};
|
|||
pub use crate::inline_assistant::InlineAssistant;
|
||||
use crate::slash_command_settings::SlashCommandSettings;
|
||||
pub use agent_diff::{AgentDiffPane, AgentDiffToolbar};
|
||||
pub use text_thread_editor::AgentPanelDelegate;
|
||||
pub use ui::preview::{all_agent_previews, get_agent_preview};
|
||||
|
||||
actions!(
|
||||
|
@ -140,7 +146,7 @@ pub fn init(
|
|||
AgentSettings::register(cx);
|
||||
SlashCommandSettings::register(cx);
|
||||
|
||||
assistant_context_editor::init(client.clone(), cx);
|
||||
assistant_context::init(client.clone(), cx);
|
||||
rules_library::init(cx);
|
||||
if !is_eval {
|
||||
// Initializing the language model from the user settings messes with the eval, so we only initialize them when
|
||||
|
|
|
@ -73,7 +73,7 @@ fn search(
|
|||
recent_entries: Vec<RecentEntry>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
thread_store: Option<WeakEntity<ThreadStore>>,
|
||||
text_thread_context_store: Option<WeakEntity<assistant_context_editor::ContextStore>>,
|
||||
text_thread_context_store: Option<WeakEntity<assistant_context::ContextStore>>,
|
||||
workspace: Entity<Workspace>,
|
||||
cx: &mut App,
|
||||
) -> Task<Vec<Match>> {
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::agent_model_selector::AgentModelSelector;
|
|||
use crate::buffer_codegen::BufferCodegen;
|
||||
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
|
||||
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||
use crate::language_model_selector::ToggleModelSelector;
|
||||
use crate::message_editor::{ContextCreasesAddon, extract_message_creases, insert_message_creases};
|
||||
use crate::terminal_codegen::TerminalCodegen;
|
||||
use crate::{CycleNextInlineAssist, CyclePreviousInlineAssist, ModelUsageContext};
|
||||
|
@ -10,7 +11,6 @@ use agent::{
|
|||
context_store::ContextStore,
|
||||
thread_store::{TextThreadStore, ThreadStore},
|
||||
};
|
||||
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
||||
use client::ErrorExt;
|
||||
use collections::VecDeque;
|
||||
use db::kvp::Dismissable;
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::agent_model_selector::AgentModelSelector;
|
||||
use crate::language_model_selector::ToggleModelSelector;
|
||||
use crate::tool_compatibility::{IncompatibleToolsState, IncompatibleToolsTooltip};
|
||||
use crate::ui::{
|
||||
MaxModeTooltip,
|
||||
|
@ -13,7 +14,6 @@ use agent::{
|
|||
context_store::ContextStoreEvent,
|
||||
};
|
||||
use agent_settings::{AgentSettings, CompletionMode};
|
||||
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
||||
use buffer_diff::BufferDiff;
|
||||
use client::UserStore;
|
||||
use collections::{HashMap, HashSet};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::context_editor::ContextEditor;
|
||||
use crate::text_thread_editor::TextThreadEditor;
|
||||
use anyhow::Result;
|
||||
pub use assistant_slash_command::SlashCommand;
|
||||
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
|
||||
|
@ -21,14 +21,14 @@ use workspace::Workspace;
|
|||
pub struct SlashCommandCompletionProvider {
|
||||
cancel_flag: Mutex<Arc<AtomicBool>>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
editor: Option<WeakEntity<ContextEditor>>,
|
||||
editor: Option<WeakEntity<TextThreadEditor>>,
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
}
|
||||
|
||||
impl SlashCommandCompletionProvider {
|
||||
pub fn new(
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
editor: Option<WeakEntity<ContextEditor>>,
|
||||
editor: Option<WeakEntity<TextThreadEditor>>,
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
) -> Self {
|
||||
Self {
|
|
@ -1,12 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::text_thread_editor::TextThreadEditor;
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
use gpui::{AnyElement, AnyView, DismissEvent, SharedString, Task, WeakEntity};
|
||||
use picker::{Picker, PickerDelegate, PickerEditorPosition};
|
||||
use std::sync::Arc;
|
||||
use ui::{ListItem, ListItemSpacing, PopoverMenu, PopoverTrigger, Tooltip, prelude::*};
|
||||
|
||||
use crate::context_editor::ContextEditor;
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub(super) struct SlashCommandSelector<T, TT>
|
||||
where
|
||||
|
@ -14,7 +12,7 @@ where
|
|||
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
|
||||
{
|
||||
working_set: Arc<SlashCommandWorkingSet>,
|
||||
active_context_editor: WeakEntity<ContextEditor>,
|
||||
active_context_editor: WeakEntity<TextThreadEditor>,
|
||||
trigger: T,
|
||||
tooltip: TT,
|
||||
}
|
||||
|
@ -49,7 +47,7 @@ impl AsRef<str> for SlashCommandEntry {
|
|||
pub(crate) struct SlashCommandDelegate {
|
||||
all_commands: Vec<SlashCommandEntry>,
|
||||
filtered_commands: Vec<SlashCommandEntry>,
|
||||
active_context_editor: WeakEntity<ContextEditor>,
|
||||
active_context_editor: WeakEntity<TextThreadEditor>,
|
||||
selected_index: usize,
|
||||
}
|
||||
|
||||
|
@ -60,7 +58,7 @@ where
|
|||
{
|
||||
pub(crate) fn new(
|
||||
working_set: Arc<SlashCommandWorkingSet>,
|
||||
active_context_editor: WeakEntity<ContextEditor>,
|
||||
active_context_editor: WeakEntity<TextThreadEditor>,
|
||||
trigger: T,
|
||||
tooltip: TT,
|
||||
) -> Self {
|
|
@ -76,14 +76,11 @@ use workspace::{
|
|||
searchable::{SearchEvent, SearchableItem},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
use crate::{slash_command::SlashCommandCompletionProvider, slash_command_picker};
|
||||
use assistant_context::{
|
||||
AssistantContext, CacheStatus, Content, ContextEvent, ContextId, InvokedSlashCommandId,
|
||||
InvokedSlashCommandStatus, Message, MessageId, MessageMetadata, MessageStatus,
|
||||
ParsedSlashCommand, PendingSlashCommandStatus,
|
||||
};
|
||||
use crate::{
|
||||
ThoughtProcessOutputSection, slash_command::SlashCommandCompletionProvider,
|
||||
slash_command_picker,
|
||||
ParsedSlashCommand, PendingSlashCommandStatus, ThoughtProcessOutputSection,
|
||||
};
|
||||
|
||||
actions!(
|
||||
|
@ -131,7 +128,7 @@ pub trait AgentPanelDelegate {
|
|||
workspace: &mut Workspace,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Option<Entity<ContextEditor>>;
|
||||
) -> Option<Entity<TextThreadEditor>>;
|
||||
|
||||
fn open_saved_context(
|
||||
&self,
|
||||
|
@ -147,7 +144,7 @@ pub trait AgentPanelDelegate {
|
|||
context_id: ContextId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Task<Result<Entity<ContextEditor>>>;
|
||||
) -> Task<Result<Entity<TextThreadEditor>>>;
|
||||
|
||||
fn quote_selection(
|
||||
&self,
|
||||
|
@ -176,7 +173,7 @@ struct GlobalAssistantPanelDelegate(Arc<dyn AgentPanelDelegate>);
|
|||
|
||||
impl Global for GlobalAssistantPanelDelegate {}
|
||||
|
||||
pub struct ContextEditor {
|
||||
pub struct TextThreadEditor {
|
||||
context: Entity<AssistantContext>,
|
||||
fs: Arc<dyn Fs>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
|
@ -206,10 +203,24 @@ pub struct ContextEditor {
|
|||
language_model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
}
|
||||
|
||||
pub const DEFAULT_TAB_TITLE: &str = "New Chat";
|
||||
const MAX_TAB_TITLE_LEN: usize = 16;
|
||||
|
||||
impl ContextEditor {
|
||||
impl TextThreadEditor {
|
||||
pub fn init(cx: &mut App) {
|
||||
workspace::FollowableViewRegistry::register::<TextThreadEditor>(cx);
|
||||
|
||||
cx.observe_new(
|
||||
|workspace: &mut Workspace, _window, _cx: &mut Context<Workspace>| {
|
||||
workspace
|
||||
.register_action(TextThreadEditor::quote_selection)
|
||||
.register_action(TextThreadEditor::insert_selection)
|
||||
.register_action(TextThreadEditor::copy_code)
|
||||
.register_action(TextThreadEditor::handle_insert_dragged_files);
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn for_context(
|
||||
context: Entity<AssistantContext>,
|
||||
fs: Arc<dyn Fs>,
|
||||
|
@ -1279,7 +1290,7 @@ impl ContextEditor {
|
|||
/// Returns either the selected text, or the content of the Markdown code
|
||||
/// block surrounding the cursor.
|
||||
fn get_selection_or_code_block(
|
||||
context_editor_view: &Entity<ContextEditor>,
|
||||
context_editor_view: &Entity<TextThreadEditor>,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Option<(String, bool)> {
|
||||
const CODE_FENCE_DELIMITER: &'static str = "```";
|
||||
|
@ -2029,7 +2040,7 @@ impl ContextEditor {
|
|||
/// Whether or not we should allow messages to be sent.
|
||||
/// Will return false if the selected provided has a configuration error or
|
||||
/// if the user has not accepted the terms of service for this provider.
|
||||
fn sending_disabled(&self, cx: &mut Context<'_, ContextEditor>) -> bool {
|
||||
fn sending_disabled(&self, cx: &mut Context<'_, TextThreadEditor>) -> bool {
|
||||
let model_registry = LanguageModelRegistry::read_global(cx);
|
||||
let Some(configuration_error) =
|
||||
model_registry.configuration_error(model_registry.default_model(), cx)
|
||||
|
@ -2546,10 +2557,10 @@ struct SelectedCreaseMetadata {
|
|||
crease: CreaseMetadata,
|
||||
}
|
||||
|
||||
impl EventEmitter<EditorEvent> for ContextEditor {}
|
||||
impl EventEmitter<SearchEvent> for ContextEditor {}
|
||||
impl EventEmitter<EditorEvent> for TextThreadEditor {}
|
||||
impl EventEmitter<SearchEvent> for TextThreadEditor {}
|
||||
|
||||
impl Render for ContextEditor {
|
||||
impl Render for TextThreadEditor {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let provider = LanguageModelRegistry::read_global(cx)
|
||||
.default_model()
|
||||
|
@ -2568,15 +2579,15 @@ impl Render for ContextEditor {
|
|||
|
||||
v_flex()
|
||||
.key_context("ContextEditor")
|
||||
.capture_action(cx.listener(ContextEditor::cancel))
|
||||
.capture_action(cx.listener(ContextEditor::save))
|
||||
.capture_action(cx.listener(ContextEditor::copy))
|
||||
.capture_action(cx.listener(ContextEditor::cut))
|
||||
.capture_action(cx.listener(ContextEditor::paste))
|
||||
.capture_action(cx.listener(ContextEditor::cycle_message_role))
|
||||
.capture_action(cx.listener(ContextEditor::confirm_command))
|
||||
.on_action(cx.listener(ContextEditor::assist))
|
||||
.on_action(cx.listener(ContextEditor::split))
|
||||
.capture_action(cx.listener(TextThreadEditor::cancel))
|
||||
.capture_action(cx.listener(TextThreadEditor::save))
|
||||
.capture_action(cx.listener(TextThreadEditor::copy))
|
||||
.capture_action(cx.listener(TextThreadEditor::cut))
|
||||
.capture_action(cx.listener(TextThreadEditor::paste))
|
||||
.capture_action(cx.listener(TextThreadEditor::cycle_message_role))
|
||||
.capture_action(cx.listener(TextThreadEditor::confirm_command))
|
||||
.on_action(cx.listener(TextThreadEditor::assist))
|
||||
.on_action(cx.listener(TextThreadEditor::split))
|
||||
.on_action(move |_: &ToggleModelSelector, window, cx| {
|
||||
language_model_selector.toggle(window, cx);
|
||||
})
|
||||
|
@ -2631,13 +2642,13 @@ impl Render for ContextEditor {
|
|||
}
|
||||
}
|
||||
|
||||
impl Focusable for ContextEditor {
|
||||
impl Focusable for TextThreadEditor {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.editor.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Item for ContextEditor {
|
||||
impl Item for TextThreadEditor {
|
||||
type Event = editor::EditorEvent;
|
||||
|
||||
fn tab_content_text(&self, _detail: usize, cx: &App) -> SharedString {
|
||||
|
@ -2710,7 +2721,7 @@ impl Item for ContextEditor {
|
|||
}
|
||||
}
|
||||
|
||||
impl SearchableItem for ContextEditor {
|
||||
impl SearchableItem for TextThreadEditor {
|
||||
type Match = <Editor as SearchableItem>::Match;
|
||||
|
||||
fn clear_matches(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
|
@ -2791,7 +2802,7 @@ impl SearchableItem for ContextEditor {
|
|||
}
|
||||
}
|
||||
|
||||
impl FollowableItem for ContextEditor {
|
||||
impl FollowableItem for TextThreadEditor {
|
||||
fn remote_id(&self) -> Option<workspace::ViewId> {
|
||||
self.remote_id
|
||||
}
|
||||
|
@ -2914,21 +2925,14 @@ impl FollowableItem for ContextEditor {
|
|||
}
|
||||
|
||||
pub struct ContextEditorToolbarItem {
|
||||
active_context_editor: Option<WeakEntity<ContextEditor>>,
|
||||
active_context_editor: Option<WeakEntity<TextThreadEditor>>,
|
||||
model_summary_editor: Entity<Editor>,
|
||||
}
|
||||
|
||||
impl ContextEditorToolbarItem {
|
||||
pub fn new(model_summary_editor: Entity<Editor>) -> Self {
|
||||
Self {
|
||||
active_context_editor: None,
|
||||
model_summary_editor,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ContextEditorToolbarItem {}
|
||||
|
||||
pub fn render_remaining_tokens(
|
||||
context_editor: &Entity<ContextEditor>,
|
||||
context_editor: &Entity<TextThreadEditor>,
|
||||
cx: &App,
|
||||
) -> Option<impl IntoElement + use<>> {
|
||||
let context = &context_editor.read(cx).context;
|
||||
|
@ -3044,7 +3048,7 @@ impl ToolbarItemView for ContextEditorToolbarItem {
|
|||
cx: &mut Context<Self>,
|
||||
) -> ToolbarItemLocation {
|
||||
self.active_context_editor = active_pane_item
|
||||
.and_then(|item| item.act_as::<ContextEditor>(cx))
|
||||
.and_then(|item| item.act_as::<TextThreadEditor>(cx))
|
||||
.map(|editor| editor.downgrade());
|
||||
cx.notify();
|
||||
if self.active_context_editor.is_none() {
|
||||
|
@ -3405,7 +3409,7 @@ mod tests {
|
|||
cx: &mut TestAppContext,
|
||||
) -> (
|
||||
Entity<AssistantContext>,
|
||||
Entity<ContextEditor>,
|
||||
Entity<TextThreadEditor>,
|
||||
VisualTestContext,
|
||||
) {
|
||||
cx.update(init_test);
|
||||
|
@ -3421,7 +3425,7 @@ mod tests {
|
|||
let context_editor = window
|
||||
.update(&mut cx, |_, window, cx| {
|
||||
cx.new(|cx| {
|
||||
let editor = ContextEditor::for_context(
|
||||
let editor = TextThreadEditor::for_context(
|
||||
context.clone(),
|
||||
fs,
|
||||
workspace.downgrade(),
|
||||
|
@ -3454,7 +3458,7 @@ mod tests {
|
|||
}
|
||||
|
||||
fn assert_copy_paste_context_editor<T: editor::ToOffset>(
|
||||
context_editor: &Entity<ContextEditor>,
|
||||
context_editor: &Entity<TextThreadEditor>,
|
||||
range: Range<T>,
|
||||
expected_text: &str,
|
||||
cx: &mut VisualTestContext,
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "assistant_context_editor"
|
||||
name = "assistant_context"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
|
@ -9,7 +9,7 @@ license = "GPL-3.0-or-later"
|
|||
workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/assistant_context_editor.rs"
|
||||
path = "src/assistant_context.rs"
|
||||
|
||||
[dependencies]
|
||||
agent_settings.workspace = true
|
||||
|
@ -21,27 +21,20 @@ client.workspace = true
|
|||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
context_server.workspace = true
|
||||
editor.workspace = true
|
||||
feature_flags.workspace = true
|
||||
fs.workspace = true
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
indexed_docs.workspace = true
|
||||
language.workspace = true
|
||||
language_model.workspace = true
|
||||
log.workspace = true
|
||||
multi_buffer.workspace = true
|
||||
open_ai.workspace = true
|
||||
ordered-float.workspace = true
|
||||
parking_lot.workspace = true
|
||||
paths.workspace = true
|
||||
picker.workspace = true
|
||||
project.workspace = true
|
||||
prompt_store.workspace = true
|
||||
proto.workspace = true
|
||||
regex.workspace = true
|
||||
rope.workspace = true
|
||||
rpc.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
@ -50,21 +43,17 @@ smallvec.workspace = true
|
|||
smol.workspace = true
|
||||
telemetry_events.workspace = true
|
||||
text.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
uuid.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
zed_llm_client.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
indoc.workspace = true
|
||||
language_model = { workspace = true, features = ["test-support"] }
|
||||
languages = { workspace = true, features = ["test-support"] }
|
||||
pretty_assertions.workspace = true
|
||||
rand.workspace = true
|
||||
tree-sitter-md.workspace = true
|
||||
unindent.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
|
@ -1,5 +1,6 @@
|
|||
#[cfg(test)]
|
||||
mod context_tests;
|
||||
mod assistant_context_tests;
|
||||
mod context_store;
|
||||
|
||||
use agent_settings::AgentSettings;
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
|
@ -8,7 +9,7 @@ use assistant_slash_command::{
|
|||
SlashCommandResult, SlashCommandWorkingSet,
|
||||
};
|
||||
use assistant_slash_commands::FileCommandMetadata;
|
||||
use client::{self, proto, telemetry::Telemetry};
|
||||
use client::{self, Client, proto, telemetry::Telemetry};
|
||||
use clock::ReplicaId;
|
||||
use collections::{HashMap, HashSet};
|
||||
use fs::{Fs, RenameOptions};
|
||||
|
@ -47,6 +48,12 @@ use util::{ResultExt, TryFutureExt, post_inc};
|
|||
use uuid::Uuid;
|
||||
use zed_llm_client::CompletionIntent;
|
||||
|
||||
pub use crate::context_store::*;
|
||||
|
||||
pub fn init(client: Arc<Client>, _: &mut App) {
|
||||
context_store::init(&client.into());
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct ContextId(String);
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
mod context;
|
||||
mod context_editor;
|
||||
mod context_history;
|
||||
mod context_store;
|
||||
pub mod language_model_selector;
|
||||
mod max_mode_tooltip;
|
||||
mod slash_command;
|
||||
mod slash_command_picker;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use client::Client;
|
||||
use gpui::{App, Context};
|
||||
use workspace::Workspace;
|
||||
|
||||
pub use crate::context::*;
|
||||
pub use crate::context_editor::*;
|
||||
pub use crate::context_history::*;
|
||||
pub use crate::context_store::*;
|
||||
pub use crate::slash_command::*;
|
||||
|
||||
pub fn init(client: Arc<Client>, cx: &mut App) {
|
||||
context_store::init(&client.into());
|
||||
workspace::FollowableViewRegistry::register::<ContextEditor>(cx);
|
||||
|
||||
cx.observe_new(
|
||||
|workspace: &mut Workspace, _window, _cx: &mut Context<Workspace>| {
|
||||
workspace
|
||||
.register_action(ContextEditor::quote_selection)
|
||||
.register_action(ContextEditor::insert_selection)
|
||||
.register_action(ContextEditor::copy_code)
|
||||
.register_action(ContextEditor::handle_insert_dragged_files);
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
}
|
|
@ -1,271 +0,0 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use gpui::{App, Entity, EventEmitter, FocusHandle, Focusable, Subscription, Task, WeakEntity};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::Project;
|
||||
use ui::utils::{DateTimeType, format_distance_from_now};
|
||||
use ui::{Avatar, ListItem, ListItemSpacing, prelude::*};
|
||||
use workspace::{Item, Workspace};
|
||||
|
||||
use crate::{
|
||||
AgentPanelDelegate, ContextStore, DEFAULT_TAB_TITLE, RemoteContextMetadata,
|
||||
SavedContextMetadata,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ContextMetadata {
|
||||
Remote(RemoteContextMetadata),
|
||||
Saved(SavedContextMetadata),
|
||||
}
|
||||
|
||||
enum SavedContextPickerEvent {
|
||||
Confirmed(ContextMetadata),
|
||||
}
|
||||
|
||||
pub struct ContextHistory {
|
||||
picker: Entity<Picker<SavedContextPickerDelegate>>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
}
|
||||
|
||||
impl ContextHistory {
|
||||
pub fn new(
|
||||
project: Entity<Project>,
|
||||
context_store: Entity<ContextStore>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let picker = cx.new(|cx| {
|
||||
Picker::uniform_list(
|
||||
SavedContextPickerDelegate::new(project, context_store.clone()),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.modal(false)
|
||||
.max_height(None)
|
||||
});
|
||||
|
||||
let subscriptions = vec![
|
||||
cx.observe_in(&context_store, window, |this, _, window, cx| {
|
||||
this.picker
|
||||
.update(cx, |picker, cx| picker.refresh(window, cx));
|
||||
}),
|
||||
cx.subscribe_in(&picker, window, Self::handle_picker_event),
|
||||
];
|
||||
|
||||
Self {
|
||||
picker,
|
||||
_subscriptions: subscriptions,
|
||||
workspace,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_picker_event(
|
||||
&mut self,
|
||||
_: &Entity<Picker<SavedContextPickerDelegate>>,
|
||||
event: &SavedContextPickerEvent,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let SavedContextPickerEvent::Confirmed(context) = event;
|
||||
|
||||
let Some(agent_panel_delegate) = <dyn AgentPanelDelegate>::try_global(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.workspace
|
||||
.update(cx, |workspace, cx| match context {
|
||||
ContextMetadata::Remote(metadata) => {
|
||||
agent_panel_delegate
|
||||
.open_remote_context(workspace, metadata.id.clone(), window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
ContextMetadata::Saved(metadata) => {
|
||||
agent_panel_delegate
|
||||
.open_saved_context(workspace, metadata.path.clone(), window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ContextHistory {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div().size_full().child(self.picker.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for ContextHistory {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<()> for ContextHistory {}
|
||||
|
||||
impl Item for ContextHistory {
|
||||
type Event = ();
|
||||
|
||||
fn tab_content_text(&self, _detail: usize, _cx: &App) -> SharedString {
|
||||
"History".into()
|
||||
}
|
||||
}
|
||||
|
||||
struct SavedContextPickerDelegate {
|
||||
store: Entity<ContextStore>,
|
||||
project: Entity<Project>,
|
||||
matches: Vec<ContextMetadata>,
|
||||
selected_index: usize,
|
||||
}
|
||||
|
||||
impl EventEmitter<SavedContextPickerEvent> for Picker<SavedContextPickerDelegate> {}
|
||||
|
||||
impl SavedContextPickerDelegate {
|
||||
fn new(project: Entity<Project>, store: Entity<ContextStore>) -> Self {
|
||||
Self {
|
||||
project,
|
||||
store,
|
||||
matches: Vec::new(),
|
||||
selected_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PickerDelegate for SavedContextPickerDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.matches.len()
|
||||
}
|
||||
|
||||
fn selected_index(&self) -> usize {
|
||||
self.selected_index
|
||||
}
|
||||
|
||||
fn set_selected_index(
|
||||
&mut self,
|
||||
ix: usize,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Picker<Self>>,
|
||||
) {
|
||||
self.selected_index = ix;
|
||||
}
|
||||
|
||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||
"Search...".into()
|
||||
}
|
||||
|
||||
fn update_matches(
|
||||
&mut self,
|
||||
query: String,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let search = self.store.read(cx).search(query, cx);
|
||||
cx.spawn(async move |this, cx| {
|
||||
let matches = search.await;
|
||||
this.update(cx, |this, cx| {
|
||||
let host_contexts = this.delegate.store.read(cx).host_contexts();
|
||||
this.delegate.matches = host_contexts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(ContextMetadata::Remote)
|
||||
.chain(matches.into_iter().map(ContextMetadata::Saved))
|
||||
.collect();
|
||||
this.delegate.selected_index = 0;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
}
|
||||
|
||||
fn confirm(&mut self, _secondary: bool, _window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
if let Some(metadata) = self.matches.get(self.selected_index) {
|
||||
cx.emit(SavedContextPickerEvent::Confirmed(metadata.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
fn dismissed(&mut self, _window: &mut Window, _cx: &mut Context<Picker<Self>>) {}
|
||||
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let context = self.matches.get(ix)?;
|
||||
let item = match context {
|
||||
ContextMetadata::Remote(context) => {
|
||||
let host_user = self.project.read(cx).host().and_then(|collaborator| {
|
||||
self.project
|
||||
.read(cx)
|
||||
.user_store()
|
||||
.read(cx)
|
||||
.get_cached_user(collaborator.user_id)
|
||||
});
|
||||
div()
|
||||
.flex()
|
||||
.w_full()
|
||||
.justify_between()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex().flex_1().overflow_x_hidden().child(
|
||||
Label::new(context.summary.clone().unwrap_or(DEFAULT_TAB_TITLE.into()))
|
||||
.size(LabelSize::Small),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.children(if let Some(host_user) = host_user {
|
||||
vec![
|
||||
Avatar::new(host_user.avatar_uri.clone()).into_any_element(),
|
||||
Label::new(format!("Shared by @{}", host_user.github_login))
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small)
|
||||
.into_any_element(),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
Label::new("Shared by host")
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small)
|
||||
.into_any_element(),
|
||||
]
|
||||
}),
|
||||
)
|
||||
}
|
||||
ContextMetadata::Saved(context) => div()
|
||||
.flex()
|
||||
.w_full()
|
||||
.justify_between()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.flex_1()
|
||||
.child(Label::new(context.title.clone()).size(LabelSize::Small))
|
||||
.overflow_x_hidden(),
|
||||
)
|
||||
.child(
|
||||
Label::new(format_distance_from_now(
|
||||
DateTimeType::Local(context.mtime),
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
))
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small),
|
||||
),
|
||||
};
|
||||
Some(
|
||||
ListItem::new(ix)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.toggle_state(selected)
|
||||
.child(item),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -78,7 +78,7 @@ zed_llm_client.workspace = true
|
|||
|
||||
[dev-dependencies]
|
||||
agent_settings.workspace = true
|
||||
assistant_context_editor.workspace = true
|
||||
assistant_context.workspace = true
|
||||
assistant_slash_command.workspace = true
|
||||
async-trait.workspace = true
|
||||
audio.workspace = true
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_context_editor::ContextStore;
|
||||
use assistant_context::ContextStore;
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus, assert_hunks};
|
||||
use call::{ActiveCall, ParticipantLocation, Room, room};
|
||||
|
|
|
@ -313,7 +313,7 @@ impl TestServer {
|
|||
settings::KeymapFile::load_asset_allow_partial_failure(os_keymap, cx).unwrap(),
|
||||
);
|
||||
language_model::LanguageModelRegistry::test(cx);
|
||||
assistant_context_editor::init(client.clone(), cx);
|
||||
assistant_context::init(client.clone(), cx);
|
||||
agent_settings::init(cx);
|
||||
});
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ agent_settings.workspace = true
|
|||
anyhow.workspace = true
|
||||
askpass.workspace = true
|
||||
assets.workspace = true
|
||||
assistant_context_editor.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
assistant_tools.workspace = true
|
||||
audio.workspace = true
|
||||
|
|
|
@ -9,11 +9,10 @@ mod quick_action_bar;
|
|||
#[cfg(target_os = "windows")]
|
||||
pub(crate) mod windows_only_instance;
|
||||
|
||||
use agent_ui::AgentDiffToolbar;
|
||||
use agent_ui::{AgentDiffToolbar, AgentPanelDelegate};
|
||||
use anyhow::Context as _;
|
||||
pub use app_menus::*;
|
||||
use assets::Assets;
|
||||
use assistant_context_editor::AgentPanelDelegate;
|
||||
use breadcrumbs::Breadcrumbs;
|
||||
use client::zed_urls;
|
||||
use collections::VecDeque;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue