diff --git a/crates/agent/src/context_picker.rs b/crates/agent/src/context_picker.rs index bcbee38b73..9e578c4fc0 100644 --- a/crates/agent/src/context_picker.rs +++ b/crates/agent/src/context_picker.rs @@ -34,12 +34,6 @@ use crate::context_store::ContextStore; use crate::thread::ThreadId; use crate::thread_store::ThreadStore; -#[derive(Debug, Clone, Copy)] -pub enum ConfirmBehavior { - KeepOpen, - Close, -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum ContextPickerMode { File, @@ -105,7 +99,6 @@ pub(super) struct ContextPicker { workspace: WeakEntity, context_store: WeakEntity, thread_store: Option>, - confirm_behavior: ConfirmBehavior, _subscriptions: Vec, } @@ -114,7 +107,6 @@ impl ContextPicker { workspace: WeakEntity, thread_store: Option>, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, window: &mut Window, cx: &mut Context, ) -> Self { @@ -143,7 +135,6 @@ impl ContextPicker { workspace, context_store, thread_store, - confirm_behavior, _subscriptions: subscriptions, } } @@ -166,37 +157,32 @@ impl ContextPicker { let modes = supported_context_picker_modes(&self.thread_store); - let menu = menu - .when(has_recent, |menu| { - menu.custom_row(|_, _| { - div() - .mb_1() - .child( - Label::new("Recent") - .color(Color::Muted) - .size(LabelSize::Small), - ) - .into_any_element() - }) + menu.when(has_recent, |menu| { + menu.custom_row(|_, _| { + div() + .mb_1() + .child( + Label::new("Recent") + .color(Color::Muted) + .size(LabelSize::Small), + ) + .into_any_element() }) - .extend(recent_entries) - .when(has_recent, |menu| menu.separator()) - .extend(modes.into_iter().map(|mode| { - let context_picker = context_picker.clone(); + }) + .extend(recent_entries) + .when(has_recent, |menu| menu.separator()) + .extend(modes.into_iter().map(|mode| { + let context_picker = context_picker.clone(); - ContextMenuEntry::new(mode.label()) - .icon(mode.icon()) - .icon_size(IconSize::XSmall) - .icon_color(Color::Muted) - .handler(move |window, cx| { - context_picker.update(cx, |this, cx| this.select_mode(mode, window, cx)) - }) - })); - - match self.confirm_behavior { - ConfirmBehavior::KeepOpen => menu.keep_open_on_confirm(), - ConfirmBehavior::Close => menu, - } + ContextMenuEntry::new(mode.label()) + .icon(mode.icon()) + .icon_size(IconSize::XSmall) + .icon_color(Color::Muted) + .handler(move |window, cx| { + context_picker.update(cx, |this, cx| this.select_mode(mode, window, cx)) + }) + })) + .keep_open_on_confirm() }); cx.subscribe(&menu, move |_, _, _: &DismissEvent, cx| { @@ -227,7 +213,6 @@ impl ContextPicker { context_picker.clone(), self.workspace.clone(), self.context_store.clone(), - self.confirm_behavior, window, cx, ) @@ -239,7 +224,6 @@ impl ContextPicker { context_picker.clone(), self.workspace.clone(), self.context_store.clone(), - self.confirm_behavior, window, cx, ) @@ -251,7 +235,6 @@ impl ContextPicker { context_picker.clone(), self.workspace.clone(), self.context_store.clone(), - self.confirm_behavior, window, cx, ) @@ -264,7 +247,6 @@ impl ContextPicker { thread_store.clone(), context_picker.clone(), self.context_store.clone(), - self.confirm_behavior, window, cx, ) diff --git a/crates/agent/src/context_picker/fetch_context_picker.rs b/crates/agent/src/context_picker/fetch_context_picker.rs index c4a9dd1211..5c7795237b 100644 --- a/crates/agent/src/context_picker/fetch_context_picker.rs +++ b/crates/agent/src/context_picker/fetch_context_picker.rs @@ -11,7 +11,7 @@ use picker::{Picker, PickerDelegate}; use ui::{Context, ListItem, Window, prelude::*}; use workspace::Workspace; -use crate::context_picker::{ConfirmBehavior, ContextPicker}; +use crate::context_picker::ContextPicker; use crate::context_store::ContextStore; pub struct FetchContextPicker { @@ -23,16 +23,10 @@ impl FetchContextPicker { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, window: &mut Window, cx: &mut Context, ) -> Self { - let delegate = FetchContextPickerDelegate::new( - context_picker, - workspace, - context_store, - confirm_behavior, - ); + let delegate = FetchContextPickerDelegate::new(context_picker, workspace, context_store); let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx)); Self { picker } @@ -62,7 +56,6 @@ pub struct FetchContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, url: String, } @@ -71,13 +64,11 @@ impl FetchContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, ) -> Self { FetchContextPickerDelegate { context_picker, workspace, context_store, - confirm_behavior, url: String::new(), } } @@ -204,25 +195,15 @@ impl PickerDelegate for FetchContextPickerDelegate { let http_client = workspace.read(cx).client().http_client().clone(); let url = self.url.clone(); - let confirm_behavior = self.confirm_behavior; cx.spawn_in(window, async move |this, cx| { let text = cx .background_spawn(fetch_url_content(http_client, url.clone())) .await?; - this.update_in(cx, |this, window, cx| { - this.delegate - .context_store - .update(cx, |context_store, cx| { - context_store.add_fetched_url(url, text, cx) - })?; - - match confirm_behavior { - ConfirmBehavior::KeepOpen => {} - ConfirmBehavior::Close => this.delegate.dismissed(window, cx), - } - - anyhow::Ok(()) + this.update(cx, |this, cx| { + this.delegate.context_store.update(cx, |context_store, cx| { + context_store.add_fetched_url(url, text, cx) + }) })??; anyhow::Ok(()) diff --git a/crates/agent/src/context_picker/file_context_picker.rs b/crates/agent/src/context_picker/file_context_picker.rs index 965f4a530e..5981b471c2 100644 --- a/crates/agent/src/context_picker/file_context_picker.rs +++ b/crates/agent/src/context_picker/file_context_picker.rs @@ -11,9 +11,9 @@ use picker::{Picker, PickerDelegate}; use project::{PathMatchCandidateSet, ProjectPath, WorktreeId}; use ui::{ListItem, Tooltip, prelude::*}; use util::ResultExt as _; -use workspace::{Workspace, notifications::NotifyResultExt}; +use workspace::Workspace; -use crate::context_picker::{ConfirmBehavior, ContextPicker}; +use crate::context_picker::ContextPicker; use crate::context_store::{ContextStore, FileInclusion}; pub struct FileContextPicker { @@ -25,16 +25,10 @@ impl FileContextPicker { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, window: &mut Window, cx: &mut Context, ) -> Self { - let delegate = FileContextPickerDelegate::new( - context_picker, - workspace, - context_store, - confirm_behavior, - ); + let delegate = FileContextPickerDelegate::new(context_picker, workspace, context_store); let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx)); Self { picker } @@ -57,7 +51,6 @@ pub struct FileContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, matches: Vec, selected_index: usize, } @@ -67,13 +60,11 @@ impl FileContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, ) -> Self { Self { context_picker, workspace, context_store, - confirm_behavior, matches: Vec::new(), selected_index: 0, } @@ -127,7 +118,7 @@ impl PickerDelegate for FileContextPickerDelegate { }) } - fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context>) { + fn confirm(&mut self, _secondary: bool, _window: &mut Window, cx: &mut Context>) { let Some(FileMatch { mat, .. }) = self.matches.get(self.selected_index) else { return; }; @@ -153,17 +144,7 @@ impl PickerDelegate for FileContextPickerDelegate { return; }; - let confirm_behavior = self.confirm_behavior; - cx.spawn_in(window, async move |this, cx| { - match task.await.notify_async_err(cx) { - None => anyhow::Ok(()), - Some(()) => this.update_in(cx, |this, window, cx| match confirm_behavior { - ConfirmBehavior::KeepOpen => {} - ConfirmBehavior::Close => this.delegate.dismissed(window, cx), - }), - } - }) - .detach_and_log_err(cx); + task.detach_and_log_err(cx); } fn dismissed(&mut self, _: &mut Window, cx: &mut Context>) { diff --git a/crates/agent/src/context_picker/symbol_context_picker.rs b/crates/agent/src/context_picker/symbol_context_picker.rs index 608accc098..b76d4a8093 100644 --- a/crates/agent/src/context_picker/symbol_context_picker.rs +++ b/crates/agent/src/context_picker/symbol_context_picker.rs @@ -15,7 +15,7 @@ use ui::{ListItem, prelude::*}; use util::ResultExt as _; use workspace::Workspace; -use crate::context_picker::{ConfirmBehavior, ContextPicker}; +use crate::context_picker::ContextPicker; use crate::context_store::ContextStore; pub struct SymbolContextPicker { @@ -27,16 +27,10 @@ impl SymbolContextPicker { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, window: &mut Window, cx: &mut Context, ) -> Self { - let delegate = SymbolContextPickerDelegate::new( - context_picker, - workspace, - context_store, - confirm_behavior, - ); + let delegate = SymbolContextPickerDelegate::new(context_picker, workspace, context_store); let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx)); Self { picker } @@ -59,7 +53,6 @@ pub struct SymbolContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, matches: Vec, selected_index: usize, } @@ -69,13 +62,11 @@ impl SymbolContextPickerDelegate { context_picker: WeakEntity, workspace: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, ) -> Self { Self { context_picker, workspace, context_store, - confirm_behavior, matches: Vec::new(), selected_index: 0, } @@ -135,7 +126,7 @@ impl PickerDelegate for SymbolContextPickerDelegate { }) } - fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context>) { + fn confirm(&mut self, _secondary: bool, _window: &mut Window, cx: &mut Context>) { let Some(mat) = self.matches.get(self.selected_index) else { return; }; @@ -143,7 +134,6 @@ impl PickerDelegate for SymbolContextPickerDelegate { return; }; - let confirm_behavior = self.confirm_behavior; let add_symbol_task = add_symbol( mat.symbol.clone(), true, @@ -153,16 +143,12 @@ impl PickerDelegate for SymbolContextPickerDelegate { ); let selected_index = self.selected_index; - cx.spawn_in(window, async move |this, cx| { + cx.spawn(async move |this, cx| { let included = add_symbol_task.await?; - this.update_in(cx, |this, window, cx| { + this.update(cx, |this, _| { if let Some(mat) = this.delegate.matches.get_mut(selected_index) { mat.is_included = included; } - match confirm_behavior { - ConfirmBehavior::KeepOpen => {} - ConfirmBehavior::Close => this.delegate.dismissed(window, cx), - } }) }) .detach_and_log_err(cx); diff --git a/crates/agent/src/context_picker/thread_context_picker.rs b/crates/agent/src/context_picker/thread_context_picker.rs index 98f62b3073..941926a898 100644 --- a/crates/agent/src/context_picker/thread_context_picker.rs +++ b/crates/agent/src/context_picker/thread_context_picker.rs @@ -6,7 +6,7 @@ use gpui::{App, DismissEvent, Entity, FocusHandle, Focusable, Task, WeakEntity}; use picker::{Picker, PickerDelegate}; use ui::{ListItem, prelude::*}; -use crate::context_picker::{ConfirmBehavior, ContextPicker}; +use crate::context_picker::ContextPicker; use crate::context_store::{self, ContextStore}; use crate::thread::ThreadId; use crate::thread_store::ThreadStore; @@ -20,16 +20,11 @@ impl ThreadContextPicker { thread_store: WeakEntity, context_picker: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, window: &mut Window, cx: &mut Context, ) -> Self { - let delegate = ThreadContextPickerDelegate::new( - thread_store, - context_picker, - context_store, - confirm_behavior, - ); + let delegate = + ThreadContextPickerDelegate::new(thread_store, context_picker, context_store); let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx)); ThreadContextPicker { picker } @@ -58,7 +53,6 @@ pub struct ThreadContextPickerDelegate { thread_store: WeakEntity, context_picker: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, matches: Vec, selected_index: usize, } @@ -68,13 +62,11 @@ impl ThreadContextPickerDelegate { thread_store: WeakEntity, context_picker: WeakEntity, context_store: WeakEntity, - confirm_behavior: ConfirmBehavior, ) -> Self { ThreadContextPickerDelegate { thread_store, context_picker, context_store, - confirm_behavior, matches: Vec::new(), selected_index: 0, } @@ -127,7 +119,7 @@ impl PickerDelegate for ThreadContextPickerDelegate { }) } - fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context>) { + fn confirm(&mut self, _secondary: bool, _window: &mut Window, cx: &mut Context>) { let Some(entry) = self.matches.get(self.selected_index) else { return; }; @@ -138,20 +130,15 @@ impl PickerDelegate for ThreadContextPickerDelegate { let open_thread_task = thread_store.update(cx, |this, cx| this.open_thread(&entry.id, cx)); - cx.spawn_in(window, async move |this, cx| { + cx.spawn(async move |this, cx| { let thread = open_thread_task.await?; - this.update_in(cx, |this, window, cx| { + this.update(cx, |this, cx| { this.delegate .context_store .update(cx, |context_store, cx| { context_store.add_thread(thread, true, cx) }) .ok(); - - match this.delegate.confirm_behavior { - ConfirmBehavior::KeepOpen => {} - ConfirmBehavior::Close => this.delegate.dismissed(window, cx), - } }) }) .detach_and_log_err(cx); diff --git a/crates/agent/src/context_strip.rs b/crates/agent/src/context_strip.rs index afc61f46ce..6245f88998 100644 --- a/crates/agent/src/context_strip.rs +++ b/crates/agent/src/context_strip.rs @@ -15,7 +15,7 @@ use ui::{KeyBinding, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*}; use workspace::{Workspace, notifications::NotifyResultExt}; use crate::context::{ContextId, ContextKind}; -use crate::context_picker::{ConfirmBehavior, ContextPicker}; +use crate::context_picker::ContextPicker; use crate::context_store::ContextStore; use crate::thread::Thread; use crate::thread_store::ThreadStore; @@ -52,7 +52,6 @@ impl ContextStrip { workspace.clone(), thread_store.clone(), context_store.downgrade(), - ConfirmBehavior::KeepOpen, window, cx, ) diff --git a/crates/agent/src/message_editor.rs b/crates/agent/src/message_editor.rs index 81adea8945..95870897f1 100644 --- a/crates/agent/src/message_editor.rs +++ b/crates/agent/src/message_editor.rs @@ -10,8 +10,8 @@ use editor::{ use file_icons::FileIcons; use fs::Fs; use gpui::{ - Animation, AnimationExt, App, DismissEvent, Entity, Focusable, Subscription, TextStyle, - WeakEntity, linear_color_stop, linear_gradient, point, pulsating_between, + Animation, AnimationExt, App, Entity, Focusable, Subscription, TextStyle, WeakEntity, + linear_color_stop, linear_gradient, point, pulsating_between, }; use language::{Buffer, Language}; use language_model::{ConfiguredModel, LanguageModelRegistry}; @@ -21,12 +21,12 @@ use project::Project; use settings::Settings; use std::time::Duration; use theme::ThemeSettings; -use ui::{Disclosure, KeyBinding, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*}; +use ui::{Disclosure, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*}; use util::ResultExt as _; use workspace::Workspace; use crate::assistant_model_selector::AssistantModelSelector; -use crate::context_picker::{ConfirmBehavior, ContextPicker, ContextPickerCompletionProvider}; +use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider}; use crate::context_store::{ContextStore, refresh_context_store_text}; use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind}; use crate::profile_selector::ProfileSelector; @@ -46,8 +46,6 @@ pub struct MessageEditor { context_store: Entity, context_strip: Entity, context_picker_menu_handle: PopoverMenuHandle, - inline_context_picker: Entity, - inline_context_picker_menu_handle: PopoverMenuHandle, model_selector: Entity, profile_selector: Entity, edits_expanded: bool, @@ -69,7 +67,6 @@ impl MessageEditor { cx: &mut Context, ) -> Self { let context_picker_menu_handle = PopoverMenuHandle::default(); - let inline_context_picker_menu_handle = PopoverMenuHandle::default(); let model_selector_menu_handle = PopoverMenuHandle::default(); let language = Language::new( @@ -112,17 +109,6 @@ impl MessageEditor { )))); }); - let inline_context_picker = cx.new(|cx| { - ContextPicker::new( - workspace.clone(), - Some(thread_store.clone()), - context_store.downgrade(), - ConfirmBehavior::Close, - window, - cx, - ) - }); - let context_strip = cx.new(|cx| { ContextStrip::new( context_store.clone(), @@ -135,14 +121,8 @@ impl MessageEditor { ) }); - let subscriptions = vec![ - cx.subscribe_in( - &inline_context_picker, - window, - Self::handle_inline_context_picker_event, - ), - cx.subscribe_in(&context_strip, window, Self::handle_context_strip_event), - ]; + let subscriptions = + vec![cx.subscribe_in(&context_strip, window, Self::handle_context_strip_event)]; Self { editor: editor.clone(), @@ -152,8 +132,6 @@ impl MessageEditor { context_store, context_strip, context_picker_menu_handle, - inline_context_picker, - inline_context_picker_menu_handle, model_selector: cx.new(|cx| { AssistantModelSelector::new( fs.clone(), @@ -316,17 +294,6 @@ impl MessageEditor { .detach(); } - fn handle_inline_context_picker_event( - &mut self, - _inline_context_picker: &Entity, - _event: &DismissEvent, - window: &mut Window, - cx: &mut Context, - ) { - let editor_focus_handle = self.editor.focus_handle(cx); - window.focus(&editor_focus_handle); - } - fn handle_context_strip_event( &mut self, _context_strip: &Entity, @@ -346,9 +313,7 @@ impl MessageEditor { } fn move_up(&mut self, _: &MoveUp, window: &mut Window, cx: &mut Context) { - if self.context_picker_menu_handle.is_deployed() - || self.inline_context_picker_menu_handle.is_deployed() - { + if self.context_picker_menu_handle.is_deployed() { cx.propagate(); } else { self.context_strip.focus_handle(cx).focus(window); @@ -385,8 +350,6 @@ impl Render for MessageEditor { let line_height = font_size.to_pixels(window.rem_size()) * 1.5; let focus_handle = self.editor.focus_handle(cx); - let focus_handle_clone = focus_handle.clone(); - let inline_context_picker = self.inline_context_picker.clone(); let is_editor_expanded = self.editor_is_expanded; let expand_icon = if is_editor_expanded { @@ -716,8 +679,9 @@ impl Render for MessageEditor { IconButton::new("toggle-height", expand_icon) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) - .tooltip(move |window, cx| { + .tooltip({ let focus_handle = focus_handle.clone(); + move |window, cx| { let expand_label = if is_editor_expanded { "Minimize Message Editor".to_string() } else { @@ -731,7 +695,7 @@ impl Render for MessageEditor { window, cx, ) - }) + }}) .on_click(cx.listener(|_, _, window, cx| { window.dispatch_action(Box::new(ExpandMessageEditor), cx); })) @@ -766,23 +730,6 @@ impl Render for MessageEditor { }, ).into_any() })) - .child( - PopoverMenu::new("inline-context-picker") - .menu(move |window, cx| { - inline_context_picker.update(cx, |this, cx| { - this.init(window, cx); - }); - Some(inline_context_picker.clone()) - }) - .attach(gpui::Corner::TopLeft) - .anchor(gpui::Corner::BottomLeft) - .offset(gpui::Point { - x: px(0.0), - y: (-ThemeSettings::get_global(cx).ui_font_size(cx) * 2) - - px(4.0), - }) - .with_handle(self.inline_context_picker_menu_handle.clone()), - ) .child( h_flex() .flex_none() @@ -791,7 +738,9 @@ impl Render for MessageEditor { .child( h_flex().gap_1() .child(self.model_selector.clone()) - .map(move |parent| { + .map({ + let focus_handle = focus_handle.clone(); + move |parent| { if is_generating { parent.child( IconButton::new("stop-generation", IconName::StopFilled) @@ -806,7 +755,7 @@ impl Render for MessageEditor { ) }) .on_click({ - let focus_handle = focus_handle_clone.clone(); + let focus_handle = focus_handle.clone(); move |_event, window, cx| { focus_handle.dispatch_action( &editor::actions::Cancel, @@ -834,7 +783,7 @@ impl Render for MessageEditor { || self.waiting_for_summaries_to_send ) .on_click({ - let focus_handle = focus_handle_clone.clone(); + let focus_handle = focus_handle.clone(); move |_event, window, cx| { focus_handle.dispatch_action(&Chat, window, cx); } @@ -861,7 +810,9 @@ impl Render for MessageEditor { }) ) } - }) + } + } + ) ), ), )