Skip to content

feat(input): bind Plan 9 arrow-key runes (fixes down-arrow in alacritty9) - #158

Draft
mparrett wants to merge 1 commit into
mainfrom
fix/plan9-arrow-runes
Draft

feat(input): bind Plan 9 arrow-key runes (fixes down-arrow in alacritty9)#158
mparrett wants to merge 1 commit into
mainfrom
fix/plan9-arrow-runes

Conversation

@mparrett

Copy link
Copy Markdown
Collaborator

What

Movement keys bound only the ANSI arrow escapes (ESC[A/B/C/D). This adds Plan 9's kernel arrow runes (Kup U+F00E, Kdown U+F800, Kleft U+F011, Kright U+F012) alongside them, so the arrow keys drive movement on the Plan 9 terminals that deliver runes instead of escapes.

Why it's not cosmetic

Which form a terminal sends isn't uniform, and the gap lands on the main play environment:

  • alacritty9 — where the game is actually played on 9front — sends ANSI for up/left/right, but the raw Kdown rune U+F800 for down. Measured on 9front amd64: without the U+F800 binding, up/left/right move and down does nothing.
  • The bare text console sends all four keys as runes.
  • rio's own windows swallow the arrows for scrollback, so they never reach the program — not something a key binding can address.

The down case is the one that bites: a silent dead key in the primary environment, easy to miss because hjkl and the numpad still move you.

Evidence

Probed on real hardware (9front amd64 + alacritty9) with a read-key codepoint dump, entering the alternate screen the way the game does:

↑  codes=(27 91 65)  ESC[A
↓  codes=(63488)     U+F800   ← Kdown rune, every press
←  codes=(27 91 68)  ESC[D
→  codes=(27 91 67)  ESC[C

The let-go side (read-key tokenizing these on Plan 9) is nooga/let-go#461; this is the xsofy-side binding that consumes them.

Test

input_test.lg covers the rune bindings resolving to the right movement actions.

Closes #157.

…ty9)

Movement bindings carried only the ANSI arrow escapes (ESC[A/B/C/D). On
Plan 9 the arrow keys can arrive as kernel runes instead — Kup U+F00E,
Kdown U+F800, Kleft U+F011, Kright U+F012 — and which form a terminal
sends varies:

- alacritty9 (the main play environment) sends ANSI for up/left/right
  but the raw Kdown rune for DOWN. Measured on 9front: without the U+F800
  binding, down-movement is dead in-game while the other three work.
- the bare text console sends all four as runes.
- rio's own windows swallow the arrows for scrollback (unreachable
  either way).

Bind both forms per direction so movement works wherever a key reaches
us. Adds input_test.lg coverage for the rune bindings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mparrett

Copy link
Copy Markdown
Collaborator Author

Bare-console confirmation: all four runes on real hardware

The PR body measured only the alacritty9 down-arrow; the other three rune values came from keyboard.h. Ran the arrow probe on a bare 9front console (rio exited, raw /dev/cons) and all four match the bindings:

↑  codes=(61454)  U+F00E  Kup
↓  codes=(63488)  U+F800  Kdown
←  codes=(61457)  U+F011  Kleft
→  codes=(61458)  U+F012  Kright

(raw="" because they're Private-Use-Area codepoints with no glyph — the codepoints are the receipt.) Each arrived unbuffered, one rune per press, under consctl raw mode; q quit cleanly with the console back in cooked mode.

So the two device paths together cover every key this binds: the bare console sends all four as runes, and alacritty9 sends ANSI for up/left/right plus the Kdown rune for down.

@mparrett
mparrett marked this pull request as draft July 15, 2026 04:38
@mparrett

mparrett commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Just a hunch, this PR seems like it's trying to fix something that shouldn't be that way in the first place. The "raw Kdown rune U+F800 for down" part smells like a bug rather than something to accommodate here- Not proven, but need to take a deeper look.

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.

Plan 9: arrow keys arrive as kernel runes (down-arrow dead in alacritty9)

1 participant