OpencodeNvim插件使用
opencode.nvim 使用方法笔记
#type / howto
#status / evergreen
#resource / opencode-nvim
#topic / plugin
#media / website
[!info] related notes
- 公开市场操作
- open-router
- OpenAI Codex
- LLM Provider 抽象层设计
- OpenAI Whisper 直接让 copilot 从 官方仓库中总结的, updated 即为总结时间
opencode.nvim 使用方法笔记
目的:把 opencode AI 助手接入 Neovim,能够把编辑器上下文(当前文件/选区/诊断等)一起发给 opencode,并在 Neovim 内完成提问、选择动作、执行命令、监听事件等。
1. 功能概览
- 自动连接到 Neovim 当前工作目录(CWD) 中运行的任意
opencode服务;也可以由插件“托管”一个实例 - 支持注入编辑器上下文:buffer/selection/diagnostics/quickfix/git diff 等
- 交互输入框支持:补全、高亮、最近历史、Normal 模式编辑
- 内置 Prompt 库 + 支持自定义 Prompts
- 可执行 opencode 命令(如 session 操作、滚动、撤销重做等)
- 实时转发 opencode 的 SSE 事件为 Neovim autocmd
- 可选:提供 in-process LSP(实验性)
- 支持 operator / ranges / dot-repeat(更 Vim 的操作方式)
2. 安装与基础配置
2.1 lazy.nvim 示例
{
"nickjvandyke/opencode.nvim",
version = "*",
dependencies = {
{
-- 可选但推荐:增强输入与选择器体验
"folke/snacks.nvim",
optional = true,
opts = {
input = {}, -- 增强 ask()
picker = { -- 增强 select()
actions = {
opencode_send = function(...)
return require("opencode").snacks_picker_send(...)
end,
},
win = {
input = {
keys = {
["<a-a>"] = { "opencode_send", mode = { "n", "i" } },
},
},
},
},
terminal = {}, -- 启用 snacks provider
},
},
},
config = function()
vim.g.opencode_opts = {
-- 你的配置(可留空使用默认值)
}
vim.o.autoread = true -- 如果你要用文件自动 reload(events.reload),建议开启
-- 推荐 keymaps(可按需改成 <leader>o...)
vim.keymap.set({ "n", "x" }, "<C-a>", function()
require("opencode").ask("@this: ", { submit = true })
end, { desc = "Ask opencode…" })
vim.keymap.set({ "n", "x" }, "<C-x>", function()
require("opencode").select()
end, { desc = "Execute opencode action…" })
vim.keymap.set({ "n", "t" }, "<C-.>", function()
require("opencode").toggle()
end, { desc = "Toggle opencode" })
vim.keymap.set({ "n", "x" }, "go", function()
return require("opencode").operator("@this ")
end, { desc = "Add range to opencode", expr = true })
vim.keymap.set("n", "goo", function()
return require("opencode").operator("@this ") .. "_"
end, { desc = "Add line to opencode", expr = true })
end,
}
2.2 nixvim 示例
programs.nixvim = {
extraPlugins = [
pkgs.vimPlugins.opencode-nvim
];
};
2.3 健康检查
安装后运行:
:checkhealth opencode
3. 核心概念:Contexts(上下文占位符)
插件会把 Prompt 中的占位符替换为对应上下文:
| 占位符 | 含义 |
|---|---|
@this | 当前选区/操作范围;没有则为光标位置 |
@buffer | 当前 buffer |
@buffers | 所有打开的 buffers |
@visible | 当前可见文本 |
@diagnostics | 当前 buffer 的诊断信息 |
@quickfix | quickfix 列表 |
@diff | git diff |
@marks | 全局 marks |
@grapple | grapple.nvim 标签 |
4. 内置 Prompts(示例)
用于“解释/修复/评审/生成测试”等常见任务,可在 select() 里选,也可 prompt() 里引用:
| 名称 | 内容 |
|---|---|
diagnostics | Explain @diagnostics |
diff | Review the following git diff… @diff |
document | Add comments documenting @this |
explain | Explain @this and its context |
fix | Fix @diagnostics |
implement | Implement @this |
optimize | Optimize @this… |
review | Review @this… |
test | Add tests for @this |
5. Provider(opencode 实例来源/托管方式)
5.1 工作方式
- 你可以自己在 Neovim 的 CWD 启动
opencode,插件会自动发现并连接 - 如果找不到已有实例,插件会用配置的 provider 来帮你启动/管理一个
必须用
opencode --port ...暴露服务端口(providers 默认会这样做)
5.2 可选 Provider(README 中列出的)
- Neovim 内置 terminal
snacks.terminal- kitty
- wezterm
- tmux
- custom(自定义 toggle/start/stop)
配置形态(示例):
vim.g.opencode_opts = {
provider = {
enabled = "terminal", -- 或 "snacks"/"kitty"/"wezterm"/"tmux"
terminal = {
-- ...
}
}
}
6. 日常使用入口(最常用的 5 个)
快捷方式
1. 核心对话组(最常用)
这部分是和 AI “聊天”的入口:
| 快捷键 | 动作 | 解释 |
|---|---|---|
<C-a> | Ask | 询问 AI。它会自动带上 @this(当前上下文),让你直接输入问题。 |
<C-x> | Select | 执行动作。弹出一个菜单让你选(比如解释代码、重构、找 Bug)。 |
<C-.> | Toggle | 侧边栏开关。像打开终端一样把 AI 对话框呼出或隐藏。 |
2. 算子模式组 (Operator Pending)
这是最“Vim 化”但也最难理解的部分。它模仿了 d (delete) 或 y (yank) 的逻辑:
go+ {范围}:将指定范围的代码发给 AI。- 例如:
gow(发送当前单词),goap(发送整个段落)。
- 例如:
goo:发送当前行。- 类比:就像
dd删一行,goo就是把这一行“喂”给 AI。
- 类比:就像
3. 滚动与导航(对话框内)
当你呼出了 AI 窗口,想在里面翻页时:
| 快捷键 | 动作 |
|---|---|
<S-C-u> | 向上翻半页 (Shift + Ctrl + U) |
<S-C-d> | 向下翻半页 (Shift + Ctrl + D) |
4. “补偿型”重映射(改变习惯)
因为这个插件强行占用了原生的 <C-a> 和 <C-x>,为了不让你没法给数字加减,它在最后做了两行补偿:
+:现在代替了原来的<C-a>(数字加 1)。-:现在代替了原来的<C-x>(数字减 1)。
6.1 Ask:require("opencode").ask()
用途:直接输入一段 prompt 发给 opencode。
交互要点:
<Up>浏览历史输入<Tab>触发内建补全(上下文和子 agent)- 以
\n结尾:追加而不是提交 - 如果使用
snacks.input:可用<S-CR>追加且补全更强(LSP)
6.2 Select:require("opencode").select()
用途:从一个“功能列表”里选择执行:
- Prompts
- Commands(会从 opencode 拉取自定义命令)
- Provider controls(启动/停止/切换等)
使用 snacks.picker 时会有高亮与预览。
6.3 Prompt:require("opencode").prompt()
用途:更“底层”的 prompt 调用方式:
- 解析引用的命名 prompt
- 注入 contexts(如
@this、@diff等) opencode本身还会解释@引用(文件或 subagent)
6.4 Operator:require("opencode").operator()
用途:把 prompt() 包装成 Vim operator:
- 支持范围(range / visual selection)
- 支持 dot-repeat(
.重复操作)
6.5 Command:require("opencode").command()
用途:直接执行 opencode 的指令(常用于 session 管理/滚动等)。
常见命令(节选):
- 会话:
session.list/session.new/session.select/session.share - 中断/压缩:
session.interrupt/session.compact - 滚动:
session.page.up/session.page.down/session.half.page.up/session.half.page.down - 跳转:
session.first/session.last - 撤销重做:
session.undo/session.redo - prompt:
prompt.submit/prompt.clear - agent:
agent.cycle
7. Provider terminal 内置按键(buffer-local)
在 provider 的 terminal buffer 里,插件会设置类似 Neovim 的导航键:
| Key | Command | 说明 |
|---|---|---|
<C-u> | session.half.page.up | 上滚半页 |
<C-d> | session.half.page.down | 下滚半页 |
<Esc> | session.interrupt | 中断 |
gg | session.first | 到第一条消息 |
G | session.last | 到最后一条消息 |
8. Events(把 opencode SSE 转为 autocmd)
插件会把事件转发成 User autocmd:OpencodeEvent:*
示例:
vim.api.nvim_create_autocmd("User", {
pattern = "OpencodeEvent:*",
callback = function(args)
local event = args.data.event
local port = args.data.port
vim.notify(vim.inspect(event))
if event.type == "session.idle" then
vim.notify("`opencode` finished responding")
end
end,
})
额外行为:
- Edits:opencode 改文件时,自动 reload buffer
- Permissions:请求权限时,插件会等 idle 后让你批准/拒绝
9. 状态栏集成(lualine 示例)
require("lualine").setup({
sections = {
lualine_z = {
{ require("opencode").statusline },
},
},
})
10. LSP(实验性)
启用:
vim.g.opencode_opts = {
lsp = { enabled = true },
}
能力(README 提到的):
- Hover:让 opencode 简要解释光标下符号
- Code Actions:解释/修复光标下诊断
11. 配置默认值位置
完整可配项及默认值在:
./lua/opencode/config.lua
(可在仓库中查看以便按需覆盖)