feat(tui-designer): add line input mode pattern and gotchas

New section covering read_line() for text input in raw-mode TUI,
with implementation pattern and 5 gotchas from real usage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andrew Yim
2026-03-20 23:43:02 +09:00
parent 1fe6f71751
commit e2919eef18

View File

@@ -169,6 +169,46 @@ selector = ListSelector(
- Sections headers group items visually - Sections headers group items visually
- Callable headers re-evaluate on each render (for dynamic "Active:" display) - Callable headers re-evaluate on each render (for dynamic "Active:" display)
## Line Input Mode
For screens requiring text input (file paths, names, search), use `read_line()`:
```python
from myapp.tui.input import read_line
# In a key_handler:
def handle_my_key(app, key):
if key == "p":
app.console.print("Enter file path: ", end="")
path = read_line()
if path is None: # Escape pressed
return True
# Use the path...
return True
```
### Implementation pattern
```python
def read_line(prompt: str = "") -> str | None:
"""Read a full line in raw mode. Returns None on Escape/Ctrl-C."""
# Uses tty.setraw() same as read_key()
# Accumulates chars in buffer, prints each as typed
# Handles: Enter (return string), Escape (return None),
# Ctrl-C (return None), Backspace (delete last)
# Escape sequences (arrow keys pressed during input) are consumed and ignored
```
### Line Input Gotchas
| Gotcha | Problem | Fix |
|--------|---------|-----|
| Pasted paths with quotes | Users paste `'/path/to/file'` with quotes | Strip outer quotes: `path.strip("'\"")` |
| Tilde expansion | `~/.config/...` not expanded | Use `Path(path).expanduser()` |
| Raw mode echo | Characters not visible while typing | Manually `sys.stdout.write(ch)` each keystroke |
| Escape during input | Arrow keys produce garbage in buffer | Detect `0x1B`, consume rest of sequence, ignore |
| Module-level imports for testability | `import select` inside function can't be patched | Import `select`, `termios`, `tty` at module level (in `try/except`) |
## Bilingual i18n ## Bilingual i18n
Simple dict registry — no framework needed: Simple dict registry — no framework needed: