From 6ab4396800fcef86bb8638a4d76ff3daf35e895d Mon Sep 17 00:00:00 2001 From: bashbunni Date: Wed, 6 Aug 2025 17:44:09 -0700 Subject: [PATCH] feat: add command history navigation --- internal/tui/components/chat/editor/editor.go | 48 +++++++++++++++++++ internal/tui/components/chat/editor/keys.go | 10 ++++ 2 files changed, 58 insertions(+) diff --git a/internal/tui/components/chat/editor/editor.go b/internal/tui/components/chat/editor/editor.go index 4c7df84daad5b911be66dcd7f7cf6d832d714293..9866597dc2916ba458ea5570956e43dda479c381 100644 --- a/internal/tui/components/chat/editor/editor.go +++ b/internal/tui/components/chat/editor/editor.go @@ -67,6 +67,9 @@ type editorCmp struct { currentQuery string completionsStartIndex int isCompletionsOpen bool + + // History + promptHistoryIndex int } var DeleteKeyMaps = DeleteAttachmentKeyMaps{ @@ -314,6 +317,10 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.textarea.InsertRune('\n') cmds = append(cmds, util.CmdHandler(completions.CloseCompletionsMsg{})) } + // History + if key.Matches(msg, m.keyMap.Previous) || key.Matches(msg, m.keyMap.Next) { + m.textarea.SetValue(m.handleMessageHistory(msg)) + } // Handle Enter key if m.textarea.Focused() && key.Matches(msg, m.keyMap.SendMessage) { value := m.textarea.Value() @@ -560,3 +567,44 @@ func New(app *app.App) Editor { return e } + +func (m *editorCmp) getUserMessagesAsText(ctx context.Context) ([]string, error) { + allMessages, err := m.app.Messages.List(ctx, m.session.ID) + if err != nil { + return nil, err + } + + var userMessages []string + for _, msg := range allMessages { + if msg.Role == message.User { + userMessages = append(userMessages, msg.Content().Text) + } + } + return userMessages, nil +} + +func (m *editorCmp) handleMessageHistory(msg tea.KeyMsg) string { + ctx := context.Background() + userMessages, err := m.getUserMessagesAsText(ctx) + if err != nil { + return "" // Do nothing. + } + userMessages = append(userMessages, "") // Give the user a reset option. + if len(userMessages) > 0 { + if key.Matches(msg, m.keyMap.Previous) { + if m.promptHistoryIndex == 0 { + m.promptHistoryIndex = len(userMessages) - 1 + } else { + m.promptHistoryIndex -= 1 + } + } + if key.Matches(msg, m.keyMap.Next) { + if m.promptHistoryIndex == len(userMessages)-1 { + m.promptHistoryIndex = 0 + } else { + m.promptHistoryIndex += 1 + } + } + } + return userMessages[m.promptHistoryIndex] +} diff --git a/internal/tui/components/chat/editor/keys.go b/internal/tui/components/chat/editor/keys.go index 9d2274753b4667031bb43a76f54fce18c1decf51..a2f506d716ff71b8967fa9f67ec00f8ad9ff50c1 100644 --- a/internal/tui/components/chat/editor/keys.go +++ b/internal/tui/components/chat/editor/keys.go @@ -9,6 +9,8 @@ type EditorKeyMap struct { SendMessage key.Binding OpenEditor key.Binding Newline key.Binding + Next key.Binding + Previous key.Binding } func DefaultEditorKeyMap() EditorKeyMap { @@ -32,6 +34,14 @@ func DefaultEditorKeyMap() EditorKeyMap { // to reflect that. key.WithHelp("ctrl+j", "newline"), ), + Next: key.NewBinding( + key.WithKeys("shift+down"), + key.WithHelp("shift+↓", "down"), + ), + Previous: key.NewBinding( + key.WithKeys("shift+up"), + key.WithHelp("shift+↑", "up"), + ), } }