A fast, Neovim-inspired terminal editor written in Rust.
Your vim muscle memory, without the configuration overhead.
Tip: To see every keybinding available in Nevi, run
:Keymaps(or press<Space>fk) — a searchable list with a description for each one. See CHANGELOG.md for release notes and upgrade highlights.
The Problem: I love Neovim and Zed. Zed is an amazing editor - fast, modern, and beautiful. But it doesn't have all the vim keybinds I use daily, which stopped me from fully migrating to it. Neovim is powerful but can become slow with plugins. Helix uses Kakoune-style keybindings which require relearning muscle memory.
Nevi's Goal: A fast, native terminal editor where your existing vim/neovim muscle memory just works. No relearning keybindings, no plugin configuration overhead, no compromise on modern features like LSP and tree-sitter.
| Editor | Vim Keybinds | Built-in Features | Notes |
|---|---|---|---|
| Neovim | Full | Via plugins | Powerful but plugin-dependent |
| Zed | Partial | Yes | Fast but vim mode incomplete |
| Helix | Kakoune-style | Yes | Different keybind philosophy |
| Nevi | In Progress | Yes | Aiming for full vim compatibility |
Note: Nevi is under active development. Most common vim keybindings are implemented, with more being added regularly. See Keybindings for current status.
Note: Nevi currently supports macOS and Linux from source. Homebrew is available for macOS. Linux release tarballs and distro packages are planned. Windows support is planned.
- Vim/neovim keybindings - Most common keybinds implemented, more being added regularly
- Built-in LSP - rust-analyzer, typescript-language-server, pyright, and more
- Tree-sitter syntax highlighting - Fast, accurate highlighting for Rust, Go, Ruby, PHP, TypeScript, JavaScript, Python, CSS, JSON, TOML, HTML, Markdown
- Theme selection - Multiple built-in colorschemes with easy switching
- Fuzzy file finder - Telescope-style file and content search
- Previewed project replace - Project-wide literal replace with a read-only preview and explicit apply step
- Keybinding cheatsheet - Searchable
:Keymapspicker (<Space>fk) listing every binding with a description - GitHub Copilot integration - AI-powered completions
- File explorer - Built-in tree view
- Git signs - Gutter indicators for added/modified/deleted lines
- Harpoon-style quick file switching - Pin and jump to frequently used files
- Markdown preview - Open a fast, terminal-native rendered reader with
:MarkdownPreview - External formatter support - Biome, Prettier, and other formatters
- Split windows - Vertical and horizontal splits
- Configurable via TOML - Simple, readable configuration
brew install anthonyamaro15/nevi/neviOr tap first:
brew tap anthonyamaro15/nevi
brew install neviUpdate an existing Homebrew install after a new Nevi release:
brew update
brew upgrade neviIf you installed with the fully qualified formula name, this also works:
brew upgrade anthonyamaro15/nevi/neviVerify the installed version:
nevi --versionLinux users can build from source or install directly from GitHub with Cargo.
Install system build dependencies first:
# Debian / Ubuntu
sudo apt update
sudo apt install -y build-essential cmake pkg-config libssl-dev zlib1g-dev \
libx11-dev libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev
# Fedora
sudo dnf install -y gcc gcc-c++ make cmake pkgconf-pkg-config openssl-devel \
zlib-devel libX11-devel libxcb-devel
# Arch
sudo pacman -S --needed base-devel cmake pkgconf openssl zlib libx11 libxcbThen install Nevi:
cargo install --git https://github.com/anthonyamaro15/neviUpdate a Cargo-installed binary:
cargo install --git https://github.com/anthonyamaro15/nevi --forceOr build a local release binary:
git clone https://github.com/anthonyamaro15/nevi.git
cd nevi
cargo build --release
./target/release/neviUpdate a local source checkout:
git pull --ff-only
cargo build --releaseLinux binary tarballs and distro packages (.deb, .rpm, AUR) are not
published yet.
Nevi currently supports macOS and Linux from source.
Required for Homebrew install on macOS:
- Homebrew. Build dependencies such as Rust are installed by the formula when needed.
Required to build from source:
- Rust toolchain with
cargo- Minimum Rust version is 1.85
- Git, if cloning the repository with
git clone - macOS: Xcode Command Line Tools if your Rust setup prompts for native build tools
- Linux: native build packages such as
build-essential,pkg-config, and OpenSSL development headers
Required at runtime after any install method:
- A terminal emulator
Verify an installed binary with:
nevi --versionNot required:
ripgrep,grep,fd,fzf, or thetree-sitterCLI. Nevi's file finder, live grep, fuzzy matching, and syntax highlighting are built into the binary.
Optional tools unlock optional features:
| Feature | Optional tool | Install hint |
|---|---|---|
:LazyGit / <Space>gg |
lazygit |
brew install lazygit |
| Rust LSP | rust-analyzer |
rustup component add rust-analyzer |
| TypeScript / JavaScript LSP | typescript-language-server and typescript |
npm install -g typescript typescript-language-server |
| CSS / JSON / HTML LSP | vscode-langservers-extracted |
npm install -g vscode-langservers-extracted |
| TOML LSP | taplo |
cargo install taplo-cli --locked |
| Python LSP | pyright |
npm install -g pyright |
| PHP LSP | PHP 8.2+ and phpactor |
brew install php, then mkdir -p ~/.local/bin && curl -Lo phpactor.phar https://github.com/phpactor/phpactor/releases/latest/download/phpactor.phar && chmod +x phpactor.phar && mv phpactor.phar ~/.local/bin/phpactor |
| Go LSP | gopls |
go install golang.org/x/tools/gopls@latest |
| Ruby LSP | ruby-lsp |
gem install ruby-lsp |
| Markdown LSP | marksman |
Optional and disabled by default |
| External formatters | Whatever formatter you configure | Examples: biome, prettier, black, gofmt |
Git signs / :GitChanges |
A Git repository | No external git CLI required |
| GitHub Copilot completions | GitHub account and network access | No local Copilot binary required |
If an optional tool is missing, the rest of Nevi still works. Run
:checkhealth or :Health inside Nevi to inspect config paths, keymap
overrides, optional tool availability, LSP settings, formatter commands,
profiling status, and common setup issues.
Run :ToolInstall or :LspInstall to open a read-only install plan for missing
configured LSP servers and formatters.
git clone https://github.com/anthonyamaro15/nevi.git
cd nevi
cargo build --release
./target/release/nevicp target/release/nevi ~/.local/bin/
# or
sudo cp target/release/nevi /usr/local/bin/# Open current directory
nevi .
# Open a file
nevi src/main.rs
# Open a file as a read-only terminal viewer
nevi view src/main.rs
# Pick a file path from the terminal; Enter prints the path, Esc cancels
nevi pick .
# Compare any two text files in a read-only diff view.
# Wide terminals use side-by-side output; narrow terminals use stacked changes.
nevi diff before.rs after.rs
# Open multiple files
nevi file1.rs file2.rsBasic commands:
:w- Save, refusing to overwrite external disk changes:w!- Force save and overwrite external disk changes:q- Quit:wq- Save and quitZZ/:x- Save if modified and quit:checkhealth/:Health- Open editor health report in a read-only[health]buffer:ToolInstall/:LspInstall- Open missing LSP/tool install guidance in a read-only[tool-installer]buffer:FlightRecorder/:WhySlow- Open recent in-memory timing report in a read-only[flight-recorder]buffer:ConfigOpen/:config- Open your user config file:ConfigDefaults- View the latest built-in default config in a read-only[config-defaults]buffer:MarkdownPreview- Open rendered Markdown reader for.mdfiles (j/k,Ctrl-d/u,g/G,q):ProjectReplace/{pattern}/{replacement}/g- Preview project-wide literal replace:ProjectReplaceApply- Apply the last project replace preview:Jump- Labeled jump to visible text<Space>ff- Find files<Space>fg- Live grep<Space>fl- Find lines in current buffer<Space>j- Labeled jump to visible text<Space>gc- Git changes picker<Space>e- File explorer<Space>tt- Terminal picker<Space>tn/<Space>tj/<Space>tk- New / next / previous terminal session<Space>tr- Rename active terminal session<Space>fk- Search keymaps (keybinding cheatsheet)
Config location: ~/.config/nevi/config.toml
A template config file is created automatically on first run. Here's an example:
[editor]
tab_width = 2
format_on_save = true
relative_numbers = true
scroll_off = 8
[theme]
colorscheme = "onedark"
[terminal]
popup_width_ratio = 0.9
popup_height_ratio = 0.9
[lsp]
enabled = true
[copilot]
enabled = trueRun :ConfigOpen (or :config) to open your user config file from inside
Nevi. Run :ConfigDefaults to view the latest built-in default config template
in a read-only [config-defaults] buffer without changing your existing config.
Existing config files stay user-owned; Nevi does not rewrite them when new
defaults are added.
See the generated config file at ~/.config/nevi/config.toml for all available
options with documentation.
Nevi comes with 15+ built-in themes. You can also create your own custom themes.
Select a theme with :theme <name> or <Space>ft to open the theme picker.
Available themes: onedark, dracula, gruvbox, nord, tokyonight, catppuccin-mocha, rose-pine, solarized-dark, kanagawa, monokai, everforest, github-dark, github-light, ayu-dark, palenight, nightfox
- Location: Place
.tomlfiles in~/.config/nevi/themes/ - Template: A commented template is auto-generated at
~/.config/nevi/themes/_template.toml - Naming: The filename becomes the theme name (e.g.,
mytheme.toml→:theme mytheme)
Copy the template to get started:
cp ~/.config/nevi/themes/_template.toml ~/.config/nevi/themes/mytheme.toml# Define reusable colors
[palette]
red = "#e06c75"
blue = "#61afef"
bg = "#282c34"
# Syntax highlighting (can reference palette or use hex)
[syntax]
keyword = { fg = "purple" }
string = { fg = "green" }
comment = { fg = "gray", italic = true }
# UI elements
[ui]
background = "bg"
foreground = "#abb2bf"
cursor_line = "#2c313c"
[ui.statusline]
mode_normal = "blue"
mode_insert = "green"
# And more: [ui.completion], [ui.finder], [diagnostic], [git]See ~/.config/nevi/themes/_template.toml for the complete reference with all available options.
Nevi aims for full vim/neovim keybind compatibility. Most common keybindings are already implemented.
Full reference: See KEYBINDINGS.md for the complete keybind documentation with examples and tips.
h/j/k/l, w/b/e/W/B/E, 0/^/$, +/-, gg/G, {/}, (/), f/F/t/T, ;/,, %, H/M/L, gj/gk/g0/g$/g^
d/c/y + motions, dd/cc/yy, p/P/gp/gP, x/X, r, J/gJ, ==/={motion}, ., u/Ctrl+r
iw/aw, iW/aW, i"/a", i'/a', i(/a(, i{/a{, i[/a[, i</a<, ip/ap, is/as, it/at
/, ?, n/N, */#, gn/gN
gd (definition), gD (declaration), gI (implementation), gf (file under cursor), gx (URL under cursor), gr (references), K (hover), gl (diagnostic), ]d/[d (next/prev diagnostic)
ds{char} (delete), cs{old}{new} (change), ys{motion}{char} (add)
gcc (line), gc{motion} (motion)
Press <Space> by itself to show available leader continuations. Set [keymap] show_leader_popup = false to disable that popup.
| Key | Action |
|---|---|
ff |
Find files |
fg |
Live grep |
fl |
Find lines in current buffer |
sw |
Search word under cursor |
j |
Labeled jump to visible text |
fb |
Find buffers |
ft |
Theme picker |
fk |
Search keymaps |
tt |
Terminal picker |
e |
File explorer |
ca |
Code actions |
rn |
Rename symbol |
d |
Search diagnostics |
D |
Line diagnostic |
w |
Save file |
q |
Quit |
gg |
Open lazygit |
gc |
Git changes picker |
m |
Add to harpoon |
h |
Harpoon menu |
1-4 |
Jump to harpoon slot |
Ctrl+w v (vsplit), Ctrl+w s (hsplit), Ctrl+w q (close), Ctrl+w h/j/k/l or Ctrl+h/j/k/l (navigate), Ctrl+w w/W (next/previous), Ctrl+w = (equalize), Ctrl+w r/R (rotate), Ctrl+w x (exchange)
Visual mode (v/V/Ctrl+v), macros (q{a-z}/@{a-z}), marks (m{a-z}/'), read-only/expression registers ("%, ":, "#, "., "=), insert helpers (Ctrl+t/Ctrl+d/Ctrl+a/Ctrl+r/Ctrl+o), replace mode (R)
Missing a keybind? Check KEYBINDINGS.md for the full list of what's implemented. If you don't see the one you want, take a look at the keybind roadmap to see if it's already planned — and if it's not, open an issue to request it (PRs welcome too).
| Language | Server | Status |
|---|---|---|
| Rust | rust-analyzer | Supported |
| TypeScript/JavaScript | typescript-language-server | Supported |
| Python | pyright | Supported |
| PHP | phpactor | Supported |
| Ruby | ruby-lsp | Supported |
| CSS/SCSS | vscode-css-language-server | Supported |
| JSON | vscode-json-language-server | Supported |
| TOML | taplo | Supported |
| HTML | vscode-html-language-server | Supported |
| Go | gopls | Supported |
| Markdown | marksman | Optional, disabled by default |
LSP servers are auto-detected when installed. See ~/.config/nevi/config.toml for LSP configuration options.
If a server is missing, Nevi shows an install hint in the LSP status/error
message. You can also run :checkhealth to review the active LSP configuration,
or :ToolInstall / :LspInstall to open a missing-tool install plan.
Missing a language? Open a GitHub issue and we'll work on adding support!
Configure formatters in ~/.config/nevi/languages.toml:
[typescript]
formatter = { command = "biome", args = ["format", "--stdin-file-path", "{file}"] }Formatters are external commands. Nevi only runs a formatter if you configure one; otherwise it falls back to LSP formatting when available.
Contributions are welcome! Please feel free to submit issues and pull requests.
Nevi includes a test-only Vim oracle harness for checking selected key sequences against headless Neovim. The suite covers grouped deterministic motion, editing, and undo/redo cases, and failures include the key sequence plus Nevi/Neovim snapshots. The normal test suite does not require Neovim:
cargo test vim_oracle --quietTo run the real Neovim comparison, install nvim and opt in explicitly:
NEVI_VIM_ORACLE=1 cargo test vim_oracle_smoke -- --ignored --nocaptureNevi keeps a small in-memory flight recorder for recent hot-path timings. Run
:FlightRecorder or :WhySlow to open a read-only [flight-recorder] buffer
with recent render, input, syntax, LSP, finder, and terminal timing events.
Verbose file profiling is opt-in and disabled by default. To capture raw timing events while using Nevi locally:
NEVI_PROFILE=1 cargo run --release -- path/to/fileNevi writes raw timing events and a summary to /tmp/nevi_profile.log. The
summary includes count, retained sample count, total, average, p50, p95, and max
microseconds for metrics such as key handling, syntax updates, full renders, and
terminal-only renders.
Run :checkhealth (or :Health) inside Nevi to open a read-only [health]
buffer with config paths, config discoverability commands, keymap overrides and
warnings, LSP settings, optional external tool checks, formatter command checks,
profiling status, large-file thresholds, the active buffer's large-file mode,
and any profile summary from /tmp/nevi_profile.log. When syntax highlighting
is degraded for a very large buffer, the statusline shows [large] and
:checkhealth reports the active threshold. Because it is a regular buffer,
normal motions, search, and yank commands work there. Profile summaries are
written when a profiled Nevi session exits.
MIT License
Inspired by Neovim, Helix, and Zed.
Built with:
- ropey - Rope data structure for text
- tree-sitter - Syntax highlighting
- crossterm - Terminal handling
- nucleo - Fuzzy matching
- git2 - Git integration
