helix-editor/helix
Architecture
Helix is a Cargo workspace split into focused crates. The core editing primitives are functional and frontend-agnostic; the terminal UI is one of (currently the only) frontend layered on top.
The layering deliberately reflects a long-term goal: make helix-core plus helix-view reusable from a non-terminal frontend (the project vision mentions exploring a wgpu renderer). In practice today, helix-view still has terminal-shaped assumptions, but the boundary between core data structures and rendering is enforced by the crate split.
Crate map
| Crate | Lines | Description | Source |
|---|---|---|---|
helix-stdx |
~2.2k | Path, env, file-access, range, and rope helpers shared across crates. | helix-stdx/src |
helix-parsec |
~0.6k | A small parser-combinator library used by snippet parsing. | helix-parsec/src/lib.rs |
helix-event |
~1.1k | Synchronous hooks, async hooks, debouncing, and a global redraw lock. | helix-event/src |
helix-loader |
~1.2k | Locates config/runtime dirs, fetches and builds tree-sitter grammars. | helix-loader/src |
helix-core |
~19.6k | Rope, Selection, Transaction, Syntax, indent, movement, snippets. |
helix-core/src |
helix-view |
~14.5k | Editor, Document, View, Tree, theme, registers, clipboard, gutter, input. |
helix-view/src |
helix-tui |
~5.9k | TUI primitives forked from tui-rs (buffers, layouts, widgets, backends). | helix-tui/src |
helix-term |
~30.6k | Terminal frontend: application loop, commands, keymap, UI components. | helix-term/src |
helix-lsp |
~4.0k | LSP client transport, server registry, JSON-RPC. | helix-lsp/src |
helix-lsp-types |
~9.9k | LSP protocol type definitions (vendored). | helix-lsp-types/src/lib.rs |
helix-dap |
~1.1k | Debug Adapter Protocol client. | helix-dap/src |
helix-dap-types |
~1.0k | DAP protocol type definitions. | helix-dap-types/src/lib.rs |
helix-vcs |
~1.3k | Diff provider abstraction; git is the only backend today. | helix-vcs/src |
xtask |
— | Ad-hoc task runner: docgen, query-check, theme-check. |
xtask/src |
Layered view
graph TD
subgraph Frontend
Term[helix-term<br/>commands, keymap, UI]
Tui[helix-tui<br/>buffers, widgets, backends]
end
subgraph Editor State
View[helix-view<br/>Editor, Document, View, Tree]
end
subgraph Core Primitives
Core[helix-core<br/>Rope, Selection, Transaction, Syntax]
end
subgraph Integrations
Lsp[helix-lsp]
Dap[helix-dap]
Vcs[helix-vcs]
end
subgraph Foundations
Event[helix-event]
Loader[helix-loader]
Stdx[helix-stdx]
Parsec[helix-parsec]
end
Term --> Tui
Term --> View
Term --> Lsp
Term --> Dap
View --> Core
View --> Vcs
View --> Event
Lsp --> Core
Lsp --> Stdx
Core --> Stdx
Core --> Loader
Core --> Parsec
Loader --> StdxHow a keypress becomes an edit
The terminal frontend runs an async event loop in Application::run. Every iteration selects between terminal events, LSP responses, DAP messages, async jobs, redraw requests, and signals.
sequenceDiagram
participant Term as Terminal
participant App as Application
participant Comp as Compositor
participant Editor as EditorView
participant Cmd as MappableCommand
participant Doc as Document
participant Rope
Term->>App: KeyEvent
App->>Comp: handle_event
Comp->>Editor: dispatch (top layer)
Editor->>Cmd: lookup via Keymaps
Cmd->>Doc: build Transaction
Doc->>Rope: apply Transaction
Rope-->>Doc: new rope state
Doc-->>Editor: emit DocumentDidChange event
Editor-->>Comp: render request
Comp-->>Term: draw frameThe commands themselves live in helix-term/src/commands.rs (the largest file in the codebase at ~7k lines). They are invoked through MappableCommand, which wraps either a Rust function or a typable :command defined in commands/typed.rs.
Keybindings are resolved by Keymaps walking a KeyTrie tree built from default.rs merged with user config.
Rendering
The TUI uses a layered compositor inspired by Cursive. Each layer is a Component (see compositor.rs). The bottom layer is the editor view; popups, pickers, prompts, completion menus, and overlays sit on top.
Drawing happens onto an off-screen Surface (tui::buffer::Buffer from helix-tui/src/buffer.rs). Backends (termina on Unix, crossterm on Windows, plus a TestBackend used during integration tests) diff the new buffer against the previous frame and emit minimal terminal updates. See helix-tui for the full backend model.
Data flow for a document
A Document (helix-view/src/document.rs) bundles:
- The text
Rope(fromropey) - A per-
ViewSelection(eachViewhas its own selection over the same document) - Optional
Syntax(tree-sitter parse tree) and tree-house highlighter state - Document
Historyfor undo/redo - Diagnostics from language servers and other providers
- A
DiffHandlefromhelix-vcsfor git gutter signs
Modifications go through Transaction::change or change_by_selection (helix-core/src/transaction.rs). Transactions are OT-style change sets that can be inverted (for undo), composed, and mapped (so positions in old text can be translated into new text).
Async and event handling
Long-running or debounced work uses AsyncHook from helix-event. Examples include LSP completion debouncing, document highlight requests, and DAP message processing. Synchronous reactions to editor state changes (e.g. closing the completion popup when the cursor moves) use synchronous hooks declared via the events! macro and registered with register_hook!.
The tokio runtime is single-threaded for the main loop but uses worker threads for I/O (see helix-term/Cargo.toml features rt, rt-multi-thread).
Cross-cutting concerns
- Configuration.
helix-term/src/config.rsloads global and workspace TOML and merges them. Editor settings come fromhelix-view/src/editor.rs::Config. - Themes.
helix-view/src/theme.rsloads*.tomlthemes fromruntime/themes/. - Languages.
languages.tomlis the source of truth for language servers, formatters, indent/textobject queries, comment tokens, and grammar URLs. It is parsed byhelix-core/src/syntax/config.rs. - Tree-sitter. Grammars are fetched and built by
helix-loader/src/grammar.rs; highlighting uses thetree-housecrate (a Helix-maintained tree-sitter wrapper). - Workspace trust.
helix-loader/src/workspace_trust.rsgates loading of workspace-local config and unsafe language settings.
For more on each subsystem, follow the links in the package, feature, and primitive sections.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.