Open-Source Wikis

/

Helix

/

Packages

/

helix-tui

helix-editor/helix

helix-tui

Forked from tui-rs, pruned and adapted to Helix's needs. ~5,900 lines of Rust. Sits between helix-view's drawing types (Rect, Style) and the terminal backend.

Purpose

helix-tui provides:

  • Buffer — an off-screen grid of styled Cells that components draw into.
  • Backend — a trait abstracting terminal I/O. Three implementations: termina (Unix), crossterm (Windows), and a TestBackend used by integration tests.
  • Layout — constraint-based rectangle splitting.
  • Widgets — small drawable primitives: Block, Paragraph, Table.
  • Terminal — owns the backend and a double-buffered surface; computes per-frame diffs.

Directory layout

helix-tui/src
├── lib.rs        # re-export Terminal, TerminalOptions, Viewport
├── buffer.rs     # Cell, Buffer (the surface; ~33k chars)
├── layout.rs     # Layout, Constraint, Rect splitting
├── terminal.rs   # Terminal<Backend>: draw cycle, viewport, resize handling
├── text.rs       # Text/Spans/Span (styled text)
├── symbols.rs    # Unicode glyph constants (lines, blocks, dots)
├── backend/
│   ├── mod.rs        # Backend trait
│   ├── termina.rs    # termina backend (Unix); ~26k chars
│   ├── crossterm.rs  # crossterm backend (Windows); ~16k chars
│   └── test.rs       # TestBackend for integration tests
└── widgets/
    ├── mod.rs        # Widget trait
    ├── block.rs      # Bordered box widget
    ├── paragraph.rs  # Word-wrapped text
    ├── reflow.rs     # Soft-wrap implementation used by Paragraph
    └── table.rs      # Table widget (used by file picker, etc.)

Note: list.rs exists in tui-rs upstream but is commented out here — Helix's pickers and menus don't use it.

Key abstractions

Type File Purpose
Cell buffer.rs One terminal cell: symbol (a String), Style, Underline.
Buffer buffer.rs A 2D grid of Cells; the type that Component::render writes into.
Backend (trait) backend/mod.rs Claim/restore terminal, draw a sparse cell stream, control cursor and clear.
Terminal<B> terminal.rs Owns the backend + previous + current Buffer. draw diffs the buffers.
Viewport terminal.rs Full (alternate screen) or Inline { height }.
Rect (re-export from helix-view) helix-view/src/graphics.rs x, y, width, height.
Constraint layout.rs Length, Percentage, Ratio, Min, Max — used to split Rects.
Widget (trait) widgets/mod.rs fn render(self, area: Rect, buf: &mut Buffer).

Render cycle

graph LR
    Comp[Compositor.render] -->|fills| Curr[Buffer current]
    Curr -->|diff vs| Prev[Buffer previous]
    Curr -->|cell deltas| BackendDraw[Backend::draw]
    BackendDraw --> TermIO[Terminal escape sequences]
    Curr -.swap.-> Prev

Terminal::draw (terminal.rs) clears the current buffer, lets the caller paint via a closure, runs Buffer::diff to compute changed cells, sends them through Backend::draw, then swaps the buffers. Only changed cells hit the wire — a typing keystroke usually generates a handful of cell updates rather than a full redraw.

Backends

The backend abstraction allows three concrete implementations:

  • TerminaBackend (backend/termina.rs) — Unix backend using the termina crate. Handles modern features like the kitty keyboard protocol, OSC 52 clipboard, true color, undercurl, and bracketed paste.
  • CrosstermBackend (backend/crossterm.rs) — Windows backend using crossterm ≥ 0.28.
  • TestBackend (backend/test.rs) — in-memory backend used by cargo integration-test. Deterministic sizes and a snapshot of the rendered grid.

The application chooses the backend at compile time via cfg-guards in helix-term/src/application.rs.

Widgets

The Widget trait is small but powerful: the widget consumes itself and writes directly into the buffer. Helix uses three of them:

  • Block — bordered box with a title; used to frame popups and pickers.
  • Paragraph + reflow.rs — word-wrapped text; used in markdown rendering and signature help.
  • Table — column-aligned rows; used in pickers (file picker, symbol picker, diagnostics picker, etc.).

The fourth tui-rs widget, List, is commented out — Helix uses Menu (helix-term/src/ui/menu.rs) and Picker instead, which expose richer interaction.

Integration points

  • The Cell type pulls Style and Color from helix-view::graphics, so widgets stay independent of theme loading.
  • helix-term::compositor::Compositor::render calls Terminal::draw, then walks each Component and gives it a &mut Buffer plus a Rect.
  • Backends initialize and tear down through Backend::claim/restore, called from Application::new and the panic hook in helix-term/src/application.rs.

Entry points for modification

  • New widget: add a module under widgets/ and implement Widget.
  • Backend feature flag (e.g. supporting a new escape sequence): add a method to the Backend trait and implement it across termina/crossterm/test.
  • Tweaking buffer diff behaviour: see Buffer::diff in buffer.rs.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

helix-tui – Helix wiki | Factory