txt

A fast, keyboard-driven terminal text editor for engineers.

Why txt

Most terminal editors demand a ceremony before you can edit: configuring plugins, learning a modal system, or fighting with a setup that takes hours to get right. GUI editors are the opposite problem — they are powerful, but reaching for the mouse to edit a config file or fix a typo breaks your flow.

I built txt because I spend most of my time in the terminal, and switching to a different tool just to make a quick edit always felt like friction I did not want. The editors that live in the terminal either have steep learning curves built around modal paradigms, or they are too limited to be genuinely useful.

The design principle behind txt is simple: editing should feel like thought. The editor opens immediately, keystrokes are predictable and discoverable, and the cursor lands exactly where you expect. There is no modal confusion, no mandatory configuration, and no plugin ecosystem to navigate before you can open your first file.

txt is not trying to replace your main IDE. It is the editor you reach for when you just need to edit something — and you want to stay in the terminal to do it.

Features

Install

Homebrew (macOS and Linux)

brew tap ErikHellman/tap
brew install txt

Update later with brew upgrade txt.

macOS and Linux (curl)

curl -fsSL https://raw.githubusercontent.com/ErikHellman/txt/main/install.sh | sh

Installs the latest release binary to ~/.local/bin. Make sure that directory is on your PATH. Re-run the same command to update.

Windows

irm https://raw.githubusercontent.com/ErikHellman/txt/main/install.ps1 | iex

Installs to %LOCALAPPDATA%\txt and adds it to your PATH automatically.

Build from source

Requires Rust 1.88 or newer.

git clone https://github.com/ErikHellman/txt.git
cd txt
cargo build --release

The binary will be at ./target/release/txt. Copy it anywhere on your PATH.

Usage

Open a file or a directory:

txt file.txt
txt .

Opening a directory brings up the file sidebar automatically. Press F1 at any time to see the full list of key bindings.

Key bindings

Key Action
Ctrl+S Save file
Ctrl+Q Quit
Ctrl+P Fuzzy file picker
Ctrl+Shift+O Symbols in current file
Ctrl+Shift+P Command palette
Ctrl+F Find
Ctrl+H Find & replace
Ctrl+W Expand selection to enclosing AST node
Ctrl+Shift+W Shrink selection
Ctrl+Shift+[ Toggle code fold at cursor
Alt+Shift+Up/Down Add cursor above / below
Alt+M Jump to matching bracket
Alt+L Center the viewport on the cursor
Alt+Left / Alt+Right Walk the jump list
Ctrl+Z Undo
Ctrl+Y / Ctrl+Shift+Z Redo
Ctrl+Shift+G Git operations dialog
Ctrl+L Configure LSP server
Ctrl+, Open settings
F1 Show all key bindings

The default txt keymap is shown above. VS Code and IntelliJ IDEA presets are available from the settings UI (Ctrl+,), and a ~/.config/txt/keybindings.toml overrides individual bindings.

Configuring LSP servers

LSP is per-workspace and opt-in. The fastest way to get started is the LSP picker (Ctrl+L, or Configure LSP server in the command palette): pick a language and txt writes the selection to <workspace>/.txt/lsp.toml for you. Install the server binary from upstream first — txt does not download language servers — and the first time the binary is launched you will be asked to approve it. The SHA-256 of approved binaries is cached in ~/.config/txt/trusted_binaries.json; changed binaries re-prompt.

Built-in server presets

The picker ships with presets for the following servers — click through to the upstream project for installation instructions:

C/C++ (clangd), Python (pyright), Lua (lua-language-server), and Zig (zls) are also in the picker.

Editing lsp.toml directly

For anything beyond the defaults — passing extra flags, pointing at a custom binary, or providing initializationOptions — edit <workspace>/.txt/lsp.toml:

enabled = true
server  = "rust-analyzer"

# Plain server with no extra arguments.
[servers.rust-analyzer]
command = "rust-analyzer"

# Pass extra arguments via the `args` array.
[servers.gopls]
command = "gopls"
args    = ["serve", "-rpc.trace"]

# Use a custom binary path and forward an initializationOptions JSON
# payload during the LSP handshake.
[servers.pyright]
command      = "/opt/homebrew/bin/pyright-langserver"
args         = ["--stdio"]
init_options = { pythonPath = "/usr/bin/python3" }

# Multiple servers can live side-by-side; the `server` key at the top
# of the file selects which one is active.
[servers.typescript-language-server]
command = "typescript-language-server"
args    = ["--stdio"]

The fields are:

License

txt is dual-licensed under MIT and Apache 2.0. You may choose either license.

Bug reports and feature requests

Found a bug or have an idea for a feature? Open an issue on GitHub:

github.com/ErikHellman/txt/issues

For bugs, please include your operating system, the version of txt (run txt --version), and the steps needed to reproduce the problem.