Skip to main content

Module input_state

Module input_state 

Source
Expand description

Simple multi-line input state management

Replaces tui-textarea with a lightweight implementation for the rolling terminal interface.

§Cursor indexing model (read this before editing)

cursor_col is a character index — a count of Unicode scalar values into the current line — and never a byte offset. Every method in this file must agree on that, and the renderer counts characters too.

This file previously mixed the two: insert_char, insert_newline, delete_char, delete_char_forward and delete_to_end_of_line treated cursor_col as a byte offset while the word-movement and word-delete methods treated it as a character index. That is a crash, not a style problem: typing я once leaves cursor_col = 1 on a line that is 2 bytes long, and the second keystroke calls String::insert(1, …) in the middle of a UTF-8 sequence, which panics. Any accented Latin letter, any CJK character and any emoji did it, in the box the user types into.

Character index rather than byte index because cursor_col is what Left/Right move by: one keypress should traverse one thing the user sees, and a byte is not one.

Known limitation of character (rather than grapheme cluster) semantics: a multi-codepoint grapheme — a flag (🇺🇸 = 2 scalars), a family emoji joined with ZWJ, a skin-tone modifier, or combining accents — takes one keypress per scalar to cross or erase. That is a cosmetic annoyance; it cannot panic, because every scalar boundary is also a valid UTF-8 boundary. Moving to grapheme semantics means adding a segmentation dependency and changing only these helpers, not the call sites.

Structs§

InputState
Multi-line input state with cursor management

Enums§

Direction
Direction for cursor movement