English | 中文
A terminal text editor written in Zig.
Editing (vim-style)
- Six modes: Normal / Insert / Visual / Visual Line / Visual Block / Command
- Full motions with counts: hjkl, w/e/b/ge, ^/0/$, gg/G, {/}, %, f/F/t/T, Ctrl-u/d/f/b
- Text objects, surround, comments, alignment, EasyMotion (s /
<leader>f), multi-cursor (Ctrl+n) - Undo/redo (grouped + branch semantics), register semantics (linewise/charwise yank & put) with system clipboard interop (OSC52 + pbcopy/wl-copy/xclip/xsel, nvim
clipboard=unnamedplusstyle) - Keyboard macros:
q{reg}records (q stops),@{reg}replays with count support (3@a,@@); in Visual mode@runs the macro once per selected line (:'<,'>normal!semantics);recording @xstatus indicator - Splits (:sp/:vs + Ctrl-w family), buffer tab bar, relative line numbers, code folding
Syntax & UI
- tree-sitter syntax highlighting (multiple bundled grammars), rainbow brackets, indent guides + scope highlight animation
- Inline markdown rendering: headings/bold/italic/links/code, fence code highlighted in its own language, markup concealed off the cursor line, checkbox icons, heading/code-block background bands
- Multiple themes (
<leader>sptheme picker with live preview; the choice persists automatically — no config or env var needed): kanagawa-wave, kanagawa-dragon, catppuccin (latte / frappe / macchiato / mocha), tokyonight (night / storm / moon), everforest, onedark, melange, doom-one, sonokai-shusia, flexoki-dark, flexoki-light - Soft-wrap: lines wider than the window wrap onto continuation rows (grapheme/CJK-width aware)
- Large-file degradation: highlighting turns off above 100 KB to stay smooth
LSP
- Async attach (never blocks startup); works with zls and other common servers (auto-detects mason install paths)
- Hover (K), goto definition/declaration/references/implementation (gd/gD/gr/gI), signature help (gs)
- Diagnostics gutter marks +
]d/[djumps + diagnostics list (<leader>sd) - Auto-completion menu + ghost text (
<C-n>/trigger characters), inlay hints (<leader>ti) - Rename (
<leader>rn), format (<leader>lf), document outline (<leader>o)
Navigation & search
- Fuzzy pickers: files (
<leader>sf), grep (<leader>st), buffers (<leader>sb), recent files (<leader>sr), keymaps (<leader>sk) - File tree (
<leader>etoggle,<leader>Elocate current file) rooted at the workspace's project directory - In-buffer search (
/,?, n/N)
Workspaces (Doom-Emacs style)
- Swap-on-switch workspaces:
SPC TAB nnew /.pick /rrename /ddelete /xclear session /[]prev · next - Independent buffers, window layout and file tree per workspace; opening a file already open in another workspace is refused (no double-edit)
- The file tree and fuzzy file picker follow each workspace's project root — the opened file's nearest
.gitdirectory, else its own directory - Status bar shows the current workspace name; a snacks-style dashboard greets a fresh workspace
Git
- Gutter diff marks,
]c/[chunk jumps,<leader>hs/<leader>hrstage/reset,<leader>hphunk preview - Current-line blame ghost text (shows 1s after the cursor settles,
<leader>tbtoggles),<leader>lgfloating lazygit - Branch name in the status bar
Terminal
- Embedded terminal (Linux / macOS):
Alt+rfloating /Alt+wbottom /Alt+eright; Esc in the terminal returns to Normal mode
Requires Zig 0.16.0:
zig build # dev build
zig build -Doptimize=ReleaseFast -Dstrip # release build (daily driver)
zig build test # unit tests
zig build e2e # pty end-to-end tests (Linux only for now)Run: oz [file[:line]]
Methodology: pty-driven with screen reconstruction, same machine (Apple Silicon, macOS), same files, median of 3 runs.
| Scenario | oz | nvim --clean |
|---|---|---|
| Startup (small file) | 66 ms | 115 ms |
| Startup (5 MB / 100k lines) | 65 ms | 118 ms |
| Startup (.zig, zls installed) | 52 ms | 117 ms |
| G to end of file (100k lines) | 54 ms | 65 ms |
| 100× Ctrl-F paging | 54 ms | 100 ms |
| 500× j cursor moves | 53 ms | 100 ms |
| Type 100 chars | 64 ms | 66 ms |
| Type 30 chars at EOF of a 100k-line file | 71 ms | 56 ms |
| Full-text search (100k lines) | 58 ms | 66 ms |
| Type 60 chars with LSP attached | 60 ms | 56 ms |
On par with or faster than nvim in every scenario. Key design choices: mmap-backed lazy file loading, PieceTable with incremental line index, incremental tree-sitter parsing, async LSP handshake + writer thread + incremental sync, atomic saves (temp file + rename).
Prebuilt binaries for Linux (x86_64/arm64) and macOS (x86_64/arm64) are attached to each GitHub Release — download, extract and run, no Zig needed. To build from source see "Build & Run" above.
MIT © niT-Tin
A personal project maintained in spare time — please set expectations accordingly:
- Features are driven by my own daily use; bug reports with repro steps are very welcome;
- Pull requests are reviewed and merged, but on my own schedule;
- Keybindings / APIs may still change during 0.x;
- A star is the nicest encouragement.