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.1
- 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, ...).
- 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>o+", function() require("opencode").prompt("@this") end, { desc = "Add this" })
vim.keymap.set({ "n", "x" }, "<leader>os", function() require("opencode").select() end, { desc = "Select prompt" })
vim.keymap.set("n", "<leader>ot", function() require("opencode").toggle() end, { desc = "Toggle embedded" })
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", "<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
Select from prompts to review, explain, and improve your code:
| Description | Prompt |
|---|---|
| Ask… | (user input required) |
| Explain this | Explain @this and its context |
| Optimize this | Optimize @this for performance and readability |
| Document this | Add comments documenting @this |
| Add tests for this | Add tests for @this |
| Review buffer | Review @buffer for correctness and readability |
| Review git diff | Review the following git diff for correctness and readability:\n@diff |
| Explain diagnostics | Explain @diagnostics |
| Add buffer to prompt | @buffer |
| Add this to prompt | @this |
Tip
Create keymaps for your favorite prompts:
local prompt = require("opencode.config").opts.prompts.explain
vim.keymap.set({ "n", "x" }, "<leader>oe", function() require("opencode").prompt(prompt.prompt, prompt) 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 |
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_submit 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 (and partially based on) nvim-aider and later neopencode.nvim.
opencode.nvimuses 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.