Rust · Terminal · Vim

Neovim's Core,
Rewritten in Rust.

ctrlvim is a from-scratch Rust reimplementation of Neovim's editing engine with a Ratatui-powered terminal frontend. Same modes, same motions, zero C.

$ cargo run -p ctrlvim-tui
   Compiling ctrlvim v0.1.0
    Finished `release` profile [optimized] target(s)
     Running `target/release/cvi`

Built from the Ground Up

Every layer is Rust — from the rope data structure to the terminal renderer.

⟨⟩

Buffer Engine

Rope-backed buffers with a unified mark tree, undo tree with branch traversal (g-/g+), and a register ring.

Modal Editing

Normal, Insert, Visual, and Cmdline modes with full motions, operators, and text objects — just like Neovim.

Lua Runtime

mlua-based Lua 5.4 embedding with vim.api.*, vim.fn.*, vim.keymap, and vim.treesitter.

Async I/O

Tokio-backed event loop with timers and msgpack-RPC codec for plugin and UI communication.

Window Management

Split frame tree with <C-w> commands. Horizontal and vertical splits, just as you'd expect.

TUI Frontend

Ratatui + crossterm dashboard, plugin manager, file browser, floating overlays, and mouse support.

Vimscript

Tree-walking interpreter supporting let, if, for, while, and function — the essentials.

Treesitter

Parse, query, and node-range extraction via the tree-sitter crate for syntax-aware editing.

Workspace Architecture

13 crates, strict dependency direction, no global mutable state.

crate replaces (Neovim C) what it does
ctrlvim-types Object / typval, handles Dynamic Object, arena handles, Position/Range, errors
ctrlvim-text memline.c, mark.c, undo.c, register.c Rope-backed Buffer, MarkStore, UndoTree, Registers
ctrlvim-options option.c + options.lua Three-tier (global/buffer/window) option overrides
ctrlvim-editor normal.c, ops.c, textobject.c, edit.c, state.c Motions, operators, Mode state machine, Session dispatch
ctrlvim-vimscript eval.c + eval/*.c Minimal Vimscript interpreter with builtins
ctrlvim-treesitter lua/treesitter.c Parse, query, node ranges via tree-sitter
ctrlvim-api src/ctrlvim/api/*.c ApiContext, #[ctrlvim_api] functions, autocmd store
ctrlvim-lua executor.c + converter.c mlua embedding, Object ↔ Lua converter, vim.* bridges
ctrlvim-async event/*.c, msgpack_rpc/*.c Tokio event loop, timers, msgpack-RPC codec
ctrlvim-core startup wiring Ctrlvim facade + demo binary
ctrlvim-tui (the UI, split out) Ratatui + crossterm frontend

Design Principles

No global state. Everything threads through an explicit Editor with copy-able integer handles — a stale handle is a clean None.
One callback mechanism. Autocmds, keymaps, and timers all store an Object::LuaRef resolved through the same registry.
Codegen via proc-macro. #[ctrlvim_api] on a Rust fn emits both Lua and RPC dispatch — no C-text parser needed.

Quick Start

Requires Rust 1.80+. Clone, build, run.

1

Clone the repository

$ git clone https://github.com/CtrlUserKnown/ctrlvim.git
$ cd ctrlvim
2

Run the tests

$ cargo test --workspace
3

Launch the TUI

$ cargo run -p ctrlvim-tui

Ready to try something different?

ctrlvim is early-stage but functional. Contributions, issues, and feedback welcome.