Seamlessly integrate the opencode AI assistant with Neovim — convenient and editor-aware research, reviews, and requests.
demo.mp4
Uses
opencode
's currently undocumented API — latest tested version:v0.7.2
- Open
opencode
in an embedded terminal, or auto-connect to one matching Neovim's CWD. - Input prompts with completions, highlights, and normal-mode support.
- Select from a built-in prompt library and define custom prompts.
- Inject relevant editor context (buffer, selection, cursor, diagnostics, etc.).
- Auto-reload buffers edited by
opencode
in real-time. - Forward
opencode
's Server-Sent-Events as Neovim autocmds for automation. - Sensible defaults with well-documented, granular configuration.
{
'NickvanDyke/opencode.nvim',
dependencies = {
-- Recommended for better prompt input, and required to use `opencode.nvim`'s embedded terminal — otherwise optional
{ 'folke/snacks.nvim', opts = { input = { enabled = true } } },
},
config = function()
vim.g.opencode_opts = {
-- Your configuration, if any — see `lua/opencode/config.lua`
}
-- Required for `opts.auto_reload`
vim.opt.autoread = true
-- Recommended keymaps
vim.keymap.set('n', '<leader>ot', function() require('opencode').toggle() end, { desc = 'Toggle opencode' })
vim.keymap.set('n', '<leader>oA', function() require('opencode').ask() end, { desc = 'Ask opencode' })
vim.keymap.set('n', '<leader>oa', function() require('opencode').ask('@cursor: ') end, { desc = 'Ask opencode about this' })
vim.keymap.set('v', '<leader>oa', function() require('opencode').ask('@selection: ') end, { desc = 'Ask opencode about selection' })
vim.keymap.set('n', '<leader>on', function() require('opencode').command('session_new') end, { desc = 'New opencode session' })
vim.keymap.set('n', '<leader>oy', function() require('opencode').command('messages_copy') end, { desc = 'Copy last opencode response' })
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' })
vim.keymap.set({ 'n', 'v' }, '<leader>os', function() require('opencode').select() end, { desc = 'Select opencode prompt' })
-- Example: keymap for custom prompt
vim.keymap.set('n', '<leader>oe', function() require('opencode').prompt('Explain @cursor and its context') end, { desc = 'Explain this code' })
end,
}
nixvim
programs.nixvim = {
extraPlugins = [
pkgs.vimPlugins.opencode-nvim
];
keymaps = [
{ key = "<leader>ot"; action = "<cmd>lua require('opencode').toggle()<CR>"; }
{ key = "<leader>oa"; action = "<cmd>lua require('opencode').ask()<CR>"; mode = "n"; }
{ key = "<leader>oa"; action = "<cmd>lua require('opencode').ask('@selection: ')<CR>"; mode = "v"; }
{ key = "<leader>oe"; action = "<cmd>lua require('opencode').select_prompt()<CR>"; mode = ["n" "v"]; }
{ key = "<leader>on"; action = "<cmd>lua require('opencode').command('session_new')<CR>"; }
];
};
opencode.nvim
strives to provide a rich and reliable default experience, with a well-documented and flexible configuration and API for you to customize and compose according to your preferences.
When your prompt contains placeholders, opencode.nvim
replaces them with context before sending:
Placeholder | Context |
---|---|
@buffer |
Current buffer |
@buffers |
Open buffers |
@cursor |
Cursor position |
@selection |
Selected text |
@visible |
Visible text |
@diagnostic |
Current line diagnostics |
@diagnostics |
Current buffer diagnostics |
@quickfix |
Quickfix list |
@diff |
Git diff |
@grapple |
grapple.nvim tags |
Add custom contexts to opts.contexts
.
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), vim.log.levels.DEBUG)
-- Do something interesting, like show a notification when opencode finishes responding
if args.data.type == "session.idle" then
vim.notify("opencode finished responding", vim.log.levels.INFO)
end
end,
})
- Inspired by (and partially based on) nvim-aider and later neopencode.nvim.
opencode.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.