Opencode.nvim
neovim frontend for opencode - a terminal-based AI coding agent
Install / Use
/learn @sudo-tee/Opencode.nvimREADME
🤖 opencode.nvim
<div align="center"> <img src="https://raw.githubusercontent.com/sst/opencode/dev/packages/web/src/assets/logo-ornate-dark.svg" alt="Opencode logo" width="30%" /> </div> <div align="center">neovim frontend for opencode - a terminal-based AI coding agent
<a href="https://www.buymeacoffee.com/sudo.tee"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" height="20px"></a>
</div>✨ Description
This plugin provides a bridge between neovim and the opencode AI agent, creating a chat interface while capturing editor context (current file, selections) to enhance your prompts. It maintains persistent sessions tied to your workspace, allowing for continuous conversations with the AI assistant similar to what tools like Cursor AI offer.
Main Features
Chat Panel
The chat panel is a dedicated window inside Neovim that lets you hold a persistent conversation with the opencode AI agent. It displays your previous messages and responses, and automatically uses your current workspace and editor state as context so you can iterate on code without leaving Neovim. You can type prompts, review answers, and navigate back to your code buffer while keeping the ongoing chat session open.
<div align="center"> <img src="https://github.com/user-attachments/assets/197d69ba-6db9-4989-97ff-557c89000cf5"> </div>Quick buffer chat (<leader>o/) EXPERIMENTAL
This is an experimental feature that allows you to chat with the AI using the current buffer context. In visual mode, it captures the selected text as context, while in normal mode, it uses the current line. The AI will respond with quick edits to the files that are applied by the plugin.
Don't hesitate to give it a try and provide feedback!
Refer to the Quick Chat section for more details.
<div align="center"> <img src="https://i.imgur.com/5JNlFZn.png"> </div>📑 Table of Contents
- ⚠️Caution
- Requirements
- Installation
- Configuration
- Usage
- Permissions
- Context
- Agents
- Custom/External Server Configuration
- User Commands and Slash Commands
- Contextual Actions for Snapshots
- Contextual Restore points
- Highlight Groups
- Prompt Guard
- Custom user hooks
- Server-Sent Events (SSE) autocmds
- Quick Chat
- Setting up Opencode
- Recipes
⚠️Caution
This plugin is in early development and may have bugs and breaking changes. It is not recommended for production use yet. Please report any issues you encounter on the GitHub repository.
Opencode is also in early development and may have breaking changes. Ensure you are using a compatible version of the Opencode CLI (v0.6.3+ or more).
If your upgrade breaks the plugin, please open an issue or downgrade to the last working version.
📋 Requirements
- Opencode (v0.6.3+ or more) CLI installed and available (see Setting up opencode below)
🚀 Installation
Install the plugin with your favorite package manager. See the Configuration section below for customization options.
With lazy.nvim
{
"sudo-tee/opencode.nvim",
config = function()
require("opencode").setup({})
end,
dependencies = {
"nvim-lua/plenary.nvim",
{
"MeanderingProgrammer/render-markdown.nvim",
opts = {
anti_conceal = { enabled = false },
file_types = { 'markdown', 'opencode_output' },
},
ft = { 'markdown', 'Avante', 'copilot-chat', 'opencode_output' },
},
-- Optional, for file mentions and commands completion, pick only one
'saghen/blink.cmp',
-- 'hrsh7th/nvim-cmp',
-- Optional, for file mentions picker, pick only one
'folke/snacks.nvim',
-- 'nvim-telescope/telescope.nvim',
-- 'ibhagwan/fzf-lua',
-- 'nvim_mini/mini.nvim',
},
}
⚙️ Configuration
-- Default configuration with all available options
require('opencode').setup({
preferred_picker = nil, -- 'telescope', 'fzf', 'mini.pick', 'snacks', 'select', if nil, it will use the best available picker. Note mini.pick does not support multiple selections
preferred_completion = nil, -- 'blink', 'nvim-cmp','vim_complete' if nil, it will use the best available completion
default_global_keymaps = true, -- If false, disables all default global keymaps
default_mode = 'build', -- 'build' or 'plan' or any custom configured. @see [OpenCode Agents](https://opencode.ai/docs/modes/)
default_system_prompt = nil, -- Custom system prompt to use for all sessions. If nil, uses the default built-in system prompt
keymap_prefix = '<leader>o', -- Default keymap prefix for global keymaps change to your preferred prefix and it will be applied to all keymaps starting with <leader>o
opencode_executable = 'opencode', -- Name of your opencode binary
-- Server configuration for custom/external opencode servers
server = {
url = nil, -- URL/hostname (e.g., 'http://192.168.1.100', 'localhost', 'https://myserver.com')
port = nil, -- Port number (e.g., 8080), 'auto' for random port
timeout = 5, -- Health check timeout in seconds when connecting
spawn_command = nil, -- Optional function to start the server: function(port, url) ... end
auto_kill = true, -- Kill spawned servers when last nvim instance exits (default: true) Only applies to servers spawned by the plugin with spawn_command/kill_command
path_map = nil, -- Map host paths to server paths: string ('/app') or function(path) -> string
},
keymap = {
editor = {
['<leader>og'] = { 'toggle' }, -- Open opencode. Close if opened
['<leader>oi'] = { 'open_input' }, -- Opens and focuses on input window on insert mode
['<leader>oI'] = { 'open_input_new_session' }, -- Opens and focuses on input window on insert mode. Creates a new session
['<leader>oo'] = { 'open_output' }, -- Opens and focuses on output window
['<leader>ot'] = { 'toggle_focus' }, -- Toggle focus between opencode and last window
['<leader>oT'] = { 'timeline' }, -- Display timeline picker to navigate/undo/redo/fork messages
['<leader>oq'] = { 'close' }, -- Close UI windows
['<leader>os'] = { 'select_session' }, -- Select and load a opencode session
['<leader>oR'] = { 'rename_session' }, -- Rename current session
['<leader>op'] = { 'configure_provider' }, -- Quick provider and model switch from predefined list
['<leader>oV'] = { 'configure_variant' }, -- Switch model variant for the current model
['<leader>oy'] = { 'add_visual_selection', mode = {'v'} },
['<leader>oY'] = { 'add_visual_selection_inline', mode = {'v'} }, -- Insert visual selection as inline code block in the input buffer
['<leader>oz'] = { 'toggle_zoom' }, -- Zoom in/out on the Opencode windows
['<leader>ov'] = { 'paste_image'}, -- Paste image from clipboard into current session
['<leader>od'] = { 'diff_open' }, -- Opens a diff tab of a modified file since the last opencode prompt
['<leader>o]'] = { 'diff_next' }, -- Navigate to next file diff
['<leader>o['] = { 'diff_prev' }, -- Navigate to previous file diff
['<leader>oc'] = { 'diff_close' }, -- Close diff view tab and return to normal editing
['<leader>ora'] = { 'diff_revert_all_last_prompt' }, -- Revert all file changes since the last opencode prompt
['<leader>ort'] = { 'diff_revert_this_last_prompt' }, -- Revert current file changes since the last opencode prompt
['<leader>orA'] = { 'diff_revert_all' }, -- Revert all file changes since the last opencode session
['<leader>orT'] = { 'diff_revert_this' }, -- Revert current file changes since the last opencode session
['<leader>orr'] = { 'diff_restore_snapshot_file' }, -- Restore a file to a restore point
['<leader>orR'] = { 'diff_restore_snapshot_all' }, -- Restore all files to a restore point
['<leader>ox'] = { 'swap_position' }, -- Swap Opencode pane left/right
['<leader>ott'] = { 'toggle_tool_output' }, -- Toggle tools output (diffs, cmd output, etc.)
['<leader>otr'] = { 'toggle_reasoning_output' }, -- Toggle reasoning output (thinking steps)
['<leader>o/'] = { 'quick_chat', mode = { 'n', 'x' } }, -- Open quick chat input with selection context in visual mode or current line context in normal mode
},
input_window = {
['<S-cr>'] = { 'submit_input_prompt', mode = { 'n', 'i' } }, -- Submit prompt (normal mode and insert mode)
['<esc>'] = { 'close', defer_to_completion = true }, -- Close UI windows
['<C-c>'] = { 'cancel', defer_to_completion = true }, -- Cancel opencode request while it is running
['~'] = { 'mention_file', mode = 'i' }, -- Pick a file and add to context. See File Mentions section
['@'] = { 'mention', mode = 'i' }, -- Insert mention (file/agent)
['/'] = { 'slash_commands', mode = 'i' }, -- Pick a command to run in the input window
['#'] = { 'context_items', mode = 'i' }, -- Manage context items (current file, selection, diagnostics, mentioned files)
['<M-v>'] = { 'paste_image
