feat(ui): ctrl+l/ctrl+m to open model switcher (#1274)

Carlos Alexandro Becker created

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

Change summary

internal/tui/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(-)

Detailed changes

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{})
 			},

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"),

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)
 

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())