fix(tui): input wrap width mismatch — last letter no longer flickers

The 'columns' prop passed to TextInput was cols - pw, but the actual
render width is cols - pw - 2 (NoSelect's paddingX={1} on each side
subtracts two cols from the composer area). cursorLayout thought it
had two extra cols, so wrap-ansi wrapped at render col N while the
declared cursor sat at col N+2 on the same row. The render and the
declared cursor disagreed right at the wrap boundary — the last
letter of a sentence spanning two lines flickered in/out as each
keystroke flipped which cell the cursor claimed.

Also polish the /help hotkeys panel — the !cmd / {!cmd} placeholders
read as literal commands to type, so show them with angle-bracket
syntax and a concrete example (blitz row 5 sub-item 4).
This commit is contained in:
Brooklyn Nicholson 2026-04-22 14:40:54 -05:00
parent a7cc903bf5
commit 88993a468f
2 changed files with 10 additions and 3 deletions

View file

@ -216,8 +216,15 @@ const ComposerPane = memo(function ComposerPane({
</Box>
<Box flexGrow={1} position="relative">
{/*
Subtract the NoSelect paddingX={1} (2 cols total) and the
prompt-glyph column (pw) so cursorLayout agrees with the
width wrap-ansi actually uses at render time. Off-by-one/
two here manifests as the final letter flickering
in/out when a sentence crosses the wrap boundary.
*/}
<TextInput
columns={Math.max(20, composer.cols - pw)}
columns={Math.max(20, composer.cols - pw - 2)}
onChange={composer.updateInput}
onPaste={composer.handleTextPaste}
onSubmit={composer.submit}

View file

@ -24,6 +24,6 @@ export const HOTKEYS: [string, string][] = [
['Home/End', 'start / end of line'],
['Shift+Enter / Alt+Enter', 'insert newline'],
['\\+Enter', 'multi-line continuation (fallback)'],
['!cmd', 'run shell command'],
['{!cmd}', 'interpolate shell output inline']
['!<cmd>', 'run a shell command (e.g. !ls, !git status)'],
['{!<cmd>}', 'interpolate shell output inline (e.g. "branch is {!git branch --show-current}")']
]