pi-vim-editor
Minimal Vim-style modal editing for Pi's prompt editor that composes with other editor extensions.
Package details
Install pi-vim-editor from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-vim-editor- Package
pi-vim-editor- Version
0.4.0- Published
- Oct 15, 2026
- Downloads
- 726/mo · 726/wk
- Author
- mavam
- License
- MIT
- Types
- extension
- Size
- 130.2 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
⌨️ pi-vim-editor
Minimal Vim-style modal editing for Pi's prompt editor. Instead of replacing the editor, it adds INSERT and NORMAL modes to whatever editor is installed, so Pi's inline working indicator, autocomplete, paste handling, and other editor extensions keep working.
🚀 Installation
pi install npm:pi-vim-editor
✨ Usage
The prompt starts in INSERT mode. Press Esc for NORMAL mode, where the
common Vim motions, operators, and text objects edit the prompt, and v, V,
or Ctrl-V start Visual mode. Press Esc again in NORMAL mode to interrupt
the agent, as usual. The current mode shows in a corner of the editor border.
If another extension also customizes the editor, load pi-vim-editor after it. Extensions that draw their own editor frame can show the Vim mode themselves; see docs/integration.md.
⌨️ Key bindings
Counts work on motions and most edits, as in 3w, d3w, or 2dd. Keys Vim
doesn't use, such as Enter, Tab, arrows, and Ctrl or Alt shortcuts, keep
doing what they do in Pi. The exceptions in NORMAL mode are Ctrl-V, which
starts Visual block mode instead of pasting an image, Ctrl-R, which redoes,
and Ctrl-].
Modes and Esc
| Key | Action |
|---|---|
Esc / Ctrl-[ |
INSERT or REPLACE → NORMAL; closes autocomplete first if it's open |
Esc in NORMAL |
Cancels a pending command, otherwise interrupts the agent as usual |
i a / I A |
INSERT before / after the cursor, at the first non-blank / line end |
o / O |
Open a line below / above |
R |
REPLACE: typed characters overwrite; Backspace restores |
v / V / Ctrl-V |
Visual, Visual line, Visual block |
After you submit a prompt, the editor is back in INSERT mode.
Motions
| Key | Motion |
|---|---|
h j k l |
Left, down, up, right |
w b e / W B E |
Word / WORD start, back, end |
ge / gE |
Back to the end of the previous word / WORD |
0 ^ $ |
Line start, first non-blank, last character |
gg / G / {n}G |
First line, last line, line n |
f F t T + char |
To / till a character on the line |
; / , |
Repeat the last f F t T / in reverse |
% |
Jump to the matching bracket |
Operators and text objects
d deletes, c changes, y yanks, gu lowercases, and gU uppercases.
Combine them with a motion (dw, c$, y3j, d%), double them for whole
lines (dd, cc, yy, guu, gUU), or use a text object:
| Object | Inner / around |
|---|---|
| word / WORD | iw aw / iW aW |
| quotes | i" a", i' a' |
| brackets | i( a(, i[ a[, i{ a{ (closing brackets work too) |
Quote and bracket objects stay on the current line.
Edits, undo, and repeat
| Key | Action |
|---|---|
x / X |
Delete the character under / before the cursor |
s / S |
Substitute a character / the line |
r + char |
Replace the character under the cursor |
~ |
Toggle case and move right |
D / C / Y |
Delete / change to the line end, yank the line |
J |
Join with the next line |
>> / << |
Indent / outdent by two spaces |
p / P |
Put after / before the cursor |
u |
Undo a whole change, such as ciwfoo<Esc> |
Ctrl-R |
Redo what u undid |
. / {n}. |
Repeat the last change, including Visual changes and typed text |
Deletes, changes, and yanks share one register. Yanks also go to the system
clipboard. Prefix a command with "+ or "* to use the system clipboard
explicitly: "+dd cuts a line to it, and "+p puts it. Edits that would cut
into a pasted block ([paste #1 +24 lines]) are refused.
Visual modes
Motions and text objects (viw, vi() extend the selection.
| Key | Action |
|---|---|
o / O |
Jump to the other end / the other corner of a block |
d x / c s / y |
Delete / change / yank the selection |
p |
Replace the selection with the register (not in a block) |
r + char |
Replace every selected character |
~ / u / U |
Toggle case, lowercase, uppercase |
J / > / < |
Join, indent, outdent the selected lines |
$ |
Block: extend to the end of every line |
I / A |
Block: insert / append on every line |
Quitting Pi
| Keys | Action |
|---|---|
ZZ, :q, :qa |
Quit if the prompt is empty |
ZQ, :q!, :qa! |
Quit, dropping the prompt |
The full spec, including where it differs from Vim, is in docs/ux.md.
🆚 Comparison
How pi-vim-editor compares with the most downloaded Vim extensions for Pi, based on reading their source as of October 2026:
| pi‑vim‑editor | pi‑vim | pi‑command‑deck | pi‑vim‑keys | pixit | pi‑vimmode | |
|---|---|---|---|---|---|---|
| Downloads/month | new | 2,766 | 1,017 | 916 | 462 | 337 |
| Keeps Pi's editor | ✅ | ❌ replaces it | ❌ replaces it | ❌ replaces it | ❌ replaces it | ❌ replaces it |
| Works with other editor extensions | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Inline working indicator | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Visual modes | v V Ctrl-V |
v V |
v V |
v V |
❌ | v V Ctrl-V |
| Operators | d c y gu gU |
d c y |
d c y gu gU g~ |
limited | d c y |
d c y gu gU g~ |
| Text objects | word, quotes, brackets | word, quotes, brackets | + paragraph | ❌ | word | + more |
| Counts | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
. repeat |
✅ | ✅ | ✅ | ❌ | ❌ | ⚠️ partial |
Ctrl-R redo |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Replace mode R |
✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
Search / ? n |
❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
| Macros, named registers | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| System clipboard | both ways | both ways | yanks | ❌ | ❌ | both ways |
| Ex commands | :q |
Pi commands | Pi commands | ❌ | ❌ | Pi commands, editing |
| Cursor shape per mode | ✅ opt-in¹ | ✅ | ✅ | ✅ | ❌ | ✅ |
¹ Requires Pi's hardware cursor and a terminal that supports cursor shapes.
⚙️ Configuration
To make plain p paste the system clipboard, and every delete and change
copy to it, as with Vim's clipboard=unnamedplus:
{ "vimEditor": { "clipboard": "unnamedplus" } }
Move the mode label to another corner in Pi's settings.json:
{ "vimEditor": { "indicator": "top-left" } }
Choose bottom-right (default), bottom-left, top-right, or top-left.
To also show the mode through the cursor shape, enable both settings:
{
"showHardwareCursor": true,
"vimEditor": { "cursorShape": true }
}
cursorShape defaults to false. When enabled, INSERT uses a steady bar,
NORMAL and Visual modes a steady block, and REPLACE a steady underline. Pi
still controls cursor visibility; with its hardware cursor hidden, the
software cursor stays unchanged.
Cursor shapes require DECSCUSR support in your terminal and, if used, tmux
or another multiplexer. Disable cursorShape if your terminal ignores the
sequences. The extension resets the shape with DECSCUSR 0, the terminal's
default (a blinking block in xterm), when the prompt loses focus, Pi opens an external editor or suspends,
or the extension shuts down or reloads. It does not query or restore your
pre-Pi cursor shape.