背景
用 pi 写代码时,AI 经常批量修改文件。时间久了容易忘了改过哪些文件、是否有遗漏。我希望能随时一键查看工作区文件的变更状态——像 git status 但不用切出去、不用手指离开键盘。
之前写过 pi 的 CustomEditor 扩展把光标改成竖线。这次更进一步:利用 pi 的 overlay(浮动框) + shortcut(快捷键) + status bar(状态栏) 三项能力,做了一个完整的 Git 变更查看器。
直接体验
你可以直接运行下面的命令安装本文的插件的最新版本,下文的描述可能会有过期
| |
需求
- 随时可看——一键唤起浮动面板,列出所有变更文件
- 分类清晰——区分 Staged / Unstaged / Untracked / Conflict
- 快速操作——
Enter:文件路径填入输入框(交给 AI 处理)e:用 nvim 打开编辑/查看y:复制完整文件路径到系统剪贴板
- 无感提示——状态栏常驻显示变更计数,提醒有未提交的改动
实现方法
整体架构
| |
关键 API
| API | 用途 |
|---|---|
pi.registerShortcut("ctrl+shift+g", ...) | 全局快捷键,任何位置一键唤起 |
ctx.ui.custom(component, { overlay: true }) | 渲染浮动框,叠加在当前 UI 之上 |
ctx.ui.setStatus(key, text) | footer 状态栏常驻显示 |
ctx.ui.setEditorText(text) | 将文本放入输入框 |
pi.exec("git", ["status", "--porcelain"]) | 获取 git 变更(异步,复用 pi 进程管理) |
matchesKey(data, Key.escape) | TUI 键盘事件匹配(兼容各种终端协议) |
truncateToWidth() / visibleWidth() | ANSI-aware 字符串截断/宽度计算 |
浮动框渲染
浮动框使用 Unicode box-drawing 字符绘制边框(╭╮╰╯│─),内部按分类分组渲染:
- 文件行用
padToWidth()补齐到统一宽度,保证右边框对齐 - 选中行高亮显示(
▶前缀 + accent 色) - 状态标签按类别着色:绿
[+]=staged、黄[*]=modified、红[-]=deleted、灰[?]=untracked - 底部提示栏显示全部快捷键
剪贴板:OSC 52
y 键复制文件路径到系统剪贴板不依赖 xclip / wl-copy 等外部工具,而是通过 OSC 52(Operating System Command 52)终端转义序列:
| |
现代终端(Kitty、Ghostty、WezTerm、Alacritty、Foot、iTerm2)均支持,零依赖、跨平台。
nvim 编辑:spawnSync
e 键通过 Node.js spawnSync 以 stdio: "inherit" 方式启动 nvim,让 nvim 直接接管终端:
| |
退出 nvim 后控制权自动回到 pi,TUI 会重绘恢复。
完整代码
https://github.com/joyanhui/pi-extension/tree/main/pi-ext-git-changes
效果
浮动框
| |
状态栏
| |
操作速查
| 按键 | 效果 |
|---|---|
ctrl+shift+g | 全局唤起浮动框 |
Enter | 文件路径填入输入框,交给 AI |
e | nvim 打开文件编辑/查看 |
y | 复制完整路径到系统剪贴板(OSC 52) |
Esc | 关闭浮动框 |
总结
这次扩展利用了 pi 的三个扩展能力:
- Overlay(
ctx.ui.custom+overlay: true)——浮动框不破坏主 UI 状态,查看完即关 - Shortcut(
pi.registerShortcut)——ctrl+shift+g与全局键位不冲突(比ctrl+shift+upreset、ctrl+shift+pplan mode 等默认未占用) - Status bar(
ctx.ui.setStatus)——变更计数无感常驻,配合tool_result事件自动刷新
结合 bar-cursor 扩展 和 NixOS home-manager 的 activation 脚本软链接管理,pi 的整个配置都是声明式、可追溯的。TypeScript 扩展放到 ~/.pi/agent/extensions/ 目录就自动加载,/reload 热更新,开发体验很流畅。
另见:
- pi 美化插件:输入框光标改为竖线(bar-cursor) — 基于 CustomEditor 扩展,方块光标换成终端原生竖线
- pi 插件:浮动终端(float-term) — 基于 node-pty + overlay,在 pi 内随时唤起 fish / lazygit / yazi 浮动终端