Integrate the opencode AI assistant with Neovim — streamline editor-aware research, reviews, and requests.
demo.mp4
Uses
opencode's currently undocumented API — latest tested version:v0.14.7
- Auto-connect to any
opencodeinside Neovim's CWD, or toggle an embedded instance. - Input prompts with completions, highlights, and normal-mode support.
- Select from a prompt library and define your own.
- Inject relevant editor context (buffer, cursor, selection, diagnostics, ...).
- Control
opencodewith commands. - Auto-reload buffers edited by
opencodein real-time. - Forward
opencode's Server-Sent-Events as Neovim autocmds for automation. - Sensible defaults with well-documented, flexible configuration and API to fit your workflow.
{
"NickvanDyke/opencode.nvim",
dependencies = {
-- Recommended for `ask()` and `select()`.
-- Required for `toggle()`.
{ "folke/snacks.nvim", opts = { input = {}, picker = {} } },
},
config = function()
vim.g.opencode_opts = {
-- Your configuration, if any — see `lua/opencode/config.lua`
}
-- Required for `vim.g.opencode_opts.auto_reload`
vim.opt.autoread = true
-- Recommended/example keymaps
vim.keymap.set({ "n", "x" }, "<leader>oa", function() require("opencode").ask("@this: ", { submit = true }) end, { desc = "Ask about this" })
vim.keymap.set({ "n", "x" }, "<leader>os", function() require("opencode").select() end, { desc = "Select prompt" })
vim.keymap.set({ "n", "x" }, "<leader>o+", function() require("opencode").prompt("@this") end, { desc = "Add this" })
vim.keymap.set("n", "<leader>ot", function() require("opencode").toggle() end, { desc = "Toggle embedded" })
vim.keymap.set("n", "<leader>oc", function() require("opencode").command() end, { desc = "Select command" })
vim.keymap.set("n", "<leader>on", function() require("opencode").command("session_new") end, { desc = "New session" })
vim.keymap.set("n", "<leader>oi", function() require("opencode").command("session_interrupt") end, { desc = "Interrupt session" })
vim.keymap.set("n", "<leader>oA", function() require("opencode").command("agent_cycle") end, { desc = "Cycle selected agent" })
vim.keymap.set("n", "<S-C-u>", function() require("opencode").command("messages_half_page_up") end, { desc = "Messages half page up" })
vim.keymap.set("n", "<S-C-d>", function() require("opencode").command("messages_half_page_down") end, { desc = "Messages half page down" })
end,
}nixvim
programs.nixvim = { extraPlugins = [ pkgs.vimPlugins.opencode-nvim ]; };
opencode.nvim provides a rich and reliable default experience — see all available options and their defaults here.
Send a prompt. The main entrypoint — build on it!
Replaces placeholders with the corresponding contexts:
| Placeholder | Context |
|---|---|
@buffer |
Current buffer |
@buffers |
Open buffers |
@cursor |
Cursor position |
@selection |
Visual selection |
@this |
Visual selection if any, else cursor position |
@visible |
Visible text |
@diagnostics |
Current buffer diagnostics |
@quickfix |
Quickfix list |
@diff |
Git diff |
@grapple |
grapple.nvim tags |
Input a prompt.
- Highlights placeholders.
- Completes placeholders.
- Press
<Tab>to trigger built-in completion. - When using
blink.cmpandsnacks.input, registersopts.auto_register_cmp_sources.
- Press
- Press
<Up>to browse recent inputs.
Select from prompts to review, explain, and improve your code:
| Description | Prompt |
|---|---|
ask |
(user input required) |
explain |
Explain @this and its context |
optimize |
Optimize @this for performance and readability |
document |
Add comments documenting @this |
test |
Add tests for @this |
review |
Review @this for correctness and readability |
diagnostics |
Explain @diagnostics |
fix |
Fix @diagnostics |
diff |
Review the following git diff for correctness and readability: @diff |
add_buffer |
@buffer |
add_this |
@this |
Tip
Create keymaps for your favorite prompts:
vim.keymap.set({ "n", "x" }, "<leader>oe", function() local explain = require("opencode.config").opts.prompts.explain require("opencode").prompt(explain.prompt, explain) end, { desc = "Explain this" })
Send a command:
| Command | Description |
|---|---|
session_new |
Start a new session |
session_share |
Share the current session |
session_interrupt |
Interrupt the current session |
session_compact |
Compact the current session (reduce context size) |
messages_page_up |
Scroll messages up by one page |
messages_page_down |
Scroll messages down by one page |
messages_half_page_up |
Scroll messages up by half a page |
messages_half_page_down |
Scroll messages down by half a page |
messages_first |
Jump to the first message in the session |
messages_last |
Jump to the last message in the session |
agent_cycle |
Cycle the selected agent |
Supports all commands — these are just the most useful ones
Toggle an embedded opencode terminal (requires snacks.nvim).
opencode.nvim connects to any opencode inside Neovim's CWD, but provides this for quickstart.
To use your own method (terminal app or plugin, multiplexer, etc.), launch opencode with it and optionally override vim.g.opencode_opts.on_opencode_not_found and vim.g.opencode_opts.on_send for convenience, then use opencode.nvim normally.
opencode.nvim forwards opencode's Server-Sent-Events as an OpencodeEvent autocmd:
-- Listen for `opencode` events vim.api.nvim_create_autocmd("User", { pattern = "OpencodeEvent", callback = function(args) -- See the available event types and their properties vim.notify(vim.inspect(args.data)) -- Do something useful if args.data.type == "session.idle" then vim.notify("`opencode` finished responding") end end, })
- Inspired by nvim-aider, neopencode.nvim, and sidekick.nvim.
- Uses
opencode's TUI for simplicity — see sudo-tee/opencode.nvim for a Neovim frontend. - mcp-neovim-server may better suit you, but it lacks customization and tool calls are slow and unreliable.