# opencode.nvim **Repository Path**: rulei_mirror/opencode.nvim ## Basic Information - **Project Name**: opencode.nvim - **Description**: mirror https://github.com/NickvanDyke/opencode.nvim - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-10 - **Last Updated**: 2026-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # opencode.nvim Integrate the [opencode](https://github.com/sst/opencode) AI assistant with Neovim β€” streamline editor-aware research, reviews, and requests. ## ✨ Features - Auto-connect to _any_ `opencode` running inside Neovim's CWD, or provide an integrated instance. - Input prompts with completions, highlights, and normal-mode support. - Select prompts from a library and define your own. - Share editor context (buffer, cursor, selection, diagnostics, etc.). - Execute commands. - Respond to permission requests. - Reload edited buffers in real-time. - Monitor state via statusline component. - Forward Server-Sent-Events as autocmds for automation. - Sensible defaults with well-documented, flexible configuration and API to fit your workflow. - _Vim-y_ β€” supports ranges and dot-repeat. ## πŸ“¦ Setup ### [lazy.nvim](https://github.com/folke/lazy.nvim) ```lua { "NickvanDyke/opencode.nvim", dependencies = { -- Recommended for `ask()` and `select()`. -- Required for `snacks` provider. ---@module 'snacks' <- Loads `snacks.nvim` types for configuration intellisense. { "folke/snacks.nvim", opts = { input = {}, picker = {}, terminal = {} } }, }, config = function() ---@type opencode.Opts vim.g.opencode_opts = { -- Your configuration, if any β€” see `lua/opencode/config.lua`, or "goto definition". } -- Required for `opts.events.reload`. vim.o.autoread = true -- Recommended/example keymaps. vim.keymap.set({ "n", "x" }, "", function() require("opencode").ask("@this: ", { submit = true }) end, { desc = "Ask opencode" }) vim.keymap.set({ "n", "x" }, "", function() require("opencode").select() end, { desc = "Execute opencode action…" }) vim.keymap.set({ "n", "t" }, "", function() require("opencode").toggle() end, { desc = "Toggle opencode" }) vim.keymap.set({ "n", "x" }, "go", function() return require("opencode").operator("@this ") end, { expr = true, desc = "Add range to opencode" }) vim.keymap.set("n", "goo", function() return require("opencode").operator("@this ") .. "_" end, { expr = true, desc = "Add line to opencode" }) vim.keymap.set("n", "", function() require("opencode").command("session.half.page.up") end, { desc = "opencode half page up" }) vim.keymap.set("n", "", function() require("opencode").command("session.half.page.down") end, { desc = "opencode half page down" }) -- You may want these if you stick with the opinionated "" and "" above β€” otherwise consider "o". vim.keymap.set("n", "+", "", { desc = "Increment", noremap = true }) vim.keymap.set("n", "-", "", { desc = "Decrement", noremap = true }) end, } ``` ### [nixvim](https://github.com/nix-community/nixvim) ```nix programs.nixvim = { extraPlugins = [ pkgs.vimPlugins.opencode-nvim ]; }; ``` > [!TIP] > Run `:checkhealth opencode` after setup. ## βš™οΈ Configuration `opencode.nvim` provides a rich and reliable default experience β€” see all available options and their defaults [here](./lua/opencode/config.lua). ### Contexts `opencode.nvim` replaces placeholders in prompts with the corresponding context: | Placeholder | Context | | -------------- | ----------------------------------------------------------- | | `@this` | Operator range or visual selection if any, else cursor position | | `@buffer` | Current buffer | | `@buffers` | Open buffers | | `@visible` | Visible text | | `@diagnostics` | Current buffer diagnostics | | `@quickfix` | Quickfix list | | `@diff` | Git diff | | `@grapple` | [grapple.nvim](https://github.com/cbochs/grapple.nvim) tags | ### Prompts Select or reference prompts to review, explain, and improve your code: | Name | Prompt | | ------------- | ---------------------------------------------------------------------- | | `diagnostics` | Explain `@diagnostics` | | `diff` | Review the following git diff for correctness and readability: `@diff` | | `document` | Add comments documenting `@this` | | `explain` | Explain `@this` and its context | | `fix` | Fix `@diagnostics` | | `implement` | Implement `@this` | | `optimize` | Optimize `@this` for performance and readability | | `review` | Review `@this` for correctness and readability | | `test` | Add tests for `@this` | ### Provider You can manually run `opencode` inside Neovim's CWD however you like and `opencode.nvim` will find it! If `opencode.nvim` can't find an existing `opencode`, it uses the configured provider (defaulting based on availability) to manage one for you. > [!IMPORTANT] > You _must_ run `opencode` with the `--port` flag to expose its server. Providers do so by default.
Neovim terminal ```lua vim.g.opencode_opts = { provider = { enabled = "terminal", terminal = { -- ... } } } ```
snacks.terminal ```lua vim.g.opencode_opts = { provider = { enabled = "snacks", snacks = { -- ... } } } ```
kitty ```lua vim.g.opencode_opts = { provider = { enabled = "kitty", kitty = { -- ... } } } ``` The kitty provider requires [remote control via a socket](https://sw.kovidgoyal.net/kitty/remote-control/#remote-control-via-a-socket) to be enabled. You can do this either by running Kitty with the following command: ```bash # For Linux only: kitty -o allow_remote_control=yes --single-instance --listen-on unix:@mykitty # Other UNIX systems: kitty -o allow_remote_control=yes --single-instance --listen-on unix:/tmp/mykitty ``` OR, by adding the following to your `kitty.conf`: ``` # For Linux only: allow_remote_control yes listen_on unix:@mykitty # Other UNIX systems: allow_remote_control yes listen_on unix:/tmp/kitty ```
wezterm ```lua vim.g.opencode_opts = { provider = { enabled = "wezterm", wezterm = { -- ... } } } ```
tmux ```lua vim.g.opencode_opts = { provider = { enabled = "tmux", tmux = { -- ... } } } ```
custom Integrate your custom method for convenience! ```lua vim.g.opencode_opts = { provider = { toggle = function(self) -- ... end, start = function(self) -- ... end, stop = function(self) -- ... end, } } ```
Please submit PRs adding new providers! πŸ™‚ ## πŸš€ Usage ### ✍️ Ask β€” `require("opencode").ask()` Input a prompt for `opencode`. - Press `` to browse recent asks. - Highlights and completes contexts and `opencode` subagents. - Press `` to trigger built-in completion. - Registers `opts.ask.blink_cmp_sources` when using `snacks.input` and `blink.cmp`. image ### πŸ“ Select β€” `require("opencode").select()` Select from all `opencode.nvim` functionality. - Fetches custom commands from `opencode`. - Highlights and previews items when using `snacks.picker`. image ### πŸ—£οΈ Prompt β€” `require("opencode").prompt()` Prompt `opencode`. - Resolves named references to configured prompts. - Injects configured contexts. - `opencode` will interpret `@` references to files or subagents. ### πŸ§‘β€πŸ”¬ Operator β€” `require("opencode").operator()` Wraps `prompt` as an operator, supporting ranges and dot-repeat. ### πŸ§‘β€πŸ« Command β€” `require("opencode").command()` Command `opencode`: | Command | Description | | ------------------------ | -------------------------------------------------- | | `session.list` | List sessions | | `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) | | `session.page.up` | Scroll messages up by one page | | `session.page.down` | Scroll messages down by one page | | `session.half.page.up` | Scroll messages up by half a page | | `session.half.page.down` | Scroll messages down by half a page | | `session.first` | Jump to the first message in the session | | `session.last` | Jump to the last message in the session | | `session.undo` | Undo the last action in the current session | | `session.redo` | Redo the last undone action in the current session | | `prompt.submit` | Submit the TUI input | | `prompt.clear` | Clear the TUI input | | `agent.cycle` | Cycle the selected agent | ## πŸ‘€ Events `opencode.nvim` forwards `opencode`'s Server-Sent-Events as an `OpencodeEvent` autocmd: ```lua -- Handle `opencode` events vim.api.nvim_create_autocmd("User", { pattern = "OpencodeEvent:*", -- Optionally filter event types callback = function(args) ---@type opencode.cli.client.Event local event = args.data.event ---@type number local port = args.data.port -- See the available event types and their properties vim.notify(vim.inspect(event)) -- Do something useful if event.type == "session.idle" then vim.notify("`opencode` finished responding") end end, }) ``` ### Edits When `opencode` edits a file, `opencode.nvim` automatically reloads the corresponding buffer. ### Permissions When `opencode` requests a permission, `opencode.nvim` waits for idle to ask you to approve or deny it. image ### Statusline
lualine ```lua require("lualine").setup({ sections = { lualine_z = { { require("opencode").statusline, }, } } }) ```
## πŸ™ Acknowledgments - Inspired by [nvim-aider](https://github.com/GeorgesAlkhouri/nvim-aider), [neopencode.nvim](https://github.com/loukotal/neopencode.nvim), and [sidekick.nvim](https://github.com/folke/sidekick.nvim). - Uses `opencode`'s TUI for simplicity β€” see [sudo-tee/opencode.nvim](https://github.com/sudo-tee/opencode.nvim) for a Neovim frontend. - [mcp-neovim-server](https://github.com/bigcodegen/mcp-neovim-server) may better suit you, but it lacks customization and tool calls are slow and unreliable.