feat(tui): create loom-tui crate scaffold with crossterm lifecycle #48

Merged
charles merged 1 commit from tui/scaffold-11 into main 2026-04-11 20:41:12 +00:00
Owner

Summary

First step of the loom-tui initiative. Adds a new binary crate loom-tui wired into the workspace so subsequent tickets have a place to land and can assume a running ratatui app.

Closes charles/loom#11. Tracked under #47.

What's in this PR

  • New workspace member crates/loom-tui/ with loom-tui binary (edition 2024)
  • Workspace deps: color-eyre added; crossterm picks up event-stream; tokio picks up signal
  • Terminal lifecycle (src/terminal.rs): alt-screen + raw mode + mouse capture + focus events on init, matching teardown on restore, panic hook that restores the terminal before propagating
  • Minimal App event loop (src/app.rs): tokio::select! over crossterm::EventStream and a SIGTERM/SIGINT listener installed once up front, redrawing after every event, exits cleanly on q or Ctrl+C
  • Renders an empty bordered frame with "loom-tui" centered so the crate is visually alive
  • Pre-declared empty feature modules per spec §1.1: event, screens, components, image, keybinds, config — follow-up tickets fill them

Out of scope (follow-up tickets in the v0.1.0 milestone)

  • Image rendering subsystem — #12 Kitty, #13 sixel, #14 chafa, #15 auto-detect
  • Unified event loop + screen state machine — #16
  • Sidebar, status bar, layout — #17
  • Command palette — #18
  • Configurable keybinds — #19
  • tui.toml config file — #43
  • CI wiring (just run-tui) — #44

Test plan

  • cargo build -p loom-tui succeeds
  • cargo clippy -p loom-tui -- -D warnings passes
  • cargo test -p loom-tui (no tests yet, added by #46) exits 0
  • just qa passes (all 85 existing loom-gtk tests still green)
  • Manual: cargo run -p loom-tui launches, shows the frame, q exits cleanly, terminal restored

Notes

Signal handling quirk worth flagging for review: the SIGTERM/SIGINT listeners are installed once before entering select! (see Shutdown::install) rather than re-created each iteration — recreating the listener each loop leaves a race window where the default disposition can kill the process during drop/reinstall.

## Summary First step of the loom-tui initiative. Adds a new binary crate `loom-tui` wired into the workspace so subsequent tickets have a place to land and can assume a running ratatui app. Closes charles/loom#11. Tracked under #47. ## What's in this PR - New workspace member `crates/loom-tui/` with `loom-tui` binary (edition 2024) - Workspace deps: `color-eyre` added; `crossterm` picks up `event-stream`; `tokio` picks up `signal` - Terminal lifecycle (`src/terminal.rs`): alt-screen + raw mode + mouse capture + focus events on init, matching teardown on restore, panic hook that restores the terminal before propagating - Minimal `App` event loop (`src/app.rs`): `tokio::select!` over `crossterm::EventStream` and a SIGTERM/SIGINT listener installed once up front, redrawing after every event, exits cleanly on `q` or `Ctrl+C` - Renders an empty bordered frame with "loom-tui" centered so the crate is visually alive - Pre-declared empty feature modules per spec §1.1: `event`, `screens`, `components`, `image`, `keybinds`, `config` — follow-up tickets fill them ## Out of scope (follow-up tickets in the v0.1.0 milestone) - Image rendering subsystem — #12 Kitty, #13 sixel, #14 chafa, #15 auto-detect - Unified event loop + screen state machine — #16 - Sidebar, status bar, layout — #17 - Command palette — #18 - Configurable keybinds — #19 - `tui.toml` config file — #43 - CI wiring (`just run-tui`) — #44 ## Test plan - [x] `cargo build -p loom-tui` succeeds - [x] `cargo clippy -p loom-tui -- -D warnings` passes - [x] `cargo test -p loom-tui` (no tests yet, added by #46) exits 0 - [x] `just qa` passes (all 85 existing loom-gtk tests still green) - [ ] Manual: `cargo run -p loom-tui` launches, shows the frame, `q` exits cleanly, terminal restored ## Notes Signal handling quirk worth flagging for review: the SIGTERM/SIGINT listeners are installed **once** before entering `select!` (see `Shutdown::install`) rather than re-created each iteration — recreating the listener each loop leaves a race window where the default disposition can kill the process during drop/reinstall.
feat(tui): create loom-tui crate scaffold with crossterm lifecycle
All checks were successful
QA / qa (pull_request) Successful in 27m24s
ec5f5433d8
Add a new binary crate `loom-tui` wired into the workspace so subsequent
loom-tui tickets have a place to land. Handles the terminal lifecycle
(alt-screen, raw mode, mouse capture, focus events), installs a panic
hook that restores the terminal before propagating, and runs a minimal
`App` event loop that listens for keyboard input and SIGTERM/SIGINT via
tokio signal handlers installed once for the lifetime of the loop. The
UI renders an empty bordered frame with "loom-tui" centered and exits
cleanly on `q` or Ctrl+C.

Pre-declares the empty feature modules (`event`, `screens`, `components`,
`image`, `keybinds`, `config`) per spec §1.1 so later PRs can slot into
a stable module tree.

Closes charles/loom#11

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
charles deleted branch tui/scaffold-11 2026-04-11 20:41:12 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom!48
No description provided.