Skip to content

Fix/prompt cancel handling#15

Closed
blipinsk wants to merge 4 commits intomainfrom
fix/prompt-cancel-handling
Closed

Fix/prompt cancel handling#15
blipinsk wants to merge 4 commits intomainfrom
fix/prompt-cancel-handling

Conversation

@blipinsk
Copy link
Copy Markdown
Member

No description provided.

Terminals using the Kitty keyboard protocol (Ghostty, Kitty, WezTerm)
send Ctrl+C and ESC as escape sequences rather than raw signals. The
existing stdin reading (fmt.Scanln, bufio.ReadString) blocked waiting
for a newline and never processed these, leaving users stuck.

Add internal/prompt package that reads stdin in raw terminal mode,
handling Ctrl+C (0x03) and standalone ESC (0x1b) as cancel. Arrow keys
and other escape sequences are detected via a 50ms lookahead and
discarded rather than triggering cancel. Multi-byte UTF-8 input is
consumed cleanly. Falls back to buffered line reading when stdin is
piped (tests).

Replace all 9 fmt.Scanln/bufio.ReadString call sites in cmd/root.go
and internal/mob/init.go with the new prompt.ReadLine/Confirm functions.
- pickMob: handle ErrCancelled with "Cancelled." message instead of
  propagating as an error. main.go exits cleanly (code 0) on ErrCancelled.
- ESC detection: 50ms lookahead distinguishes standalone ESC from arrow
  key / escape sequences. Added comment about orphaned goroutine safety.
- Remove unused fd parameter from isStandaloneEsc and drainSequence.
- UTF-8 multi-byte input: emit terminal bell on discard so the user
  gets feedback that the character was rejected.
drainSequence had a race with the goroutine in isStandaloneEsc: the
goroutine closed the channel after sending one byte, so drainSequence
could see a closed channel and return before consuming the full
sequence, leaking terminator bytes (e.g. arrow up leaked 'A').
Fix: goroutine only reads the first byte after ESC; drainSequence
reads remaining bytes directly from stdin.

readLineFallback created a new bufio.Reader per call, so its internal
buffer swallowed all remaining piped input on the first read. Chained
ReadLine calls (e.g. setupRepo prompts) got EOF on the second and
third call. Fix: use a package-level reader initialized lazily on
first use.
The goroutine-based ESC sequence detection and UTF-8 continuation byte
handling were overengineered for short prompts (mob names, y/n). Revert
to treating any 0x1b byte as cancel - arrow keys also cancel, which is
fine for the inputs we accept. Non-ASCII bytes are silently ignored by
the default case.
@blipinsk
Copy link
Copy Markdown
Member Author

im unsure about this one, i think i was trying to optimize some ghostty bug

@blipinsk
Copy link
Copy Markdown
Member Author

this issue is almost certainly fixed by #24

@blipinsk blipinsk closed this Mar 26, 2026
@blipinsk blipinsk deleted the fix/prompt-cancel-handling branch March 26, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant