Skip to content

chat: the question's own-answer box answers none of the standard text-editing chords (⌘←/→, ⌘⌫, word kill), and the surface's boxes do not share one editing vocabulary #1013

Description

@santoshkumarradha

What happened

On dev@e61f57a82 (2026-09-12), typing an answer into a question's own box — the something else… row on the question block — the standard macOS text-editing keys do nothing. ⌘←/⌘→ do not reach the ends of the line, ⌘⌫ does not kill to the start of the line, and ⌥⌫/ctrl+⌫ does not delete a word. The only way to remove text is one character at a time, so a long answer cannot be cleared in one gesture.

That box routes its keys by hand, and what it binds is a short list:

// internal/tui3/question.go — questionOtherKey
case "left", "ctrl+b":            box.left()
case "right", "ctrl+f":           box.right()
case "home", "ctrl+a":            box.home()
case "end", "ctrl+e":             box.end()
case "alt+left", "alt+b":         box.wordLeft()
case "alt+right", "alt+f":        box.wordRight()
case "backspace":                 box.deleteBackward()
case "delete":                    box.deleteForward()

Nothing there answers super+left/super+right/meta+left/meta+right (⌘←/⌘→), super+backspace (⌘⌫), alt+backspace/ctrl+backspace (⌥⌫, the word kill), ctrl+u, ctrl+z, shift+-selection or ctrl+a-style select-all.

The same keys DO exist one file over: the main message box's router (app.key in internal/tui3/input.go) binds every one of those spellings, and every other text box is meant to ask the shared table internal/tui3/editkeys.go (editorMotion, editorWordKill, editorUndo) before reading its own switch. That table's own header says why:

what was scattered was the KEY MAP, hand-rolled per box, and a hand-rolled map is a map that forgets.

This box is one that forgot.

Replication

Deterministic (no model). The box's keys are a pure function of the keypress, so a internal/tui3 unit test is enough: build the block's questionOther.words editor, point the pointer at the something else… row, and feed it a tea.KeyPressMsg spelled super+left, super+backspace and alt+backspace. TODAY the caret does not move and no text is deleted; on left/alt+left it does. Same fact by hand, on any terminal: run aforge (dev@e61f57a82), raise a question with a something else… row, walk onto it, type a sentence, press ⌘⌫ and ⌥⌫ — nothing is deleted.

Terminal nuance, and it is the reason this reads as "no keys at all". A -modified chord only reaches the process on a terminal that reports the modifier (kitty protocol / modifyOtherKeys); on a plain macOS profile the terminal never sends the byte. So the message box also has the hole in practice, profile by profile. The question's own-answer box has it regardless of profile, because it does not handle the key even where the terminal does send it.

Where

  • internal/tui3/question.goquestionOtherKey, the hand-rolled switch (its box is questionOther.words, documented as "the surface's own one-line editor, so the caret, the word jumps and the undo stack are the ones every other box on this surface has" — which is the claim that is not true).
  • The vocabulary it does not use: internal/tui3/editkeys.go (editorMotion, editorWordKill, editorUndo) and the editor motions in internal/tui3/input.go.
  • Boxes that DO call the shared helpers today: home.go, homeexchange.go, palette.go, place_tasks.go, rewindsheet.go, settings.go.
  • Boxes that hand-roll and do not call editkeys at all (grep -c 'editorMotion\|editorWordKill\|editorUndo' = 0): the question's own-answer box, steersend.go, recipient.go, connect.go, deliverables.go, connectpanel.go, folderpick.go, subharness.go, place_memory.go.
  • Manual page that would have to agree: internal/manual/chat/questions.md.

The fix

No implementation is proposed here — this is filed as a report, and the shape of the answer is the owner's call. What should be true of the product:

  • Every box a person types into answers the same editing keys a hand already knows: ⌘←/⌘→ at the line's ends, ⌥←/⌥→ a word at a time, ⌘⌫ kill to line start, ⌥⌫/ctrl+⌫ kill a word, undo, select-all — under every spelling the terminals on this machine actually send.
  • There is one editing vocabulary rather than one per box, so a key that works in the message box works in the question's own-answer box, in the errand composer, in every filter and in every panel.
  • Where a given terminal cannot deliver a chord at all, the surface says so once rather than leaving a key silently dead.

Acceptance

  • e2e / unit: the question's own-answer box, the message box and one filter box each answer super+left, super+right, super+backspace, alt+backspace, ctrl+backspace, ctrl+u and ctrl+z — the caret lands on the line's end, the word/line is deleted, the edit is undone — asserted on the editor's value and cursor, not on a test existing.
  • e2e: a control — the same box still types ordinary text, still sends on enter, and esc/ keep the meanings the block gives them (the box owns only the keys that are not its grammar).
  • Unit: a structural law that every editor on the surface reads the shared vocabulary before its own switch — the way editkeys.go already frames it — so a box added later cannot quietly omit the chords.
  • The manual page for the question's own-answer box quotes the keys it now answers, and the change entry's invalidates names what people believed before.

Drafted with agentfield ai · reviewed and owned by the author

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:chatThe v3 surface a person sits in front of (internal/tui3)bugSomething the code does that it should notsev:seriousWrong or missing behaviour a person meets in ordinary use

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions