From 90351066b1593abc75f1eb146378dd30effe40c3 Mon Sep 17 00:00:00 2001 From: patriceckhart Date: Thu, 7 May 2026 19:41:27 +0200 Subject: [PATCH] Recover queued messages with Option+Up Pressing Option+Up while the agent is busy now pops the most recently queued ('sliding in') message back into the editor so the user can edit and resend it. Repeated presses keep peeling messages off the tail of the queue, newest first; each press replaces the editor contents rather than appending. When the queue is empty the keypress falls through to the existing scroll-up behavior. A muted hint row underneath the chips advertises the shortcut, using the same color as the model info on the status bar so it reads as ambient metadata. --- internal/agent/modes/interactive.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/internal/agent/modes/interactive.go b/internal/agent/modes/interactive.go index 10df643..3caab02 100644 --- a/internal/agent/modes/interactive.go +++ b/internal/agent/modes/interactive.go @@ -1001,6 +1001,12 @@ func (i *Interactive) redraw() { text := truncateLine(q, cols-17) queue = append(queue, label+i.cfg.Theme.FG256(i.cfg.Theme.Muted, text)) } + // Hint row, rendered in the same muted tone as the model + // info on the status bar so it reads as ambient metadata + // rather than a chip. Tells the user how to recover the + // most recent queued message back into the editor. + hint := " Press Option+↑ to slide back into input" + queue = append(queue, i.cfg.Theme.FG256(i.cfg.Theme.Muted, hint)) } // Bottom-sticky sections (always visible, never scroll). Each @@ -1728,6 +1734,25 @@ func (i *Interactive) handleKey(ctx context.Context, k tui.Key) (done bool) { i.scrollBy(-i.chatPage()) return false case tui.KeyUp: + // Alt/Option+Up: pop the most recently queued ("sliding in") + // message back into the editor so the user can edit and + // resend it. Repeated presses keep peeling messages off the + // tail of the queue; each press *replaces* the editor + // contents (we don't append/push). When the queue is empty + // the keypress falls through to the normal scroll behavior. + if k.Alt { + i.mu.Lock() + if n := len(i.queued); n > 0 { + text := i.queued[n-1] + i.queued = i.queued[:n-1] + i.mu.Unlock() + i.ed.SetValue(text) + i.inputHistoryIndex = -1 + i.invalidate() + return false + } + i.mu.Unlock() + } // Always use up/down for chat scrolling, even when the editor // contains text. This makes keyboard scrolling consistent with // a draft present at the cost of disabling vertical cursor