Integrate the nanocode AI assistant with Neovim — streamline editor-aware research, reviews, and requests.
- Auto-connect to any
nanocoderunning inside Neovim's CWD, or provide an integrated instance. - Share editor context (buffer, cursor, selection, diagnostics, etc.).
- Input prompts with completions, highlights, and normal-mode support.
- Select prompts from a library and define your own.
- 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.
{
"nanogpt-community/nanocode.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 nanocode.Opts
vim.g.nanocode = {
-- Your configuration, if any — see `lua/nanocode/config.lua`, or "goto definition" on the type or field.
}
-- Required for `opts.events.reload`.
vim.o.autoread = true
-- Recommended/example keymaps.
vim.keymap.set({ "n", "x" }, "<C-a>", function() require("nanocode").ask("@this: ", { submit = true }) end, { desc = "Ask nanocode…" })
vim.keymap.set({ "n", "x" }, "<C-x>", function() require("nanocode").select() end, { desc = "Execute nanocode action…" })
vim.keymap.set({ "n", "t" }, "<C-.>", function() require("nanocode").toggle() end, { desc = "Toggle nanocode" })
vim.keymap.set({ "n", "x" }, "go", function() return require("nanocode").operator("@this ") end, { desc = "Add range to nanocode", expr = true })
vim.keymap.set("n", "goo", function() return require("nanocode").operator("@this ") .. "_" end, { desc = "Add line to nanocode", expr = true })
vim.keymap.set("n", "<S-C-u>", function() require("nanocode").command("session.half.page.up") end, { desc = "Scroll nanocode up" })
vim.keymap.set("n", "<S-C-d>", function() require("nanocode").command("session.half.page.down") end, { desc = "Scroll nanocode down" })
-- You may want these if you stick with the opinionated "<C-a>" and "<C-x>" above — otherwise consider "<leader>o…".
vim.keymap.set("n", "+", "<C-a>", { desc = "Increment under cursor", noremap = true })
vim.keymap.set("n", "-", "<C-x>", { desc = "Decrement under cursor", noremap = true })
end,
}programs.nixvim = {
extraPlugins = [
pkgs.vimPlugins.nanocode-nvim
];
};Tip
Run :checkhealth nanocode after setup.
nanocode.nvim provides a rich and reliable default experience — see all available options and their defaults here.
nanocode.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 |
@marks |
Global marks |
@grapple |
grapple.nvim tags |
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 |
nanocodenanocodenanocodenanocodenanocode
Details
Neovim terminal
vim.g.nanocode_opts = {
provider = {
enabled = "terminal",
terminal = {
-- ...
}
}
}snacks.terminal
vim.g.nanocode_opts = {
provider = {
enabled = "snacks",
snacks = {
-- ...
}
}
}kitty
vim.g.nanocode_opts = {
provider = {
enabled = "kitty",
kitty = {
-- ...
}
}
}The kitty provider requires remote control via a socket to be enabled.
You can do this either by running Kitty with the following command:
# 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/mykittyOR, 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
vim.g.nanocode_opts = {
provider = {
enabled = "wezterm",
wezterm = {
-- ...
}
}
}tmux
vim.g.nanocode_opts = {
provider = {
enabled = "tmux",
tmux = {
-- ...
}
}
}custom
Integrate your custom method for convenience!
vim.g.nanocode_opts = {
provider = {
toggle = function(self)
-- ...
end,
start = function(self)
-- ...
end,
stop = function(self)
-- ...
end,
}
}Input a prompt for nanocode.
- Press
<Up>to browse recent asks. - Highlights and completes contexts and
nanocodesubagents.- Press
<Tab>to trigger built-in completion. - Registers
opts.ask.blink_cmp_sourceswhen usingsnacks.inputandblink.cmp.
- Press
Select from all nanocode.nvim functionality.
- Prompts
- Commands
- Fetches custom commands from
nanocode
- Fetches custom commands from
- Provider controls
Highlights and previews items when using snacks.picker.
Prompt nanocode.
- Resolves named references to configured prompts.
- Injects configured contexts.
nanocodewill interpret@references to files or subagents.
Wraps prompt as an operator, supporting ranges and dot-repeat.
Command nanocode:
| Command | Description |
|---|---|
session.list |
List sessions |
session.new |
Start a new session |
session.select |
Select a 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 |
nanocode.nvim forwards nanocode's Server-Sent-Events as an nanocodeEvent autocmd:
-- Handle `nanocode` events
vim.api.nvim_create_autocmd("User", {
pattern = "nanocodeEvent:*", -- Optionally filter event types
callback = function(args)
---@type nanocode.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("`nanocode` finished responding")
end
end,
})When nanocode edits a file, nanocode.nvim automatically reloads the corresponding buffer.
When nanocode requests a permission, nanocode.nvim waits for idle to ask you to approve or deny it.
lualine
require("lualine").setup({
sections = {
lualine_z = {
{
require("nanocode").statusline,
},
}
}
})- Forked from opencode.nvim