RetroFed Forum
Your home away from modern life.
vorto — A Vim-flavored modal terminal editor, written in Rust.
Post Reply
AuthorMessage
♠️ Critical Nexus ✊🏿 reddthat.com PumpkinDrama@reddthat.com
Joined: 2023-09-23
Quote

vorto

A Vim-flavored modal terminal editor, written in Rust.

Vorto is…

a modal terminal text editor with batteries included. Tree-sitter
highlighting, Language Server Protocol support, fuzzy pickers, an
in-editor AI agent pane, and optional Copilot inline completions — all
in a single, dependency-light binary that starts instantly and needs no
Node toolchain, plugin manager, or external repos to clone.

Why vorto

  • Batteries included, not assembled. LSP, tree-sitter, fuzzy
    pickers, a file explorer, git gutter, themes, multi-cursor, and
    bookmarks all work out of the box — there is no plugin manager to
    learn and nothing to wire together.
  • A single static binary. Pure Rust, no runtime dependencies beyond
    a C compiler for building grammars on demand.
  • No Node, no clones. Tree-sitter grammars install on demand — no
    tree-sitter-cli, no external repos, no Node toolchain.
  • Responsive by design. An async architecture keeps the UI snappy
    while language servers index and grammars parse in the background.
  • Familiar. Vim-style modal editing with operators, motions,
    tree-sitter text objects, multi-cursor, jump labels, bookmarks, and
    .-repeat.
  • Themable. Helix-compatible TOML themes — most Helix theme files
    drop in unchanged.
  • Optional AI. Ghost-text inline completions via
    copilot-language-server and an :agent pane that runs an AI coding
    agent inside the editor — both silent when not configured.

Installation

From crates.io:

cargo install vorto

From source:

git clone https://github.com/vorto-editor/vorto.git
cd vorto
make install            # installs to ~/.local/bin
# or
cargo build --release   # binary at target/release/vorto

Requires a Rust toolchain (edition 2024). A C compiler is needed when
building tree-sitter grammars.

vorto [FILE]
vorto -h | --help
vorto -V | --version

Features

Editing

  • Normal / Insert / Visual (char, line, block) / Command modes
  • Operators: d y c > <
  • Motions: h j k l, w b e W B E ge gE, f F t T ; ,, gg G H M L,
    { }, %, <C-f> <C-b> <C-d> <C-u>
  • Search: / ?, n N, * #, gn gN
  • Text objects: iw aw, i" a", i( a(, i{ a{, i[ a[, ip ap,
    plus tree-sitter-aware if af (function), ic ac (class),
    i, a, (parameter)
  • Multi-cursor: + add next match, Shift-Down add below, - pop,
    <space>, clear
  • Code folding: za toggle, zo open, zc close the fold under the
    cursor; zR open all, zM close all. Fold ranges come from a
    language's tree-sitter folds.scm when available, falling back to
    indentation so folding works in any buffer. A collapsed fold shows a
    ⋯ N lines marker on its header row; vertical motions step over
    hidden lines. Folds are per-pane and survive buffer switches
  • Jump labels: gw (easymotion-style 2-char word jumps)
  • Jump history: <C-o> / <C-i> (or Tab) walk the per-pane jumplist;
    :jumps / <space>j open a fuzzy picker over it
  • Bookmarks (harpoon-style): <space>ma add, <space>md remove,
    <space>mm open the picker; :bookmarks (alias :bm) takes
    add / delete / list. Marked lines show a ● in the gutter and
    persist per-project across restarts
  • Per-buffer cursor memory: switching back to a buffer restores the
    cursor where you left it (tracked independently per pane)
  • Auto-pair brackets and quotes, language-aware comment toggle
    (<space>c), case toggle, line join, repeat with .
  • Undo / redo (u / <C-r>), system clipboard yank/paste via
    arboard

Language Server Protocol

Feature Binding / Trigger
Diagnostics inline, navigate with ]d / [d
Hover K (scrollable markdown popup)
Completion <C-n> / <C-p> + trigger chars
Signature help auto on ( / ,
Code actions <space>a
Goto definition gd
Goto declaration gD
Goto implementation gi
References gr (preview picker)
Rename <space>r
Format on save :w runs configured formatter

Servers and formatters ship with built-in defaults for the common
languages (rust-analyzer, pyright, gopls, clangd, vtsls, and ~30
more). Override or add to them per-language in config.toml.

Tree-sitter

  • Built-in grammar recipes for 44 languages: rust, python, go,
    javascript, typescript, tsx, toml, kotlin, c, cpp, java, bash, json,
    yaml, markdown, html, css, lua, ruby, zig, sql, dockerfile, make,
    hcl, diff, vue, svelte, haskell, elixir, nix, c-sharp, swift, php,
    dart, ocaml, graphql, fish, julia, gleam, scala, odin, proto, cmake,
    xml
    .
  • Install on demand — only the grammars you use are built and cached:
    vorto grammar list
    vorto grammar install rust python
    vorto grammar install --all
    vorto grammar install-queries rust
    vorto grammar remove rust
    
  • Or from inside the editor with :grammar — opens a modal listing
    every grammar and its install status; j/k to move, Enter to
    install the selected grammar (asynchronously, in the background),
    d to remove. The buffer re-highlights the moment an install
    finishes — no restart. :grammar install <name>… and
    :grammar remove <name>… work inline too, mirroring the CLI.
  • Uses highlights.scm for coloring, indents.scm for auto-indent,
    textobjects.scm for tree-sitter text objects, and folds.scm for
    syntax-aware code folding (indentation-based folds when absent).
  • Falls back to plain text when a grammar is unavailable.

UI

  • Fuzzy pickers with live syntax-highlighted preview:
    • Files — :e (git-aware)
    • Buffers — :ls / :buffers
    • Changed files — <space>g (files differing from HEAD)
    • Document symbols — <space><space> (LSP)
  • File explorer tree on <space>e — navigate with j k l /
    arrows, toggle hidden files with ., toggle .gitignored files
    with h, filter with /, and create / delete / rename / move with
    a / d / r / m
  • Splits: :split / :vsplit, <space>w h / <space>w v,
    cycle with <C-w w>
  • Status bar with mode badge, filename, cursor position, dirty flag
  • Configurable indentation guides (line / dot, skip levels)
  • Mode-specific cursor shapes (block / bar / underline)
  • Mouse support: click to move cursor, scroll to scroll
  • Non-blocking toast notifications

Theming

  • :theme opens a filterable picker that previews each theme live on
    the current buffer as you move the cursor; Enter applies and persists
    it to config.toml, Esc reverts.
  • Helix-compatible TOML themes — a flat scope → color map with an
    optional [palette], so most Helix theme files drop in unchanged.
  • Dozens of built-ins (Catppuccin, tokyonight, nord, dracula, gruvbox,
    rose-pine, kanagawa, ayu, …) plus an ansi theme that uses your
    terminal's own palette. See Themes for the full reference.

AI (optional)

  • Inline completions — if copilot-language-server is on your
    PATH, vorto enables ghost-text inline completions: accept with
    <Tab>, dismiss with <Esc>. Missing the binary is a no-op — no
    errors, no prompts.
  • Agent launcher — :agent opens an AI coding agent in a built-in
    pane inside vorto, running under a pseudo-terminal alongside your
    buffers (no external multiplexer required). A bare :agent launches
    the configured default, or opens a picker the first time and remembers
    your choice. Re-running :agent focuses the existing pane instead of
    spawning another; the agent process keeps running even if you close its
    pane. While the agent pane is focused, every key goes to the agent
    except Ctrl-W, which is reserved for window navigation
    (Ctrl-W h/j/k/l/w) so you can move focus back to a buffer. :agent explain @file / :agent chat @file go further: they build a prompt
    about the active buffer and send it to the agent. Use @selection
    instead of @file to scope it to the visually-selected text: select in
    visual mode, press :, and the selection is captured for :agent explain @selection and embedded in the prompt as a code block. An
    unsaved or scratch buffer used as @file is snapshotted to a temp file
    first so the agent has something on disk to read. Built-in catalog:
    claude, codex, gemini, aider — override commands/args or the
    default in config.toml (see below).

Git

  • Diff gutter: + added, ~ modified, ⋮ deleted marker
  • File picker honors .gitignore and your global excludes file
  • Status bar surfaces buffer dirty state
  • Conflict markers: <<<<<<< / ======= / >>>>>>> blocks (and the
    diff3 ||||||| base) are highlighted — a colored bar on each marker
    line and a dim tint on the "ours" / "theirs" sides, layered under
    syntax. Jump between conflicts with ]c / [c, and resolve the one at
    the cursor with :conflict ours / theirs / both / none (undoable).
    Works on both git conflicts and the autoreload = "merge" markers
    below.

Auto-reload

When the active buffer's file changes on disk, vorto reacts according to
the autoreload setting ([editor], overridable per language):

  • "replace" (default) — prompt to reload; if the buffer is dirty it
    warns that unsaved edits will be replaced (undo with u). Declining
    suppresses re-prompts until the file changes again.
  • "merge" — follow the external edit via a three-way merge instead of
    prompting; conflicts are written inline with <<<<<<< / ======= /
    >>>>>>> markers (local (your edits) vs disk) and the result is
    undoable.
  • "none" — disable the watcher; reload manually with :reload.

Configuration

Configuration lives under $XDG_CONFIG_HOME/vorto/ (typically
~/.config/vorto/):

  • config.toml — editor settings, keymap, theme, per-language LSP /
    formatter / indent overrides, a [finder] table (hidden_patterns,
    max_items) controlling what the file picker and explorer treat as
    hidden, and an [agent] / [agents.*] section for the :agent
    launcher:

    [agent]
    default = "claude"      # bare :agent launches this; unset → picker
    
    [agents.claude]         # override a built-in or add a new agent
    command = "claude"
    args = ["--model", "opus"]
    # How `:agent explain @file` passes its prompt at launch. `{prompt}` is
    # substituted with the text. Defaults to ["{prompt}"] (positional, as
    # claude/codex accept); aider needs ["--message", "{prompt}"]; set [] to
    # opt an agent out of launch-time seeding.
    prompt_args = ["{prompt}"]
    

    A workspace-local .vorto/config.toml takes precedence over the
    global file when present.

  • grammars/ — installed tree-sitter .so libraries

  • queries/<lang>/ — installed highlights.scm, indents.scm,
    textobjects.scm

  • themes/<name>.toml — color themes (see below)

Themes

:theme opens a filterable picker (/ to filter, j/k to move) that
previews each theme live on the current buffer as you move the cursor;
Enter applies and saves theme = "<name>" to config.toml, Esc reverts.

Themes are Helix-compatible TOML — a flat scope → color map with an
optional [palette], so most Helix theme files drop in unchanged:

# ~/.config/vorto/themes/mytheme.toml
keyword           = "mauve"
"function.macro"  = { fg = "mauve", modifiers = ["bold"] }
comment           = { fg = "#6c7086", modifiers = ["italic"] }
"ui.selection"    = { bg = "#313244" }

[palette]            # must come last (a TOML table header captures the
mauve = "#cba6f7"    # keys after it)

Color values are a [palette] name, a #rrggbb (or #rgb) hex literal,
or an ANSI color name. Scopes cover tree-sitter highlight captures
(keyword, function.method, …) and editor chrome — ui.background
(paints the whole editor; a theme that sets it recolors the background,
one that omits it keeps the terminal's), ui.selection, ui.linenr,
ui.statusline, ui.popup, ….

Built-in themes: ansi (terminal palette), the Catppuccin flavors
(catppuccin-latte, -frappe, -macchiato, -mocha), tokyonight,
nord, dracula, onedark/onelight, rose-pine, gruvbox-dark/
-light, everforest-dark/-light, kanagawa, solarized-dark/
-light, ayu-dark/-mirage/-light, and monokai-pro.
A file in themes/ shadows a built-in of the same name. The special
theme ansi uses your terminal's own 16-color palette and is always
available. Set the startup theme with theme = "<name>" in config.toml.

See the documentation site for the
full configuration reference.

License

Licensed under either of

at your option.

2   Original
Post Reply
Back to top