@thazhemadam/pi-vim
Vim-style modal editing integration for Pi.
Package details
Install @thazhemadam/pi-vim from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@thazhemadam/pi-vim- Package
@thazhemadam/pi-vim- Version
0.1.2- Published
- Aug 30, 2026
- Downloads
- 225/mo · 151/wk
- Author
- thazhemadam
- License
- LGPL-3.0-only
- Types
- extension
- Size
- 82.4 KB
- Dependencies
- 2 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@thazhemadam/pi-vim
A Pi extension for Vim-style modal editing in the prompt editor.
The extension provides colored mode labels, mode-specific cursor shapes, Visual selections, registers, and linear undo history. It uses @thazhemadam/vim-state for host-neutral editing behavior.
Requirements
- Node.js 22.19.0 or later
- Pi 0.79.8 or later
Install
Install the extension from npm:
pi install npm:@thazhemadam/pi-vim
To install a specific Git revision instead:
pi install git:github.com/thazhemadam/vim-state@<commit>
Then start or restart Pi. The prompt starts in Insert mode.
Run this Pi command to verify that the extension loaded:
/pi-vim-status
Use pi config to enable or disable the extension after installation. To remove an npm installation:
pi remove npm:@thazhemadam/pi-vim
First steps
- Type a prompt in Insert mode.
- Press
Escapeto enter Normal mode. - Use Vim commands to edit the prompt.
- Press
ito return to Insert mode. - Press
Enterin Normal mode to submit the prompt.
If autocomplete is open, the first Escape closes autocomplete. Press Escape again to enter Normal mode.
The label at the lower-right edge shows the active parser state:
INSERTNORMALOPERATORVISUALVISUAL LINEREPLACE
The terminal cursor also changes by mode. Insert mode uses a bar. Normal and Visual modes use a block. Replace and operator states use an underline.
Command reference
Only the commands listed below are supported. Host keys that pass through to Pi are described under Pi behavior.
Modes and insert entry
| Key | Action |
|---|---|
Escape |
Leave Insert, Replace, Visual, or operator-pending mode. |
i |
Insert before the cursor. |
a |
Insert after the cursor. |
I |
Insert before the first non-blank character. |
A |
Insert at the end of the line. |
o |
Open a line below and enter Insert mode. |
O |
Open a line above and enter Insert mode. |
r{char} |
Replace one character. |
R |
Enter Replace mode. |
v |
Enter character-wise Visual mode. |
V |
Enter line-wise Visual mode. |
Motions
| Key | Action |
|---|---|
h, j, k, l |
Move left, down, up, or right. |
0 |
Move to the start of the line. |
^, _ |
Move to the first non-blank character. |
$ |
Move to the end of the line. |
w, b, e |
Move by Vim-style words. |
W, B, E |
Move by whitespace-delimited WORDS. |
f{char}, F{char} |
Find a character forward or backward on the line. |
t{char}, T{char} |
Move just before a forward target or just after a backward target. |
gg |
Move to the first line. |
G |
Move to the last line. |
{count}gg, {count}G |
Move to the specified one-based line number. |
A word contains ASCII letters, digits, or _. Adjacent punctuation is a separate word. A WORD is any non-whitespace run.
Operators, edits, and registers
| Key | Action |
|---|---|
d{motion} |
Delete the motion range. |
c{motion} |
Change the motion range and enter Insert mode. |
y{motion} |
Yank the motion range. |
dd, cc, yy |
Delete, change, or yank whole lines. |
iw, aw |
Select an inner word or a word with surrounding whitespace after an operator. |
x, X |
Delete the character under or before the cursor. |
D, C |
Delete or change through the end of the line. |
p, P |
Put the unnamed register after or before the cursor. |
J |
Join lines. |
~ |
Toggle character case. |
u |
Undo one pi-vim edit. |
Ctrl-R |
Redo one pi-vim edit. |
Operators support h, j, k, l, 0, $, ^, _, w, b, e, W, B, E, f, F, t, and T. They also support iw and aw.
Counts work with:
h,j,k,l,w,b,e,W,B,E,f,F,t,T,gg, andGd,c, andywith those motions exceptggandG, with$, or asdd,cc, andyyx,X,D,C,p,P,J, and~
Counts do not apply to 0, ^, _, iw, or aw.
The editor stores at most 100 undo snapshots. One Insert or Replace session is one undo step. A new edit after undo clears the redo path.
Visual mode
Use h, j, k, l, 0, $, ^, _, w, b, e, W, B, E, or G to extend a Visual selection. Counts work with h, j, k, l, w, b, e, W, B, E, and G.
Then use one of these keys:
| Key | Action |
|---|---|
o, O |
Swap the selection anchor and active end. |
y |
Yank the selection. |
d, x |
Delete the selection. |
c |
Change the selection and enter Insert mode. |
p, P |
Replace the selection with the unnamed register. |
~ |
Toggle the case of the selection. |
u, U |
Convert the selection to lowercase or uppercase. |
J |
Join the selected lines. |
Clipboard and registers
Delete, change, yank, and Visual replacement commands write to the internal unnamed register. By default, the extension also copies these writes to the system clipboard.
Start Pi with this flag to keep register writes local:
pi --pi-vim-local-registers
This flag stops outgoing clipboard copies. The extension does not read clipboard text into the unnamed register.
Pi behavior
The adapter keeps these Pi editor behaviors:
Entersubmits a prompt in Insert, Normal, or Visual mode.- Pi retains its normal
UpandDownprompt-history behavior in Insert and Normal modes. - Pi clear, suspend, and exit shortcuts continue to work in Insert and Normal modes.
- In Normal mode,
Escaperuns the Pi interrupt action. - Pi autocomplete receives
Escapebefore Vim leaves Insert or Replace mode. - Programmatic text insertion creates one undoable edit.
Limitations
This package implements a Vim subset, not a Vim runtime. It does not support these features:
- Command-line mode and
:commands /and?search- Named registers
- Marks, macros, and key mappings
- The repeat command (
.) - Most text objects
- Plugins or a
vimrc
Positions use UTF-16 string columns, so some multi-code-point graphemes behave differently than they do in Vim.
If Pi's wrapped editor layout becomes incompatible, Visual commands still work, but pi-vim omits selection highlighting.
Local development
From the repository root:
npm ci
npm run dev:pi
The development command builds both packages and starts Pi with only the extensions in this checkout. It also inserts a multi-line sample prompt.
Run the package tests directly with:
npm test --workspace @thazhemadam/pi-vim
Run all repository checks before you submit a change:
npm run check
npm test
npm run check:packages
The package check verifies the tarball contents, production installation, and Pi loading. CI also builds a clean Git package without development dependencies.
Programmatic exports
The package default export is the Pi extension factory. It also exports these integration helpers:
VimPiEditornormalizePiKeypiInputToVimEventisPrintablePiInput
It re-exports the public API from @thazhemadam/vim-state.
License
This package uses the GNU Lesser General Public License v3.0 only. The package also includes the corresponding GNU GPL v3 text.