From 530690734d636ea62d6092f4adad1278fe6d7d1b Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 6 Nov 2025 12:58:52 -0300 Subject: [PATCH] feat(ui): ctrl+l/ctrl+m to open model switcher (#1274) Signed-off-by: Carlos Alexandro Becker --- .../components/dialogs/commands/commands.go | 1 + internal/tui/keys.go | 5 +++++ internal/tui/page/chat/chat.go | 10 ++++++++- internal/tui/tui.go | 21 +++++++++++++++---- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/internal/tui/components/dialogs/commands/commands.go b/internal/tui/components/dialogs/commands/commands.go index 137b20a87e9313281a36d679b09794458b898591..dfe1cd6ade60da7494eab99ede1f104aa045141a 100644 --- a/internal/tui/components/dialogs/commands/commands.go +++ b/internal/tui/components/dialogs/commands/commands.go @@ -335,6 +335,7 @@ func (c *commandDialogCmp) defaultCommands() []Command { ID: "switch_model", Title: "Switch Model", Description: "Switch to a different model", + Shortcut: "ctrl+l", Handler: func(cmd Command) tea.Cmd { return util.CmdHandler(SwitchModelMsg{}) }, diff --git a/internal/tui/keys.go b/internal/tui/keys.go index 1d3d93cea77e91635bbeb1629bc8bce008496611..bee9a3063ed375819298e01098524f15247ba280 100644 --- a/internal/tui/keys.go +++ b/internal/tui/keys.go @@ -9,6 +9,7 @@ type KeyMap struct { Help key.Binding Commands key.Binding Suspend key.Binding + Models key.Binding Sessions key.Binding pageBindings []key.Binding @@ -32,6 +33,10 @@ func DefaultKeyMap() KeyMap { key.WithKeys("ctrl+z"), key.WithHelp("ctrl+z", "suspend"), ), + Models: key.NewBinding( + key.WithKeys("ctrl+l", "ctrl+m"), + key.WithHelp("ctrl+l", "models"), + ), Sessions: key.NewBinding( key.WithKeys("ctrl+s"), key.WithHelp("ctrl+s", "sessions"), diff --git a/internal/tui/page/chat/chat.go b/internal/tui/page/chat/chat.go index c478701e5ce702703a008e2cf18c0e20fdc36cc4..966bd9f230466f22da8d203f7562b39158c31c5b 100644 --- a/internal/tui/page/chat/chat.go +++ b/internal/tui/page/chat/chat.go @@ -942,11 +942,18 @@ func (p *chatPage) Help() help.KeyMap { key.WithKeys("ctrl+p"), key.WithHelp("ctrl+p", "commands"), ) + modelsBinding := key.NewBinding( + key.WithKeys("ctrl+m", "ctrl+l"), + key.WithHelp("ctrl+l", "models"), + ) + if p.keyboardEnhancements.SupportsKeyDisambiguation() { + modelsBinding.SetHelp("ctrl+m", "models") + } helpBinding := key.NewBinding( key.WithKeys("ctrl+g"), key.WithHelp("ctrl+g", "more"), ) - globalBindings = append(globalBindings, commandsBinding) + globalBindings = append(globalBindings, commandsBinding, modelsBinding) globalBindings = append(globalBindings, key.NewBinding( key.WithKeys("ctrl+s"), @@ -963,6 +970,7 @@ func (p *chatPage) Help() help.KeyMap { shortList = append(shortList, // Commands commandsBinding, + modelsBinding, ) fullList = append(fullList, globalBindings) diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 25636206b0b147a20e896e8ca8c75935a7e0f265..ecc66ee03ac35b468088f9e3d910cbd330c94df8 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -127,6 +127,9 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } return a, nil case tea.KeyboardEnhancementsMsg: + if msg.SupportsKeyDisambiguation() { + a.keyMap.Models.SetHelp("ctrl+m", "models") + } for id, page := range a.pages { m, pageCmd := page.Update(msg) a.pages[id] = m @@ -477,6 +480,20 @@ func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd { return util.CmdHandler(dialogs.OpenDialogMsg{ Model: commands.NewCommandDialog(a.selectedSessionID), }) + case key.Matches(msg, a.keyMap.Models): + // if the app is not configured show no models + if !a.isConfigured { + return nil + } + if a.dialog.ActiveDialogID() == models.ModelsDialogID { + return util.CmdHandler(dialogs.CloseDialogMsg{}) + } + if a.dialog.HasDialogs() { + return nil + } + return util.CmdHandler(dialogs.OpenDialogMsg{ + Model: models.NewModelDialogCmp(), + }) case key.Matches(msg, a.keyMap.Sessions): // if the app is not configured show no sessions if !a.isConfigured { @@ -489,10 +506,6 @@ func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd { return nil } var cmds []tea.Cmd - if a.dialog.ActiveDialogID() == commands.CommandsDialogID { - // If the commands dialog is open, close it first - cmds = append(cmds, util.CmdHandler(dialogs.CloseDialogMsg{})) - } cmds = append(cmds, func() tea.Msg { allSessions, _ := a.app.Sessions.List(context.Background())