diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 7c84cf035e..ae9b4548b2 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -618,6 +618,7 @@ "ctrl-n": "assistant2::NewThread", "new": "assistant2::NewThread", "ctrl-shift-h": "assistant2::OpenHistory", + "ctrl-i": "assistant2::ToggleProfileSelector", "ctrl-alt-/": "assistant::ToggleModelSelector", "ctrl-shift-a": "assistant2::ToggleContextPicker", "ctrl-e": "assistant2::ChatMode", @@ -635,7 +636,8 @@ { "context": "MessageEditor > Editor", "bindings": { - "enter": "assistant2::Chat" + "enter": "assistant2::Chat", + "ctrl-i": "assistant2::ToggleProfileSelector" } }, { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index b6c04ca8b0..6701bfeb84 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -269,6 +269,7 @@ "cmd-n": "assistant2::NewThread", "cmd-alt-p": "assistant2::NewPromptEditor", "cmd-shift-h": "assistant2::OpenHistory", + "cmd-i": "assistant2::ToggleProfileSelector", "cmd-alt-/": "assistant::ToggleModelSelector", "cmd-shift-a": "assistant2::ToggleContextPicker", "cmd-e": "assistant2::ChatMode", @@ -288,6 +289,7 @@ "use_key_equivalents": true, "bindings": { "enter": "assistant2::Chat", + "cmd-i": "assistant2::ToggleProfileSelector", "cmd-g d": "git::Diff", "shift-escape": "git::ExpandCommitEditor" } diff --git a/crates/assistant2/src/assistant.rs b/crates/assistant2/src/assistant.rs index c90ec19d54..77dd1ab6e2 100644 --- a/crates/assistant2/src/assistant.rs +++ b/crates/assistant2/src/assistant.rs @@ -44,6 +44,7 @@ actions!( NewThread, NewPromptEditor, ToggleContextPicker, + ToggleProfileSelector, RemoveAllContext, OpenHistory, OpenConfiguration, diff --git a/crates/assistant2/src/message_editor.rs b/crates/assistant2/src/message_editor.rs index ed1167f192..6e908b9124 100644 --- a/crates/assistant2/src/message_editor.rs +++ b/crates/assistant2/src/message_editor.rs @@ -29,7 +29,9 @@ use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind}; use crate::profile_selector::ProfileSelector; use crate::thread::{RequestKind, Thread}; use crate::thread_store::ThreadStore; -use crate::{Chat, ChatMode, RemoveAllContext, ThreadEvent, ToggleContextPicker}; +use crate::{ + Chat, ChatMode, RemoveAllContext, ThreadEvent, ToggleContextPicker, ToggleProfileSelector, +}; pub struct MessageEditor { thread: Entity, @@ -135,7 +137,8 @@ impl MessageEditor { cx, ) }), - profile_selector: cx.new(|cx| ProfileSelector::new(fs, thread_store, cx)), + profile_selector: cx + .new(|cx| ProfileSelector::new(fs, thread_store, editor.focus_handle(cx), cx)), _subscriptions: subscriptions, } } @@ -561,6 +564,9 @@ impl Render for MessageEditor { v_flex() .key_context("MessageEditor") .on_action(cx.listener(Self::chat)) + .on_action(cx.listener(|this, _: &ToggleProfileSelector, window, cx| { + this.profile_selector.read(cx).menu_handle().toggle(window, cx); + })) .on_action(cx.listener(|this, _: &ToggleModelSelector, window, cx| { this.model_selector .update(cx, |model_selector, cx| model_selector.toggle(window, cx)); diff --git a/crates/assistant2/src/profile_selector.rs b/crates/assistant2/src/profile_selector.rs index 838b5b0dbe..762e5bee0d 100644 --- a/crates/assistant2/src/profile_selector.rs +++ b/crates/assistant2/src/profile_selector.rs @@ -2,18 +2,20 @@ use std::sync::Arc; use assistant_settings::{AgentProfile, AssistantSettings}; use fs::Fs; -use gpui::{prelude::*, Action, Entity, Subscription, WeakEntity}; +use gpui::{prelude::*, Action, Entity, FocusHandle, Subscription, WeakEntity}; use indexmap::IndexMap; use settings::{update_settings_file, Settings as _, SettingsStore}; -use ui::{prelude::*, ContextMenu, ContextMenuEntry, PopoverMenu, Tooltip}; +use ui::{prelude::*, ContextMenu, ContextMenuEntry, PopoverMenu, PopoverMenuHandle, Tooltip}; use util::ResultExt as _; -use crate::{ManageProfiles, ThreadStore}; +use crate::{ManageProfiles, ThreadStore, ToggleProfileSelector}; pub struct ProfileSelector { profiles: IndexMap, AgentProfile>, fs: Arc, thread_store: WeakEntity, + focus_handle: FocusHandle, + menu_handle: PopoverMenuHandle, _subscriptions: Vec, } @@ -21,6 +23,7 @@ impl ProfileSelector { pub fn new( fs: Arc, thread_store: WeakEntity, + focus_handle: FocusHandle, cx: &mut Context, ) -> Self { let settings_subscription = cx.observe_global::(move |this, cx| { @@ -31,6 +34,8 @@ impl ProfileSelector { profiles: IndexMap::default(), fs, thread_store, + focus_handle, + menu_handle: PopoverMenuHandle::default(), _subscriptions: vec![settings_subscription], }; this.refresh_profiles(cx); @@ -38,6 +43,10 @@ impl ProfileSelector { this } + pub fn menu_handle(&self) -> PopoverMenuHandle { + self.menu_handle.clone() + } + fn refresh_profiles(&mut self, cx: &mut Context) { let settings = AssistantSettings::get_global(cx); @@ -106,7 +115,8 @@ impl Render for ProfileSelector { .unwrap_or_else(|| "Unknown".into()); let this = cx.entity().clone(); - PopoverMenu::new("tool-selector") + let focus_handle = self.focus_handle.clone(); + PopoverMenu::new("profile-selector") .menu(move |window, cx| { Some(this.update(cx, |this, cx| this.build_context_menu(window, cx))) }) @@ -114,8 +124,17 @@ impl Render for ProfileSelector { Button::new("profile-selector-button", profile) .style(ButtonStyle::Filled) .label_size(LabelSize::Small), - Tooltip::text("Change Profile"), + move |window, cx| { + Tooltip::for_action_in( + "Change Profile", + &ToggleProfileSelector, + &focus_handle, + window, + cx, + ) + }, ) .anchor(gpui::Corner::BottomLeft) + .with_handle(self.menu_handle.clone()) } }