assistant2: Add keybinding for profile selector (#27674)
This PR adds a keybinding to toggle the profile selector. Defaults to `Cmd-I` on macOS and `ctrl-I` on Linux/Windows. Release Notes: - N/A
This commit is contained in:
parent
55d934a3be
commit
c8fb95cd1b
5 changed files with 38 additions and 8 deletions
|
@ -618,6 +618,7 @@
|
||||||
"ctrl-n": "assistant2::NewThread",
|
"ctrl-n": "assistant2::NewThread",
|
||||||
"new": "assistant2::NewThread",
|
"new": "assistant2::NewThread",
|
||||||
"ctrl-shift-h": "assistant2::OpenHistory",
|
"ctrl-shift-h": "assistant2::OpenHistory",
|
||||||
|
"ctrl-i": "assistant2::ToggleProfileSelector",
|
||||||
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
||||||
"ctrl-shift-a": "assistant2::ToggleContextPicker",
|
"ctrl-shift-a": "assistant2::ToggleContextPicker",
|
||||||
"ctrl-e": "assistant2::ChatMode",
|
"ctrl-e": "assistant2::ChatMode",
|
||||||
|
@ -635,7 +636,8 @@
|
||||||
{
|
{
|
||||||
"context": "MessageEditor > Editor",
|
"context": "MessageEditor > Editor",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"enter": "assistant2::Chat"
|
"enter": "assistant2::Chat",
|
||||||
|
"ctrl-i": "assistant2::ToggleProfileSelector"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -269,6 +269,7 @@
|
||||||
"cmd-n": "assistant2::NewThread",
|
"cmd-n": "assistant2::NewThread",
|
||||||
"cmd-alt-p": "assistant2::NewPromptEditor",
|
"cmd-alt-p": "assistant2::NewPromptEditor",
|
||||||
"cmd-shift-h": "assistant2::OpenHistory",
|
"cmd-shift-h": "assistant2::OpenHistory",
|
||||||
|
"cmd-i": "assistant2::ToggleProfileSelector",
|
||||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||||
"cmd-shift-a": "assistant2::ToggleContextPicker",
|
"cmd-shift-a": "assistant2::ToggleContextPicker",
|
||||||
"cmd-e": "assistant2::ChatMode",
|
"cmd-e": "assistant2::ChatMode",
|
||||||
|
@ -288,6 +289,7 @@
|
||||||
"use_key_equivalents": true,
|
"use_key_equivalents": true,
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"enter": "assistant2::Chat",
|
"enter": "assistant2::Chat",
|
||||||
|
"cmd-i": "assistant2::ToggleProfileSelector",
|
||||||
"cmd-g d": "git::Diff",
|
"cmd-g d": "git::Diff",
|
||||||
"shift-escape": "git::ExpandCommitEditor"
|
"shift-escape": "git::ExpandCommitEditor"
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ actions!(
|
||||||
NewThread,
|
NewThread,
|
||||||
NewPromptEditor,
|
NewPromptEditor,
|
||||||
ToggleContextPicker,
|
ToggleContextPicker,
|
||||||
|
ToggleProfileSelector,
|
||||||
RemoveAllContext,
|
RemoveAllContext,
|
||||||
OpenHistory,
|
OpenHistory,
|
||||||
OpenConfiguration,
|
OpenConfiguration,
|
||||||
|
|
|
@ -29,7 +29,9 @@ use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||||
use crate::profile_selector::ProfileSelector;
|
use crate::profile_selector::ProfileSelector;
|
||||||
use crate::thread::{RequestKind, Thread};
|
use crate::thread::{RequestKind, Thread};
|
||||||
use crate::thread_store::ThreadStore;
|
use crate::thread_store::ThreadStore;
|
||||||
use crate::{Chat, ChatMode, RemoveAllContext, ThreadEvent, ToggleContextPicker};
|
use crate::{
|
||||||
|
Chat, ChatMode, RemoveAllContext, ThreadEvent, ToggleContextPicker, ToggleProfileSelector,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct MessageEditor {
|
pub struct MessageEditor {
|
||||||
thread: Entity<Thread>,
|
thread: Entity<Thread>,
|
||||||
|
@ -135,7 +137,8 @@ impl MessageEditor {
|
||||||
cx,
|
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,
|
_subscriptions: subscriptions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,6 +564,9 @@ impl Render for MessageEditor {
|
||||||
v_flex()
|
v_flex()
|
||||||
.key_context("MessageEditor")
|
.key_context("MessageEditor")
|
||||||
.on_action(cx.listener(Self::chat))
|
.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| {
|
.on_action(cx.listener(|this, _: &ToggleModelSelector, window, cx| {
|
||||||
this.model_selector
|
this.model_selector
|
||||||
.update(cx, |model_selector, cx| model_selector.toggle(window, cx));
|
.update(cx, |model_selector, cx| model_selector.toggle(window, cx));
|
||||||
|
|
|
@ -2,18 +2,20 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use assistant_settings::{AgentProfile, AssistantSettings};
|
use assistant_settings::{AgentProfile, AssistantSettings};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{prelude::*, Action, Entity, Subscription, WeakEntity};
|
use gpui::{prelude::*, Action, Entity, FocusHandle, Subscription, WeakEntity};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use settings::{update_settings_file, Settings as _, SettingsStore};
|
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 util::ResultExt as _;
|
||||||
|
|
||||||
use crate::{ManageProfiles, ThreadStore};
|
use crate::{ManageProfiles, ThreadStore, ToggleProfileSelector};
|
||||||
|
|
||||||
pub struct ProfileSelector {
|
pub struct ProfileSelector {
|
||||||
profiles: IndexMap<Arc<str>, AgentProfile>,
|
profiles: IndexMap<Arc<str>, AgentProfile>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
thread_store: WeakEntity<ThreadStore>,
|
thread_store: WeakEntity<ThreadStore>,
|
||||||
|
focus_handle: FocusHandle,
|
||||||
|
menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +23,7 @@ impl ProfileSelector {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
thread_store: WeakEntity<ThreadStore>,
|
thread_store: WeakEntity<ThreadStore>,
|
||||||
|
focus_handle: FocusHandle,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let settings_subscription = cx.observe_global::<SettingsStore>(move |this, cx| {
|
let settings_subscription = cx.observe_global::<SettingsStore>(move |this, cx| {
|
||||||
|
@ -31,6 +34,8 @@ impl ProfileSelector {
|
||||||
profiles: IndexMap::default(),
|
profiles: IndexMap::default(),
|
||||||
fs,
|
fs,
|
||||||
thread_store,
|
thread_store,
|
||||||
|
focus_handle,
|
||||||
|
menu_handle: PopoverMenuHandle::default(),
|
||||||
_subscriptions: vec![settings_subscription],
|
_subscriptions: vec![settings_subscription],
|
||||||
};
|
};
|
||||||
this.refresh_profiles(cx);
|
this.refresh_profiles(cx);
|
||||||
|
@ -38,6 +43,10 @@ impl ProfileSelector {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn menu_handle(&self) -> PopoverMenuHandle<ContextMenu> {
|
||||||
|
self.menu_handle.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn refresh_profiles(&mut self, cx: &mut Context<Self>) {
|
fn refresh_profiles(&mut self, cx: &mut Context<Self>) {
|
||||||
let settings = AssistantSettings::get_global(cx);
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
|
||||||
|
@ -106,7 +115,8 @@ impl Render for ProfileSelector {
|
||||||
.unwrap_or_else(|| "Unknown".into());
|
.unwrap_or_else(|| "Unknown".into());
|
||||||
|
|
||||||
let this = cx.entity().clone();
|
let this = cx.entity().clone();
|
||||||
PopoverMenu::new("tool-selector")
|
let focus_handle = self.focus_handle.clone();
|
||||||
|
PopoverMenu::new("profile-selector")
|
||||||
.menu(move |window, cx| {
|
.menu(move |window, cx| {
|
||||||
Some(this.update(cx, |this, cx| this.build_context_menu(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)
|
Button::new("profile-selector-button", profile)
|
||||||
.style(ButtonStyle::Filled)
|
.style(ButtonStyle::Filled)
|
||||||
.label_size(LabelSize::Small),
|
.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)
|
.anchor(gpui::Corner::BottomLeft)
|
||||||
|
.with_handle(self.menu_handle.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue