{"_id":"@bingzizkli/pi-vimmode","_rev":"2-0511d65d388b527c175284a055a7e4dd","name":"@bingzizkli/pi-vimmode","dist-tags":{"latest":"0.9.0-yy.10"},"versions":{"0.9.0-yy.9":{"name":"@bingzizkli/pi-vimmode","version":"0.9.0-yy.9","keywords":["pi","pi-extension","pi-package"],"author":{"name":"pekochan069"},"license":"MIT","_id":"@bingzizkli/pi-vimmode@0.9.0-yy.9","maintainers":[{"name":"bingzizkli","email":"2111576411@qq.com"}],"contributors":[{"url":"fork maintainer","name":"bingDai21"}],"homepage":"https://github.com/bingDai21/pi-vimmode#readme","bugs":{"url":"https://github.com/bingDai21/pi-vimmode/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"67b6f65804cf3beae1591822871a7e59a139f259","tarball":"https://registry.npmjs.org/@bingzizkli/pi-vimmode/-/pi-vimmode-0.9.0-yy.9.tgz","fileCount":63,"integrity":"sha512-9t5pTxPC/GjFaDbDSfGrNUdubTfAHkfDyQqoX1BXA5R4o9U4YB8lRWwIIMxvkcNG9xeJZyDrTAub/zYy/HCrIQ==","signatures":[{"sig":"MEQCIEUwcKX7ZBipNsBnX9V6tMl1UdPb2DFlQTn8V6ePGbjfAiA2S/q0SFaIkrgcgoEOibU49qYEISoDYipUYvk8k1/Aag==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1351615},"type":"module","module":"index.ts","gitHead":"4b5f4663dabb611fe3c031a08f15ae192dd23f3e","private":false,"scripts":{"lint":"oxlint","test":"bun test","build":"rolldown -c","format":"oxfmt","verify":"bun run check-types && bun run lint && bun run test","prepare":"lefthook install","lint:fix":"oxlint --fix","prepublish":"bun run build && bun run verify-package","check-types":"tsc --noEmit","format:check":"oxfmt --check","verify-package":"bun scripts/verify-package.ts","check:config-reference":"bun scripts/generate-config-reference.ts --check","generate:config-reference":"bun scripts/generate-config-reference.ts"},"_npmUser":{"name":"bingzizkli","email":"2111576411@qq.com"},"repository":{"url":"git+https://github.com/bingDai21/pi-vimmode.git","type":"git"},"_npmVersion":"11.17.0","description":"Vim mode for Pi coding agent (fork of pi-vimmode with local enhancements)","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.60.0","oxlint":"^1.75.0","lefthook":"^2.1.10","rolldown":"^1.2.0","bun-types":"^1.3.14","typescript":"^7.0.2","@earendil-works/pi-tui":"^0.77.0","oxlint-plugin-complexity":"^2.1.6","@earendil-works/pi-coding-agent":"^0.77.0"},"peerDependencies":{"@earendil-works/pi-tui":"^0.77.0","@earendil-works/pi-coding-agent":"^0.77.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-vimmode_0.9.0-yy.9_1787639498849_0.21801306175524027","host":"s3://npm-registry-packages-npm-production"}},"0.9.0-yy.10":{"name":"@bingzizkli/pi-vimmode","version":"0.9.0-yy.10","private":false,"description":"Vim mode for Pi coding agent (fork of pi-vimmode with local enhancements)","keywords":["pi","pi-extension","pi-package"],"homepage":"https://github.com/bingDai21/pi-vimmode#readme","bugs":{"url":"https://github.com/bingDai21/pi-vimmode/issues"},"license":"MIT","author":{"name":"pekochan069"},"contributors":[{"name":"bingDai21","url":"fork maintainer"}],"repository":{"type":"git","url":"git+https://github.com/bingDai21/pi-vimmode.git"},"type":"module","module":"index.ts","publishConfig":{"access":"public"},"scripts":{"build":"rolldown -c","verify-package":"bun scripts/verify-package.ts","generate:config-reference":"bun scripts/generate-config-reference.ts","check:config-reference":"bun scripts/generate-config-reference.ts --check","prepublish":"bun run build && bun run verify-package","format":"oxfmt","format:check":"oxfmt --check","lint":"oxlint","lint:fix":"oxlint --fix","test":"bun test","check-types":"tsc --noEmit","verify":"bun run check-types && bun run lint && bun run test","prepare":"lefthook install"},"devDependencies":{"@earendil-works/pi-coding-agent":"^0.77.0","@earendil-works/pi-tui":"^0.77.0","bun-types":"^1.3.14","lefthook":"^2.1.10","oxfmt":"^0.60.0","oxlint":"^1.75.0","oxlint-plugin-complexity":"^2.1.6","rolldown":"^1.2.0","typescript":"^7.0.2"},"peerDependencies":{"@earendil-works/pi-coding-agent":"^0.77.0","@earendil-works/pi-tui":"^0.77.0"},"pi":{"extensions":["./index.ts"]},"gitHead":"1cbdcd7af4b9748199d793f7abd6b92aa78b4749","_id":"@bingzizkli/pi-vimmode@0.9.0-yy.10","_nodeVersion":"24.18.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-yVRRzeRQmOf4eCvida13gpO2Qxc89iU6ZRBCxchV/CVBSn40xvzJNeOqu050rD1V1CzQjj8AF8FX/1xJjWndvA==","shasum":"c9675e07ed57991fb80ad4a68dd22af73d4100db","tarball":"https://registry.npmjs.org/@bingzizkli/pi-vimmode/-/pi-vimmode-0.9.0-yy.10.tgz","fileCount":63,"unpackedSize":1341392,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCeOvTa//i4oONHXpiLpcmR/eh64xbABqXX/6/yDwG1BQIhALB2Eb1ixQw9RHF4xh3ToQXbmG38Ks9IuU/ui6ZZYMaF"}]},"_npmUser":{"name":"bingzizkli","email":"2111576411@qq.com"},"directories":{},"maintainers":[{"name":"bingzizkli","email":"2111576411@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-vimmode_0.9.0-yy.10_1787719313738_0.07529364880303291"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-25T06:31:38.696Z","modified":"2026-08-26T04:41:54.040Z","0.9.0-yy.9":"2026-08-25T06:31:39.006Z","0.9.0-yy.10":"2026-08-26T04:41:53.900Z"},"bugs":{"url":"https://github.com/bingDai21/pi-vimmode/issues"},"author":{"name":"pekochan069"},"license":"MIT","homepage":"https://github.com/bingDai21/pi-vimmode#readme","keywords":["pi","pi-extension","pi-package"],"repository":{"type":"git","url":"git+https://github.com/bingDai21/pi-vimmode.git"},"description":"Vim mode for Pi coding agent (fork of pi-vimmode with local enhancements)","contributors":[{"name":"bingDai21","url":"fork maintainer"}],"maintainers":[{"name":"bingzizkli","email":"2111576411@qq.com"}],"readme":"# pi-vimmode (@bingzizkli/pi-vimmode)\n\n> **[中文] 这是修改版 Fork** —— 上游项目地址: **https://github.com/pekochan069/pi-vimmode**\n> （上游 npm 包名 `pi-vimmode`，作者 pekochan069，MIT 许可证。本仓库沿用 MIT 许可证并保留原版权声明。）\n>\n> 相对上游的修改（按提交顺序）：\n>\n> 1. **remap 可扩展内置操作符前缀** —— `yy`→`\"+yy` 这类重映射不再遮蔽 `y` 操作符本身（`yw`/`y$` 等仍可用）\n> 2. **移除 Ex 命令行模式** —— 按 `:` 不再进入命令行\n> 3. **移除 footer 的 \"vim\" 状态段**\n> 4. **visual 模式文本对象** —— `viw`/`va\"`/`vi(` 直接在可视模式下生效\n> 5. **yank 高亮** —— 仿 neovim `vim.highlight.on_yank()`，yank 时选区反色闪烁 100ms\n> 6. **修复 Backspace 解析** —— `keySequence` 将 DEL(0x7f) 排除出可打印快路径，使 `<backspace>` remap 生效\n> 7. **新增 `command.quit` action** —— 可绑定按键退出 Pi，如 `vim.keymap.set(\"n\", \"<c-d>\", vim.action.command.quit(), { allowProtected: true })`\n> 8. **移除 EasyMotion 支持** —— 上游的 easymotion 代码与设置已完全删除\n> 9. **修复可视模式带计数移动** —— 计数不再残留 pending，重放映射（如 `H`→`4h`）可连续使用\n> 10. **修复 Windows 撤销/重做** —— `u` 直接调用底层撤销，不再依赖被平台改绑的快捷键\n> 11. **Windows 剪贴板读取提速** —— 常驻 PowerShell 工作进程，粘贴从 ~1.3s 降至毫秒级，且异步落地后立即刷屏\n\nVim-style prompt editing for [Pi](https://pi.dev/).\n\n`pi-vimmode` replaces Pi's main input editor with a `CustomEditor`-based modal editor. It targets practical prompt editing for agent prompts, not full Vim parity.\n\n## Breaking changes\n\n### v0.7.0\n\n- `Ctrl-v` no longer enters visual block mode by default. `Ctrl-v`, Windows `Alt-v`, and `Ctrl-Alt-v` are delegated to Pi for image/clipboard paste in normal and visual modes unless explicitly rebound.\n- Visual block mode now has an empty default keybinding. Configure `piVimMode.keymap.commands.visualBlock` with a non-protected key such as `<A-b>`, or explicitly allow and bind `<C-v>` if Vim-style visual block is more important than Pi image paste in your workflow.\n\n```json\n{\n  \"piVimMode\": {\n    \"keymap\": {\n      \"commands\": { \"visualBlock\": [\"<A-b>\"] }\n    }\n  }\n}\n```\n\nTo intentionally reclaim `Ctrl-v` for visual block:\n\n```json\n{\n  \"piVimMode\": {\n    \"keymap\": {\n      \"commands\": { \"visualBlock\": [\"<C-v>\"] },\n      \"allowProtectedOverrides\": [\"<C-v>\"]\n    }\n  }\n}\n```\n\n## Install / load\n\nInstall from npm:\n\n```sh\npi install npm:pi-vimmode\n```\n\nor Install from Git to install latest version:\n\n```sh\npi install git:https://github.com/pekochan069/pi-vimmode\n```\n\nFor local development from this checkout:\n\n```sh\nbun install\n```\n\nPi discovers the extension through `package.json`:\n\n```json\n{\n  \"pi\": {\n    \"extensions\": [\"./index.ts\"]\n  }\n}\n```\n\nFor local testing, load this package as a Pi extension using Pi's normal extension loading flow.\n\n### Compatibility with extensions that modifies editor\n\nPi currently exposes a single custom-editor factory which makes last extension could overrides previous editor factories.\\\nCurrently, `pi-vimmode` is implemented with `CustomEditor` which cannot decorate an arbitrary editor instances provided by other extensions.\nThis means editor extensions that maintain per-instance state, such as history or additional editor behavior, may lose that state when their factory is replaced.\n\nUntil pi supports composable order independant editor extension api, you should load pi-vimmode in front of other extensions that set editor component, like `@zigai/pi-prompt-history`.\nLoad `pi-vimmode` before other extensions in `settings.json`:\n\n```json\n{\n  \"packages\": [\"pi-vimmode\", \"another-editor-extension\"]\n}\n```\n\nSee issue #16 for more information.\n\n## Quick start\n\n1. Start Pi with the extension loaded.\n2. Type normally in insert mode.\n3. Press `Esc` to enter normal mode when autocomplete is inactive.\n4. Use supported Vim commands such as `h`, `j`, `k`, `l`, `w`, `b`, `e`, `0`, `$`, `i`, `a`, `x`, `dd`, `cw`, `p`, `/`, `n`, `N`, `v`, `V`, configured visual block, `:s`, `:d`, `:y`, `:pu`, `:t`, `:m`, `:j`, `:noh`, `q`, `@`, and `@@`.\n5. Press `i`, `a`, `I`, `A`, `o`, `O`, `C`, `s`, or `S` to return to insert mode after edits; use operator forms such as `cw`, `cc`, or `c$` when changing by motion.\n\nDefault modes:\n\n- **INSERT**: Pi-like text entry. Autocomplete, submit, newlines, image paste, external editor, and app shortcuts use Pi's default behavior.\n- **NORMAL**: supported Vim command mode. Unsupported printable keys are ignored.\n- **VISUAL**: characterwise selection.\n- **V-LINE**: linewise selection.\n- **V-BLOCK**: rectangular block selection.\n\n`Esc` in normal mode delegates to Pi so interrupt/abort behavior still works. `Esc` in visual modes cancels the selection and returns to normal mode.\n\n## Documentation\n\nCanonical user-facing docs live under `docs/`:\n\n- [`docs/features.md`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/features.md): supported modes, motions, edits, operators, prompt-native text objects, prompt transforms, character search, prompt search, visual modes, Ex command-line commands, registers, marks, macros, UI/status rendering, Pi shortcut compatibility, limitations, recovery, and validation examples.\n- [`docs/settings.md`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/settings.md): every supported `piVimMode` setting, defaults, accepted value shapes, merge behavior, key sequence syntax, protected-key validation, warnings, troubleshooting, and practical config examples.\n- [`docs/adr/0002-user-facing-pi-vimmode-docs.md`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/adr/0002-user-facing-pi-vimmode-docs.md): documentation source-of-truth decision and maintenance rules.\n\nREADME is the quickstart and index. Keep detailed behavior and settings reference in the canonical docs above.\n\n## Common configuration\n\nMinimal startup override:\n\n```json\n{\n  \"piVimMode\": {\n    \"startMode\": \"normal\"\n  }\n}\n```\n\nExample keymap/UI override:\n\n```json\n{\n  \"piVimMode\": {\n    \"leader\": \" \",\n    \"cursor\": {\n      \"normal\": \"block\",\n      \"insert\": \"bar\"\n    },\n    \"keymap\": {\n      \"commands\": {\n        \"startSearch\": [\"/\"],\n        \"showKeybindings\": [\"<leader>k\"]\n      }\n    },\n    \"ui\": {\n      \"status\": {\n        \"items\": [\"mode\", \"pending\", \"search\", \"macro\", \"cursorPosition\", \"warnings\"]\n      }\n    }\n  }\n}\n```\n\nTrusted global JS keybindings live at `~/.pi/agent/pi-vimmode.config.js` and run as unsandboxed local code with full Pi process privileges. See [trusted JavaScript config guide](https://github.com/pekochan069/pi-vimmode/blob/main/docs/config.md#basic-setup):\n\n```js\n/** @type {import(\"./npm/node_modules/pi-vimmode/config\").VimConfig} */\nexport default (vim) => {\n  vim.g.mapleader = \" \";\n  vim.keymap.set(\"i\", \"<A-w>\", vim.prompt.deleteWordBackward());\n  vim.keymap.set(\"n\", \"<leader>q\", vim.prompt.reflow({ width: 88 }));\n  vim.keymap.set(\"n\", \"ZD\", \":vimdoctor<CR>\");\n};\n```\n\nRun `/vimmode reload` after editing root JS config. See [`docs/config.md`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/config.md) for complete trusted JavaScript API, workflows, reload, and safety contract. See [`docs/settings.md`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/settings.md) for canonical JSON defaults and settings.\n\n## Recover or disable\n\nIf the extension blocks editing or configuration goes wrong:\n\n- Run `/vimmode off` to restore Pi's previous editor for the current extension runtime.\n- Run `/vimmode on` or `/vimmode` to enable the Vim editor again.\n- Start with [`docs/features.md#disable-or-recover`](https://github.com/pekochan069/pi-vimmode/blob/main/docs/features.md#disable-or-recover).\n- Use `pi list` to inspect installed extensions.\n- Use `pi remove` or `pi uninstall` with the installed extension identifier to remove it.\n- Use `pi config` or edit Pi config files to remove `piVimMode` overrides.\n- Restart Pi after changing extension or config state.\n\n## Architecture\n\n`VimEditor` is the Pi adapter shell. It owns `CustomEditor` integration, snapshots, effect application, rendering bridge, public cursor restoration, and best-effort terminal cursor writes. Insert-mode `bar` hardware cursors stay visible while Pi agent work is active; non-bar cursors are suppressed during busy output.\n\nModal editing behavior lives under `src/modal/`:\n\n- `engine.ts` owns mode transitions, finite semantic key dispatch, register updates, and supported Vim semantics.\n- `types.ts` defines adapter-applied effects such as delegation, edits, macro replay, cursor restoration, invalidation, and terminal cursor hints.\n- `view.ts` derives mode labels, status items, visual status text, and cursor position text without needing Pi TUI objects.\n\nThe parser in `src/commands.ts` and text transforms in `src/buffer.ts` remain pure helpers. Config maps keys to supported semantic actions; it does not add private Pi APIs, recursive mappings, `.vimrc`, Vimscript, or Neovim Lua support.\n\n## Project docs\n\n- `docs/features.md`: canonical feature guide.\n- `docs/settings.md`: canonical settings reference.\n- `docs/adr/`: documentation and architecture decisions.\n- `docs/plans/`: implementation plans for Vim editor work.\n- `docs/solutions/`: reusable learnings for parser, buffer, lifecycle, and visual-mode bugs.\n- `openspec/specs/`: durable OpenSpec requirements for supported Vim behavior.\n\n## Validate\n\n```sh\nbun test\nbun run check-types\nbun run lint\nbun run format:check\nbun run build\nbun run verify-package\nbun pm pack --dry-run\n```\n\nBefore publishing, inspect dry-run package contents and confirm extension entrypoint plus runtime source/build output are included, not docs only.\n\nManual smoke checklist:\n\n1. Load extension in Pi.\n2. Type text in insert mode.\n3. Press `Esc`, use normal-mode motions and edits.\n4. Use `v`, `V`, and a configured visual-block binding such as `<A-b>`; confirm visual highlighting and selection operations.\n5. Configure `piVimMode.startMode`, `piVimMode.cursor`, a keymap binding, and UI status items; confirm behavior changes.\n6. Confirm insert/normal submit and normal-mode `Esc` still delegate to Pi where expected.\n7. Record and replay a macro with `q{slot}`, `@{slot}`, and `@@`.\n8. Run `/query`, `n`, `N`, `:%s/old/new/g`, `:2,3copy$`, `:move0`, and `:noh`; confirm prompt-local search/Ex behavior.\n","readmeFilename":"README.md"}