A fast terminal text editor for engineers who want to make quick, precise edits without leaving the terminal.
- Starts instantly. No bundled language servers, no plugin system, no background daemons. LSP support is available when you need it — bring your own server.
- No configuration required. Works out of the box with sensible defaults; a TOML config is available when you want it.
- Keyboard-driven. Familiar shortcuts (Ctrl+S, Ctrl+F, Ctrl+Z), fuzzy file picker, multi-cursor editing, and AST-aware selection — all without a mouse.
- Just editing. No built-in terminal, no code execution, no extension marketplace. The right tool for reviewing a diff, editing a config file, or making a targeted change alongside an AI coding agent.
curl -fsSL https://raw.githubusercontent.com/ErikHellman/txt/main/install.sh | shInstalls the latest release to ~/.local/bin/txt. Run the same command to update.
irm https://raw.githubusercontent.com/ErikHellman/txt/main/install.ps1 | iexInstalls to %LOCALAPPDATA%\txt\txt.exe and adds it to your user PATH.
Requires Rust 1.88 or later.
git clone https://github.com/ErikHellman/txt.git
cd txt
cargo build --release
# Binary is at target/release/txtDownload the archive for your platform from the Releases page, extract the binary, and place it on your PATH. Verify integrity with checksums.txt:
sha256sum --check checksums.txtbrew tap ErikHellman/tap
brew install txtNot yet available.
txt # open an empty buffer
txt file.rs # open a file
txt . # open a directory (file sidebar opens automatically)
txt --help # show CLI referencePress F1 inside the editor for a scrollable in-app reference.
| Key | Action |
|---|---|
| Arrow keys | Move cursor |
| Ctrl+Left / Ctrl+Right | Jump to previous / next word |
| Home / End | Line start / end |
| Ctrl+Home / Ctrl+End | File start / end |
| PageUp / PageDown | Page up / down |
| Ctrl+Up / Ctrl+Down | Scroll viewport without moving cursor |
| Key | Action |
|---|---|
| Shift+Arrows | Extend selection character by character |
| Ctrl+Shift+Left / Right | Extend selection word by word |
| Shift+Home / End | Extend to line start / end |
| Ctrl+Shift+Home / End | Extend to file start / end |
| Ctrl+A | Select all |
| Key | Action |
|---|---|
| Alt+Shift+Down | Add cursor on the line below |
| Alt+Shift+Up | Add cursor on the line above |
| Esc | Collapse all cursors to the primary cursor |
All editing and navigation operations apply to every cursor simultaneously.
| Key | Action |
|---|---|
| Ctrl+W | Expand selection to enclosing syntax node |
| Ctrl+Shift+W | Contract selection back one node |
| Ctrl+Shift+L | Select all occurrences of current selection |
| Key | Action |
|---|---|
| Ctrl+D | Duplicate current line |
| Alt+Up / Alt+Down | Move line up / down |
| Ctrl+/ | Toggle line comment |
| Ctrl+Backspace | Delete word backward |
| Ctrl+Delete | Delete word forward |
| Key | Action |
|---|---|
| Ctrl+C | Copy selection (or current line if no selection) |
| Ctrl+X | Cut selection (or current line) |
| Ctrl+V | Paste |
| Ctrl+Shift+C | Copy file reference |
| Key | Action |
|---|---|
| Ctrl+Z | Undo |
| Ctrl+Y / Ctrl+Shift+Z | Redo |
| Key | Action |
|---|---|
| Ctrl+S | Save |
| Ctrl+Shift+S | Save as |
| Ctrl+N | New file |
| Ctrl+T | New tab |
| Ctrl+O | Open file (path prompt) |
| Ctrl+] / Ctrl+PgDn | Next tab |
| Ctrl+[ / Ctrl+PgUp | Previous tab |
| Ctrl+1 – Ctrl+9 | Jump to tab by index |
| Ctrl+G | Jump to line |
| Key | Action |
|---|---|
| Ctrl+P | Fuzzy file picker |
| Ctrl+R | Recent files picker |
| Ctrl+B | Focus / open sidebar |
| Ctrl+Shift+B | Toggle sidebar (show/hide) |
| Ctrl+Shift+P | Command palette |
| Ctrl+Shift+E | Buffer switcher |
Sidebar keys (when sidebar is focused):
| Key | Action |
|---|---|
| Up / Down | Navigate entries |
| Space / Right | Open file or expand/collapse directory (stays in sidebar) |
| Left | Collapse current directory and move to its parent |
| Enter | Open file or toggle directory |
| Ctrl+C | Copy file |
| Ctrl+X | Cut file/directory |
| Ctrl+V | Paste |
| F2 | Rename file/directory |
| Delete | Delete file/directory |
| Ctrl+Shift+N | New folder |
| F5 | Refresh file tree |
| Key | Action |
|---|---|
| Ctrl+F | Open find bar |
| Ctrl+H | Open find & replace bar |
| F3 / Enter | Next match |
| Shift+F3 | Previous match |
| Alt+R | Toggle regex mode |
| Alt+C | Toggle case-sensitive mode |
| Tab | Switch between find and replace fields |
| Enter (in replace field) | Replace current match and advance |
| Ctrl+A (in replace field) | Replace all matches |
| Esc | Close search bar |
LSP servers must be installed separately on your system before they can be used. Use Ctrl+L to configure which server to launch for the current file type.
| Key | Action |
|---|---|
| Ctrl+Space | Code completion |
| Ctrl+K | Hover info |
| F12 | Go to definition |
| Shift+F12 | Find references |
| F2 | Rename symbol |
| Ctrl+. | Code action / quick fix |
| Key | Action |
|---|---|
| Alt+Z | Toggle word wrap |
| F1 | Toggle help overlay |
| Ctrl+Alt+, | Open settings |
| Ctrl+L | Configure LSP server |
| Ctrl+Q | Quit |
| Action | Effect |
|---|---|
| Click | Place cursor |
| Click and drag | Extend selection |
| Scroll wheel | Scroll viewport |
Tree-sitter powered highlighting with AST-aware selection (Ctrl+W / Ctrl+Shift+W). Language is detected from the file extension.
| Language | Extensions |
|---|---|
| Rust | .rs |
| Python | .py, .pyw |
| JavaScript | .js, .mjs, .cjs |
| JSON | .json, .jsonc |
Lines modified relative to HEAD are marked in the gutter:
- Added — line is new since HEAD
- Modified — line exists in HEAD but has changed
- Deleted — a line from HEAD was removed before this position
The gutter is absent for untracked files or repositories where git is unavailable.
The find bar (Ctrl+F) shows a live match count and highlights all matches. Ctrl+H adds a replace field. Toggle [Rx] for regex and [Cc] for case-sensitive mode while searching. Ctrl+A in the replace field replaces all matches in a single undo step.
Ctrl+P opens a fuzzy picker over all files in the current workspace using the nucleo library. Type to filter, use arrow keys to select, Enter to open, Esc to close.
Ctrl+Shift+P opens a searchable list of all editor commands with their shortcuts. Useful for discovering bindings or running commands without remembering the key.
Ctrl+B focuses or opens the sidebar. Ctrl+Shift+B toggles it closed entirely. Navigating the sidebar does not disturb the editor — the active pane is always shown in the status bar mode badge. Space or Right opens a file while keeping sidebar focus; Left collapses the current directory and moves to its parent.
When a file is modified externally (by another process or an AI agent writing changes), txt detects the change and reloads the buffer automatically, preserving the current cursor position.
Alt+Shift+Down/Up adds a cursor on the adjacent line at the same column. All cursor movements, edits, clipboard operations, and deletions apply to every cursor simultaneously. Esc collapses back to the primary cursor.
Location: ~/.config/txt/config.toml
All fields are optional. The file is created with defaults on first save via the settings overlay (Ctrl+Alt+,).
tab_size = 4 # spaces per indent level
word_wrap = false # enable word wrap by default
confirm_exit = false # ask before quitting with unsaved changes
auto_save = false # auto-save after edits (debounced)
show_whitespace = false # render whitespace glyphs
theme = "default" # "default" | "monokai" | "gruvbox" | "nord"| Key | Type | Default | Description |
|---|---|---|---|
tab_size |
integer | 4 |
Spaces per tab / indent |
word_wrap |
bool | false |
Wrap long lines at viewport width |
confirm_exit |
bool | false |
Prompt before quitting with unsaved changes |
auto_save |
bool | false |
Auto-save after edits |
show_whitespace |
bool | false |
Show visible whitespace glyphs |
theme |
string | "default" |
Color theme |
Settings can also be changed interactively via Ctrl+Alt+, and are written back to config.toml immediately.
Recent files are stored per-workspace in <workspace>/.txt/recents.json (up to 50 entries). This file is local to each project. If you do not want it to appear in Git, add .txt/ to your project's .gitignore.
- Rust 1.88+ (edition 2024) — install via rustup
cargo build # debug build
cargo build --release # optimised release build
cargo run -- <file> # run from source, open a file
cargo run -- <directory> # run from source, open a directorycargo test # run all unit tests
cargo bench # criterion benchmarks (benches/buffer.rs)Fix all compiler warnings before opening a PR — CI treats warnings as errors.
Every push to main and every pull request runs:
cargo fmt --checkcargo build --all-targets(with-D warnings)cargo clippy --all-targets -- -D warningscargo test --all-targets
txt follows a Model-View-Update pattern: AppState::update() mutates all state in response to input; ui::render() draws the full frame from that state on every tick. There is no retained UI state — the terminal buffer is fully redrawn each frame.
| Type | File | Role |
|---|---|---|
AppState |
src/app.rs |
All mutable state: editor, overlays, input mode, sidebar, clipboard |
Editor |
src/editor/mod.rs |
Tab list + active-tab index |
BufferHandle |
src/editor/tab.rs |
One tab: buffer + viewport + path + syntax host |
Buffer |
src/buffer/mod.rs |
Rope-based text + undo stack + multi-cursor |
MultiCursor |
src/buffer/cursor.rs |
Sorted Vec<Cursor>; primary cursor drives the viewport |
InputHandler |
src/input/mod.rs |
crossterm events → EditorAction |
EditorAction |
src/input/action.rs |
Flat enum of all user operations |
SyntaxHost |
src/syntax/mod.rs |
tree-sitter parser, parse tree, AST selection history |
ui::render |
src/ui/mod.rs |
Top-level renderer; computes layout, delegates to sub-renderers |
unicode-widthis pinned to=0.2.2— must match ratatui's internal version exactly. Any version change silently breaks cursor column rendering.- Use byte offsets for all rope operations.
ropey::Ropeis indexed by byte offset throughoutsrc/buffer/. Convert withrope.byte_to_char()/rope.char_to_byte()— never do char-index arithmetic directly. #[allow(dead_code)]annotations are intentional. Many public methods are future API being built incrementally. Do not remove them.
| Platform | Target triple | Archive |
|---|---|---|
| macOS Intel | x86_64-apple-darwin |
.tar.gz |
| macOS Apple Silicon | aarch64-apple-darwin |
.tar.gz |
| Linux x86_64 (static) | x86_64-unknown-linux-musl |
.tar.gz |
| Linux aarch64 (static) | aarch64-unknown-linux-musl |
.tar.gz |
| Windows x86_64 | x86_64-pc-windows-msvc |
.zip |
Linux binaries are statically linked against musl libc and run on any distribution without glibc version constraints.
Releases are tagged vMAJOR.MINOR.PATCH and built automatically by GitHub Actions for all five platforms. See RELEASES.md for the full release procedure, distribution channels, and install script details.
Licensed under either of MIT or Apache 2.0 at your option.