diff --git a/internal/ui/dialog/commands.go b/internal/ui/dialog/commands.go index 6e17db70d0..b1f7900858 100644 --- a/internal/ui/dialog/commands.go +++ b/internal/ui/dialog/commands.go @@ -531,7 +531,7 @@ func (c *Commands) defaultCommands() []*CommandItem { commands = append( commands, - NewCommandItem(c.com.Styles, "quit", "Quit", "ctrl+c", tea.QuitMsg{}).WithAliases("exit"), + NewCommandItem(c.com.Styles, "quit", "Quit", "ctrl+q", tea.QuitMsg{}).WithAliases("exit"), ) return commands diff --git a/internal/ui/dialog/quit.go b/internal/ui/dialog/quit.go index 531f25bea8..0fee6dbbfd 100644 --- a/internal/ui/dialog/quit.go +++ b/internal/ui/dialog/quit.go @@ -43,8 +43,8 @@ func NewQuit(com *common.Common) *Quit { key.WithHelp("enter/space", "confirm"), ) q.keyMap.Yes = key.NewBinding( - key.WithKeys("y", "Y", "ctrl+c"), - key.WithHelp("y/Y/ctrl+c", "yes"), + key.WithKeys("y", "Y", "ctrl+q"), + key.WithHelp("y/Y/ctrl+q", "yes"), ) q.keyMap.No = key.NewBinding( key.WithKeys("n", "N"), @@ -56,8 +56,8 @@ func NewQuit(com *common.Common) *Quit { ) q.keyMap.Close = CloseKey q.keyMap.Quit = key.NewBinding( - key.WithKeys("ctrl+c"), - key.WithHelp("ctrl+c", "quit"), + key.WithKeys("ctrl+q"), + key.WithHelp("ctrl+q", "quit"), ) return q } diff --git a/internal/ui/model/keys.go b/internal/ui/model/keys.go index ebf377035e..27bbd9ffd5 100644 --- a/internal/ui/model/keys.go +++ b/internal/ui/model/keys.go @@ -21,6 +21,10 @@ type KeyMap struct { // History navigation HistoryPrev key.Binding HistoryNext key.Binding + + // Clear current input + ClearInput key.Binding + RestoreInput key.Binding } Chat struct { @@ -70,8 +74,8 @@ type KeyMap struct { func DefaultKeyMap() KeyMap { km := KeyMap{ Quit: key.NewBinding( - key.WithKeys("ctrl+c"), - key.WithHelp("ctrl+c", "quit"), + key.WithKeys("ctrl+q"), + key.WithHelp("ctrl+q", "quit"), ), Help: key.NewBinding( key.WithKeys("ctrl+g"), @@ -156,6 +160,14 @@ func DefaultKeyMap() KeyMap { km.Editor.HistoryNext = key.NewBinding( key.WithKeys("down"), ) + km.Editor.ClearInput = key.NewBinding( + key.WithKeys("ctrl+c"), + key.WithHelp("ctrl+c", "clear input"), + ) + km.Editor.RestoreInput = key.NewBinding( + key.WithKeys("ctrl+u"), + key.WithHelp("ctrl+u", "restore cleared input"), + ) km.Chat.NewSession = key.NewBinding( key.WithKeys("ctrl+n"), diff --git a/internal/ui/model/ui.go b/internal/ui/model/ui.go index 0c6102572c..fa85479a34 100644 --- a/internal/ui/model/ui.go +++ b/internal/ui/model/ui.go @@ -209,6 +209,10 @@ type UI struct { // Editor components textarea textarea.Model + // lastClearedInput stores the most recently cleared input value so it + // can be restored with Editor.RestoreInput (ctrl+shift+c). + lastClearedInput string + // Attachment list attachments *attachments.Attachments @@ -2036,6 +2040,26 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd { if cmd := m.openCommandsDialog(); cmd != nil { cmds = append(cmds, cmd) } + case key.Matches(msg, m.keyMap.Editor.ClearInput): + if m.textarea.Value() != "" { + m.lastClearedInput = m.textarea.Value() + prevHeight := m.textarea.Height() + m.textarea.Reset() + if cmd := m.handleTextareaHeightChange(prevHeight); cmd != nil { + cmds = append(cmds, cmd) + } + } + m.closeCompletions() + case key.Matches(msg, m.keyMap.Editor.RestoreInput): + if m.lastClearedInput != "" { + prevHeight := m.textarea.Height() + m.textarea.SetValue(m.lastClearedInput) + m.textarea.MoveToEnd() + if cmd := m.handleTextareaHeightChange(prevHeight); cmd != nil { + cmds = append(cmds, cmd) + } + m.lastClearedInput = "" + } default: if handleGlobalKeys(msg) { // Handle global keys first before passing to textarea. @@ -2495,6 +2519,8 @@ func (m *UI) FullHelp() [][]key.Binding { case uiFocusEditor: editorBinds := []key.Binding{ k.Editor.Newline, + k.Editor.ClearInput, + k.Editor.RestoreInput, k.Editor.MentionFile, k.Editor.OpenEditor, } @@ -2550,6 +2576,8 @@ func (m *UI) FullHelp() [][]key.Binding { ) editorBinds := []key.Binding{ k.Editor.Newline, + k.Editor.ClearInput, + k.Editor.RestoreInput, k.Editor.MentionFile, k.Editor.OpenEditor, }