Skip to main content

TurboVI

A vi clone for the terminal: modes, counts, operators, registers, marks, macros, split windows and :s, in about three thousand lines of Python.

uv sync
uv run turbovi somefile.py
uv run turbovi one.py two.py   # two buffers, :bn between them
uv run turbovi                 # a scratch buffer

:q to leave, :help for what is here.

What a vim user gets

The grammar, ["x] [count] operator [count] motion, over hjkl w b e W B E 0 ^ $ gg G { } f F t T %. Operators d c y > < with doubling (dd, yy, cc), text objects (iw aw i( a" i{), and x X D C s S r ~ J p P o O.

Modes: normal, insert, visual, visual-line and command.

Paging with <C-f> <C-b> <C-d> <C-u>, by the window rather than by a fixed number, and <C-e> / <C-y> to move the view without moving the cursor.

Search with / ? n N and match highlighting. Undo and redo with u and <C-r>. . repeats the last change, recorded as keystrokes the way vi does it, so a change that ends in insert mode replays whole.

:s with ranges (%, ., $, 1,5, .+1), the g, i and n flags, any non-alphanumeric delimiter, and & in the replacement. One u undoes the whole substitution.

Marks: ma puts one down, `a comes back to the character and 'a to the first non-blank of that line. Every jump leaves a mark, so `` returns from a G or a search. `:marks` lists them. They are not shifted when the text moves, which is the one place this is smaller than vi.

Macros: qa records into register a, q stops, @a plays, 3@a plays three times, @@ repeats the last. They share storage with the yank registers the way vi's do, so "ap pastes a macro as text and @a runs a yanked line. A macro that calls itself stops with a message rather than a stack that runs out.

Several files at once with :e :ls :bn :bp :b, split windows with :sp and :vsp, and <C-w> then w s v c o or h j k l to move between them. <C-p> and :find are a fuzzy picker over the project: type a few letters of the path and it opens in the current window.

The system clipboard on "+y and "+p, over OSC 52 and a local helper, so it crosses ssh.

Syntax colouring from the file's name. :set syntax=rust colours a file with no suffix, :set nosyntax stops. A search hit and a selection paint over the colouring, because finding something inside a comment has to be visible.

A file opens and saves as itself. The encoding, the line endings and whether the last line had a newline are read once and written back unchanged. A latin-1 file stays latin-1, a CRLF file stays CRLF, and a file with no trailing newline does not gain one.

Settings and recovery

Settings live in $XDG_CONFIG_HOME/turbovi/config, a file of ex commands the way a vimrc is:

set nu
set rnu
sp

A modified buffer is copied to $XDG_DATA_HOME/turbovi/recover/ every few seconds, keyed by a hash of its absolute path, and :recover puts it back after a crash without writing anything to disk. The recovery copy is dropped when the buffer is saved.

What it is not

Not a vim: no plugins, no scripting language, no :g, no folds, no tabs, no persistent undo across sessions yet.

Built on turbodesk

turbodesk is the immediate-mode terminal UI library underneath. This editor is the application on it that uses no widgets at all — views, events and hooks, nothing else — which is what proved the core carries a real application on its own. It lived in that repository as examples/vi/ until 2026-08-26; a smaller showcase version stays there.

Release files for turbovi 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for turbovi 0.3.0
File Size Uploaded
turbovi-0.3.0.tar.gz 42.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for turbovi 0.3.0
File Interpreter ABI Platform
turbovi-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.6 kB

Release files / turbovi-0.3.0.tar.gz

Download URL turbovi-0.3.0.tar.gz
Size 42.3 kB
Tags Source
SHA-256 checksum
How to use checksums
abfa898c5e50082da4996dac3e907a7e8ca9eb24fba86b5331e38fcff79c3c08
BLAKE2b-256 checksum
How to use checksums
c6d3d09159837b4619ec5a7317b2425f3f5767c34174c8f351a41453f859b5cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / turbovi-0.3.0-py3-none-any.whl

Download URL turbovi-0.3.0-py3-none-any.whl
Size 48.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3786d49e2b663228cdc82da79b19bda37d5ed5d1c9999a1702bdb491cff5998e
BLAKE2b-256 checksum
How to use checksums
37c2d3d916d9009e6195d270c3edc92750905312e76de47e3d00045466861f0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page