feat(tui): delete queued message while editing with ctrl-x / cancel with esc

Today there's no way to remove a queued message — ↑ loads it for edit,
ctrl-K dispatches the head, but a draft you no longer want stays put
forever. ctrl-C just clears the composer and exits edit mode without
touching the queue.

Two new bindings, both gated on queueEditIdx !== null so they're
inert when the user isn't pointing at a queue item:

- ctrl-X — delete the queue item being edited, clear composer, exit
  edit mode.  "cut" matches the mental model and doesn't collide with
  any existing binding.
- esc — cancel the edit (composer clears, item stays in queue).
  Mirrors ctrl-C's existing behavior so muscle memory has two paths.

Header line now reads `queued (3) · editing 2 · ⌃X delete · esc cancel`
when in edit mode, so the affordance is discoverable without /help.
The /help hotkey table also gets a Ctrl+X entry.

ctrl-C is intentionally unchanged: it should never destroy queued
content.  Cancel is non-destructive (esc / ctrl-C); only ctrl-X
removes the item.
This commit is contained in:
Brooklyn Nicholson 2026-04-27 15:24:14 -05:00
parent 4a9ac5c355
commit ea1012f59f
7 changed files with 79 additions and 3 deletions

View file

@ -110,8 +110,18 @@ export function useComposerState({
const isBlocked = useStore($isBlocked)
const { querier } = useStdin() as { querier: Parameters<typeof readOsc52Clipboard>[0] }
const { queueRef, queueEditRef, queuedDisplay, queueEditIdx, enqueue, dequeue, replaceQ, setQueueEdit, syncQueue } =
useQueue()
const {
queueRef,
queueEditRef,
queuedDisplay,
queueEditIdx,
enqueue,
dequeue,
removeQ,
replaceQ,
setQueueEdit,
syncQueue
} = useQueue()
const { historyRef, historyIdx, setHistoryIdx, historyDraftRef, pushHistory } = useInputHistory()
const { completions, compIdx, setCompIdx, compReplace } = useCompletion(input, isBlocked, gw)
@ -294,6 +304,7 @@ export function useComposerState({
handleTextPaste,
openEditor,
pushHistory,
removeQueue: removeQ,
replaceQueue: replaceQ,
setCompIdx,
setHistoryIdx,
@ -310,6 +321,7 @@ export function useComposerState({
handleTextPaste,
openEditor,
pushHistory,
removeQ,
replaceQ,
setCompIdx,
setHistoryIdx,