agentic.nvim
Health Gecti
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 504 GitHub stars
Code Gecti
- Code scan — Scanned 8 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Agentic Chat Interface directly in Neovim with ACP providers from Claude-Code, Gemini, Codex, OpenCode, and Cursor-agent
Agentic.nvim
⚡ A Chat interface for AI agents in Neovim that works with any provider
supporting the Agent Client Protocol (ACP)
— including Claude, Gemini, Codex, OpenCode, Cursor Agent, Copilot, Auggie,
Mistral Vibe, Cline, Goose, Kiro, Pi, and more.
Agentic.nvim brings your AI assistant to Neovim through the implementation
of the Agent Client Protocol (ACP).
You'll get the same results and performance as you would when using the ACP
provider's official CLI directly from the terminal.
Agentic.nvim is the interface, your agent is the Brain. This plugin will use all
the same configurations and authentication methods you already have set up on
your terminal.
Including your MCP servers, commands, SKILLs, and sub-agents, you don't have to
recreate your configuration to use Agentic.nvim.
Sessions are interchangeable — start a conversation in Neovim and continue it in
the terminal, or pick up a terminal session right inside Neovim. Your ACP
provider manages sessions natively, so they're available everywhere.
There're no hidden prompts or magic happening behind the scenes. Just a Chat
interface, your colors, and your keymaps.
Supported providers
Works with any AI provider that implements the
Agent Client Protocol, including, but not
limited to:
|
Claude |
Gemini |
Codex |
OpenCode |
|
Cursor |
Copilot |
Augment |
Mistral Vibe |
|
Kiro |
Cline |
Goose |
Pi |
...and any future ACP-compatible provider.
✨ Features
- ⚡ Performance First - Optimized for minimal overhead and fast response
times - 🔌 Any ACP Provider - Works with any AI provider that implements the Agent
Client Protocol — Claude, Gemini, Codex, OpenCode, Cursor Agent, Copilot,
Auggie, Mistral Vibe, Cline, Goose, Kiro, Pi, and any future ACP-compatible
provider - 🔑 Zero Config Authentication - No API keys needed
- Keep you secrets secret: run
claude /login, orgemini auth login
once and, if they're working on your Terminal, they will work automatically
on Agentic.
- Keep you secrets secret: run
- 🧠 Model Switcher - Switch between available models mid-session
(<localLeader>min the chat widget) - 🔀 Switch Providers - Switch between ACP providers mid-conversation
without losing chat history (<localLeader>sin the chat widget) - ♻️ Session Restore - Sessions are interchangeable between Neovim and
terminal — continue any conversation anywhere - 📝 Context Control - Add files and text selections to conversation context
with one keypress - 🏞️ Image Support - Drag-and-drop or paste images and screenshots directly
into the chat - 🛡️ Permission System - Interactive approval workflow for AI tool calls,
mimicking Claude-code's approach, with 1, 2, 3, ... one-key press for quick
responses - 🤖 🤖 Multiple agents - Independent Chat sessions for each Neovim Tab let
you have multiple agents working simultaneously on different tasks - 🎯 Clean UI - Sidebar interface with markdown rendering and syntax
highlighting - ⌨️ Slash Commands - Native Neovim completion for ACP slash commands with
fuzzy filtering- Every slash command your provider has access too will apear when you type
/in the prompt as the first character
- Every slash command your provider has access too will apear when you type
- 📁 File Picker - Type
@to trigger autocomplete for workspace files- Reference multiple files:
@file1.lua @file2.lua
- Reference multiple files:
- 🔄 Agent Mode Switching - Switch between ACP-supported agent modes with
Shift-Tab (Similar to Claude, Gemini, Cursor-agent, etc)Default,Auto Accept,Plan mode, etc... (depends on the provider)
- ℹ️ Smart Context - Automatically includes system and project information
in the first message of each session, so the Agent don't spend time and tokens
gathering basic info
🎥 Showcase
Simple replace with tool approval:
https://github.com/user-attachments/assets/4b33bb18-95f7-4fea-bc12-9a9208823911
Rich diff preview
When editing files, if your provider asks for permission, you can see a diff
preview side-by-side or inline, set your preference in your options:
| Side-by-side | Inline |
|---|---|
Dynamic layout rotation: right - bottom - left
https://github.com/user-attachments/assets/000c5a9a-5469-44e3-b302-4074caa58fa9
Image and Screenshot support in the Chat
Drag-n-Drop or paste an image from the Clipboard directly to the chat context:
https://github.com/user-attachments/assets/6ae57136-9c08-4d71-bc8a-59babc49be4d
Session restoration
Start in the terminal, continue in Neovim — or the other way around!
🐣 NEW: Switch agent mode: Always ask, Accept Edits, Plan mode...
https://github.com/user-attachments/assets/96a11aae-3095-46e7-86f1-ccc02d21c04f
Add files to the context:
Add the current file to the Chat context or the selected text, let your agent
know where you want it to work.
https://github.com/user-attachments/assets/b6b43544-a91e-407f-834e-4b4de41259f8
Use @ to fuzzy find any file:
https://github.com/user-attachments/assets/c6653a8b-20ef-49c8-b644-db0df1b342f0
📋 Requirements
- Neovim v0.11.0 or higher
- ACP Provider CLI - Install the CLI for any ACP-compatible provider of your
choice- For security reasons, this plugin doesn't install or manage binaries for
you. You must install them manually.
- For security reasons, this plugin doesn't install or manage binaries for
We recommend using pnpmpnpm uses a constant, static global path, that's resilient to updates.
While npm loses global packages every time you change Node versions using
tools like nvm, fnm, etc...
You are free to chose any installation method you prefer!
| Provider | Install |
|---|---|
| claude-agent-acp | pnpm add -g @agentclientprotocol/claude-agent-acpOR npm i -g @agentclientprotocol/claude-agent-acpOR Download binary |
| gemini-cli | pnpm add -g @google/gemini-cliOR npm i -g @google/gemini-cliOR brew install --cask gemini |
| codex-acp | pnpm add -g @zed-industries/codex-acpOR npm i -g @zed-industries/codex-acpOR Download binary |
| opencode | pnpm add -g opencode-aiOR npm i -g opencode-aiOR brew install opencodeOR curl -fsSL https://opencode.ai/install | bash |
| cursor-agent | curl https://cursor.com/install -fsS | bash OR windows: irm 'https://cursor.com/install?win32=true' | iexOR See Cursor docs |
| copilot-cli | pnpm add -g @github/copilotOR npm i -g @github/copilotOR brew install copilot-cliOR curl -fsSL https://gh.io/copilot-install | bash |
| auggie | pnpm add -g @augmentcode/auggieOR npm i -g @augmentcode/auggieOR See Auggie docs |
| mistral-vibe | curl -LsSf https://mistral.ai/vibe/install.sh | bashOR uv tool install mistral-vibeOR pip install mistral-vibeOR Download binary |
| cline | pnpm add -g clineOR npm i -g clineOR See Cline docs |
| goose | brew install block-goose-cliOR See Goose docs |
| kiro-cli | curl -fsSL https://cli.kiro.dev/install | bashOR See Kiro CLI docs |
| pi-acp | Requires the pi CLI installed first: curl -fsSL https://pi.dev/install.sh | shOR pnpm add -g @earendil-works/pi-coding-agentOR npm i -g @earendil-works/pi-coding-agentThen the adapter: pnpm add -g pi-acp OR npm i -g pi-acp |
[!WARNING]
These install commands are here for convenience, please always refer to the
official installation instructions from the respective ACP provider.
[!NOTE]
Why install ACP provider CLIs globally?
shai-hulud
should be reason enough. 📌 Pin your versions!
But frontend projects with strict package management policies will fail to
start when usingnpx ...
📦 Installation
lazy.nvim
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
-- Any ACP-compatible provider works. Built-in: "claude-agent-acp" | "gemini-acp" | "codex-acp" | "opencode-acp" | "cursor-acp" | "copilot-acp" | "auggie-acp" | "mistral-vibe-acp" | "cline-acp" | "goose-acp" | "kiro-acp" | "pi-acp"
provider = "claude-agent-acp", -- setting the name here is all you need to get started
},
-- these are just suggested keymaps; customize as desired
keys = {
{
"<C-\\>",
function() require("agentic").toggle() end,
mode = { "n", "v", "i" },
desc = "Toggle Agentic Chat"
},
{
"<C-'>",
function() require("agentic").add_selection_or_file_to_context() end,
mode = { "n", "v" },
desc = "Add file or selection to Agentic to Context"
},
{
"<C-,>",
function() require("agentic").new_session() end,
mode = { "n", "v", "i" },
desc = "New Agentic Session"
},
{
"<A-i>r", -- ai Restore
function()
require("agentic").restore_session()
end,
desc = "Agentic Restore session",
silent = true,
mode = { "n", "v", "i" },
},
{
"<leader>ad", -- ai Diagnostics
function()
require("agentic").add_current_line_diagnostics()
end,
desc = "Add current line diagnostic to Agentic",
mode = { "n" },
},
{
"<leader>aD", -- ai all Diagnostics
function()
require("agentic").add_buffer_diagnostics()
end,
desc = "Add all buffer diagnostics to Agentic",
mode = { "n" },
},
},
}
⚙️ Configuration
You don't have to copy and paste anything from the default config, linking it
here for ease access and reference:lua/agentic/config_default.lua.
Customizing ACP Providers
You can customize the built-in providers or add any new ACP-compatible provider
by configuring the acp_providers property:
[!NOTE]
You don't have to override anything or include these in your setup!
These are just examples of how you can customize the commands, env, etc.
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
acp_providers = {
-- Override existing provider (e.g., add API key)
-- Agentic.nvim doesn't require API keys
-- Only add it if that's how you prefer to authenticate
["claude-agent-acp"] = {
env = {
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY"),
},
},
-- Example of how override the ACP command to suit your installation, if needed
["codex-acp"] = {
command = "~/.local/bin/codex-acp",
},
-- Add any new ACP-compatible provider — the name and command are up to you
["my-cool-acp"] = {
name = "My Cool ACP",
command = "cool-acp",
args = { "--mode", "acp" },
env = {
COOL_API_KEY = os.getenv("COOL_API_KEY"),
},
},
},
},
}
Provider Configuration Fields:
command(string) - The CLI command to execute (must be in PATH or absolute
path)args(table, optional) - Array of command-line argumentsenv(table, optional) - Environment variables to set for the processdefault_mode(string, optional) - Default mode ID to set on session creation
(e.g.,"bypassPermissions","plan")initial_model(string, optional) - Default model ID to set on session
creation (e.g.,"haiku")default_thought_level(string, optional) - Default thought effort level to
apply on session creation (e.g.,"high","max"for Claude)
[!NOTE]
Customizing a provider only requires specifying the fields you want to
override, not the entire configuration.
Window Layout
Configure the widget layout position and sizing:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
windows = {
position = "right", -- "right", "left", or "bottom"
width = "40%", -- Sidebar width (position = "right" or "left")
height = "30%", -- Panel height (position = "bottom")
},
},
}
position- Widget layout:"right"or"left"(vertical sidebar) or"bottom"(horizontal panel)width- Sidebar width whenpositionis right or left (percentage, decimal,
or absolute)height- Panel height whenposition = "bottom"(percentage, decimal, or
absolute)
Rotating Layouts dynamically at runtime
You can rotate between layouts, dynamically, without closing Neovim withrotate_layout():
-- Rotates through all three layouts: right → bottom → left → right ...
require("agentic").rotate_layout()
-- Rotates between right and bottom only
require("agentic").rotate_layout({ "right", "bottom" })
-- Rotates between right and left only
require("agentic").rotate_layout({ "right", "left" })
Customizing Window Options
You can customize the behavior of individual chat widget windows by configuring
the win_opts property for each window. These options override the default
window settings.
Customizing Window Headers
You can customize the header text for each panel in the chat widget using either
a table configuration or a custom render function.
Table-Based Configuration
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
headers = {
chat = {
title = " My Custom Chat Title",
suffix = "<S-Tab>: change mode",
},
-- ...
},
},
}
Function-Based Configuration
For complete control over header rendering, provide a function that receives the
header parts:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
headers = {
chat = function(parts)
local header = parts.title
if parts.context then
header = header .. " [" .. parts.context .. "]"
end
if parts.suffix then
header = header .. " • " .. parts.suffix
end
return header
end,
},
},
}
Folding
Completed tool call outputs are automatically folded to keep the chat buffer
readable. Failed tool calls stay open unless fold_on_error is enabled.
--- @type agentic.PartialUserConfig
opts = {
folding = {
tool_calls = {
enabled = true,
threshold = 10,
fold_on_error = false,
},
},
}
Set threshold = 0 to always fold completed calls, and failed calls whenfold_on_error = true. Negative values are clamped to 0. Set enabled = false
to disable folding entirely.
The fold hides the body only - the tool call header and completion status remain
visible. Use standard Vim fold commands (za, zo, zc) to toggle individual
folds, or zR/zM to open/close all folds in the chat window.
Tool Call Titles
Long non-diff titles for configured tool call kinds are truncated in the header
and shown in full as the first body block.
--- @type agentic.PartialUserConfig
opts = {
tool_calls = {
title = {
max_length = 50,
truncate_title_kinds = {
"execute",
"think",
"SubAgent",
"fetch",
"search",
},
},
},
}
Only truncate_title_kinds are affected by max_length. Titles longer thanmax_length are truncated to max_length bytes plus ...; the full title is
rendered in the folded body. Set max_length = 0 to disable title truncation.
Negative values are clamped to 0. Diff tool calls keep full header-only titles.
🚀 Usage (Public Lua API)
Commands
| Function | Description |
|---|---|
:lua require("agentic").toggle() |
Toggle chat sidebar |
:lua require("agentic").open() |
Open chat sidebar (keep open if already visible) |
:lua require("agentic").close() |
Close chat sidebar |
:lua require("agentic").add_selection() |
Add visual selection to context |
:lua require("agentic").add_file() |
Add current file to context |
:lua require("agentic").add_selection_or_file_to_context() |
Add selection (if any) or file to the context |
:lua require("agentic").add_files_to_context(opts) |
Add a list of file paths or buffer numbers to context |
:lua require("agentic").add_current_line_diagnostics() |
Add diagnostics at cursor line to context |
:lua require("agentic").add_buffer_diagnostics() |
Add all diagnostics from current buffer to context |
:lua require("agentic").new_session() |
Start new chat session, destroying and cleaning the current one |
:lua require("agentic").stop_generation() |
Stop current generation or tool execution (session stays active) |
:lua require("agentic").restore_session() |
Show provider's session picker to restore a previous session |
:lua require("agentic").restore_session_by_id(session_id) |
Restore a session by its ID |
:lua require("agentic").switch_provider() |
Switch ACP provider mid-session (shows picker, preserves history) |
:lua require("agentic").rotate_layout() |
Rotate window position through layouts (right → bottom → left) |
Optional Parameters
Open and Toggle supports optional parameter:
- auto_add_to_context (boolean, default:
true) - Whether to automatically
add the current visual selection or file to context when opening the Chat
-- Open the chat without adding anything to context
require("agentic").open({ auto_add_to_context = false })
When adding files or selections to context, you can also specify whether to
focus the prompt input after opening the chat:
- focus_prompt (boolean, default:
true) - Whether to move cursor to prompt
input after opening the chat
Available on: add_selection(opts), add_file(opts),add_selection_or_file_to_context(opts), add_files_to_context(opts),add_current_line_diagnostics(opts), add_buffer_diagnostics(opts)
-- Add selection without focusing the prompt
require("agentic").add_selection({ focus_prompt = false })
add_files_to_context(opts) accepts a files field with a list of file paths
(strings) or buffer numbers (integers). It can be used from anywhere, like your
file picker.
-- Add specific files by path
require("agentic").add_files_to_context({
files = {
"src/main.lua",
"src/utils.lua",
},
})
-- Add files by buffer number
require("agentic").add_files_to_context({
files = { 1, 5 },
focus_prompt = false,
})
restore_session_by_id(session_id) accepts a session_id argument with the
ID of the session you want to restore. Session IDs come from your provider's
session storage (e.g. provider logs, project metadata, or scripts that track
them). Unlike restore_session(), this does not require the provider to support
listing sessions.
-- Restore a session by ID
require("agentic").restore_session_by_id("58e5cf8a-1277-4e43-bc29-10c1246a2c66")
Built-in Keybindings
These keybindings are automatically set in Agentic buffers:
| Keybinding | Mode | Description |
|---|---|---|
<S-Tab> |
n/v/i | Switch agent mode (only available if provider supports modes) |
<CR> |
n | Submit prompt |
<C-s> |
n/v/i | Submit prompt |
<localLeader>p |
n | Paste image from clipboard in the Prompt buffer |
<C-v> |
i | Paste image from clipboard (same as Claude-code) |
<localLeader>s |
n | Switch ACP provider (preserves chat history) |
<localLeader>m |
n | Switch model without (preserves chat history) |
<localLeader>t |
n | Select thought effort level (model-dependent on Claude) |
q |
n | Close chat widget |
d |
n | Remove file, code selection, or diagnostic at cursor |
d |
v | Remove multiple selected files, code selections, or diagnostics |
]] |
n | Navigate to next chat heading |
[[ |
n | Navigate to previous chat heading |
]t |
n | Navigate to next tool call |
[t |
n | Navigate to previous tool call |
]c |
n | Navigate to next diff hunk (when diff preview is active) |
[c |
n | Navigate to previous diff hunk (when diff preview is active) |
Customizing Keybindings
You can customize the default keybindings by configuring the keymaps option in
your setup:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
keymaps = {
-- Keybindings for ALL buffers in the widget (chat, prompt, code, files)
widget = {
close = "q", -- String for a single keybinding
change_mode = {
{
"<S-Tab>",
mode = { "i", "n", "v" }, -- Specify modes for this keybinding
},
},
switch_provider = "<localLeader>s", -- Switch ACP provider
switch_model = "<localLeader>m", -- Switch model
change_thought_level = "<localLeader>t", -- Select thought effort level
},
-- Keybindings for the prompt buffer only
prompt = {
submit = {
"<CR>", -- Normal mode, just Enter
{
"<C-s>",
mode = { "n", "v", "i" },
},
},
paste_image = {
{
"<localLeader>p",
mode = { "n" },
},
{
"<C-v>", -- Same as Claude-code in insert mode
mode = { "i" },
}
},
},
-- Keybindings for chat buffer navigation
chat = {
next_heading = "]]",
prev_heading = "[[",
next_tool_call = "]t",
prev_tool_call = "[t",
},
-- Keybindings for diff preview navigation
diff_preview = {
next_hunk = "]c",
prev_hunk = "[c",
},
-- Keybindings to cycle focus between pending permission blocks.
-- Once a block is focused, per-block keys cycle the stacked button
-- rows (one button per row, rendered between bottom_pad and the
-- status row):
-- h / <Left> / k / <Up> : focus previous button
-- l / <Right> / j / <Down> : focus next button
-- <CR> : submit focused button
-- 1..4 : submit option N directly
-- Per-block keys only fire while a block is focused.
permission = {
cycle_next = "<C-n>",
cycle_prev = "<C-p>",
},
},
},
}
Keymap Configuration Format:
- String:
close = "q"- Simple keybinding (normal mode by default) - Array:
submit = { "<CR>", "<C-s>" }- Multiple keybindings (normal mode
only) - Table with mode:
{ "<C-s>", mode = { "i", "v" } }- Keybinding with
specific modes
The header text in the chat and prompt buffers will automatically update to show
the appropriate keybinding for the current mode.
Diff Preview
When the agent makes file edits, agentic.nvim can show a preview of the changes
before you accept or reject them. You can configure the diff preview layout:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
diff_preview = {
enabled = true,
layout = "split", -- "split" or "inline"
center_on_navigate_hunks = true,
},
},
}
Layout Options:
"split"(default) - Side-by-side diff view"inline"- Unified diff view in a single buffer
Navigation:
Use ]c and [c to navigate between diff hunks (configurable).
Note: Changing the layout requires restarting Neovim.
Slash Commands
Type / in the Prompt buffer to see available slash commands with
auto-completion.
The /new command is always available to start a new session, other commands
are provided by your ACP provider.
File Picker
You can reference and add files to the context by typing @ in the Prompt.
It will trigger the native Neovim completion menu with a list of all files in
the current workspace.
- Automatic scanning: Uses
rg,fd,git ls-files, or lua globs as
fallback - Fuzzy filtering: uses Neovim's native completion to filter results as you
type - Multiple files: You can reference multiple files in one prompt:
@file1.lua @file2.lua
Image and Screenshots support
You can drag-and-drop images into the Prompt buffer or paste images and
screenshots directly from your clipboard.
The support still depends on the ACP provider capabilities, but most of them
support images in the conversation.
Drag-and-drop should work out of the box if your terminal supports it, no need
for extra configuration or plugins.
In SSH/headless sessions, image paste and drag-and-drop usually do not reach
remote Neovim, terminal and protocol limitations.
Agentic does not copy local files into the remote filesystem; upload the image
first with scp, SFTP, or your usual file-transfer workflow, then attach the
remote file path using the @... notation.
Pasting screenshots from your clipboard works out of the box on macOS, Windows,
and WSL when Windows interop and wslpath are available. On Linux, you need one
small CLI dependency:
- macOS: no extra install. Uses the system
osascript. - Windows: no extra install. Uses the bundled
powershell.exe. - WSL: no extra install when Windows interop and
wslpathare available. - Linux (Wayland): install
wl-clipboard(provideswl-paste).- Debian/Ubuntu:
sudo apt install wl-clipboard - Arch:
sudo pacman -S wl-clipboard - Fedora:
sudo dnf install wl-clipboard
- Debian/Ubuntu:
- Linux (X11): install
xclip.- Debian/Ubuntu:
sudo apt install xclip - Arch:
sudo pacman -S xclip - Fedora:
sudo dnf install xclip
- Debian/Ubuntu:
Then just press <localleader>p in the Prompt buffer to paste the image from
your clipboard.
Session Restoration
Sessions are interchangeable between Neovim and the terminal. Start a
conversation in your terminal CLI, then load it in Neovim — or the other way
around. Your ACP provider manages sessions natively, so they're available
everywhere the provider runs.
Restoring sessions:
Call require("agentic").restore_session() to:
- See a list of previous sessions from your provider for the current project
(including sessions started in the terminal) - Select a session to restore the full conversation history
If you know the session ID, callrequire("agentic").restore_session_by_id(session_id) to restore a specific
session directly. This skips listing sessions, so it also works with providers
that don't support session listing.
Conflict handling:
If you try to restore a session when the current tab already has an active
conversation, you'll be prompted to:
- Cancel the restoration (keep current session)
- Clear current session and restore the selected one
System Information
Agentic automatically includes environment and project information in the first
message of each session:
- Platform information (OS, version, architecture)
- Shell and Neovim version
- Current date
- Git repository status (if applicable):
- Current branch
- Changed files
- Recent commits (last 3)
- Project root path
This helps the AI Agent understand the context of the current project without
having to run additional commands or grep through files, the goals is to reduce
time for the first response.
Event Hooks
Agentic.nvim provides hooks that let you respond to specific events during the
chat lifecycle. These are useful for logging, notifications, analytics, or
integrating with other plugins.
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
hooks = {
-- Called when a new ACP session is created (or fails to create).
-- Fires on both success and failure; check `data.err` first.
on_create_session_response = function(data)
-- data.session_id: string|nil - The ACP session ID (nil if err is set)
-- data.tab_page_id: number - The Neovim tabpage ID
-- data.response: table|nil - The ACP session creation response
-- (nil if err is set)
-- data.err: table|nil - Error details if session creation failed
if data.err then
vim.notify(
"Session failed: " .. vim.inspect(data.err),
vim.log.levels.ERROR
)
return
end
vim.notify("New session: " .. data.response.sessionId)
-- Reset the agentic_usage tabpage var (set by the on_session_update
-- example below) so a new session starts with a clean usage counter.
if vim.api.nvim_tabpage_is_valid(data.tab_page_id) then
vim.t[data.tab_page_id].agentic_usage = nil
end
end,
-- Called when the user submits a prompt
on_prompt_submit = function(data)
-- data.prompt: string - The user's prompt text
-- data.session_id: string - The ACP session ID
-- data.tab_page_id: number - The Neovim tabpage ID
vim.notify("Prompt submitted: " .. data.prompt:sub(1, 50))
end,
-- Called when the agent finishes responding
on_response_complete = function(data)
-- data.session_id: string - The ACP session ID
-- data.tab_page_id: number - The Neovim tabpage ID
-- data.success: boolean - Whether response completed without error
-- data.error: table|nil - Error details if failed
if data.success then
vim.notify("Agent finished!", vim.log.levels.INFO)
else
vim.notify("Agent error: " .. vim.inspect(data.error), vim.log.levels.ERROR)
end
end,
-- Called when the session is updated.
on_session_update = function(data)
-- data.session_id: string - The ACP session ID
-- data.tab_page_id: number - The Neovim tabpage ID
-- data.update: table -- The update
if data.update.sessionUpdate == "usage_update" then
-- Use this in your status line, scoped per tab/session.
if vim.api.nvim_tabpage_is_valid(data.tab_page_id) then
vim.t[data.tab_page_id].agentic_usage = {
used = data.update.used,
size = data.update.size,
}
end
end
end,
-- Called after Agentic writes to a file (file-mutating tool call completed).
-- Note: mutating the file here (e.g. formatters that save) can cause the
-- agent to re-read or retry edits on its next action.
on_file_edit = function(data)
-- data.filepath: string - Absolute path to the edited file
-- data.session_id: string - The ACP session ID
-- data.tab_page_id: number - The Neovim tabpage ID
-- data.bufnr: number|nil - Buffer number if the file is loaded
if data.bufnr then
vim.lsp.buf.format({ bufnr = data.bufnr, timeout_ms = 5000 })
end
end,
-- Called when the agent needs permission to execute a tool (e.g. shell command).
-- Fires for each pending permission request.
on_request_permission = function(data)
-- data.request: table - The ACP permission request object
-- data.request.toolCall: table - contains .kind, .title, etc.
-- data.session_id: string - The ACP session ID
-- data.tab_page_id: number - The Neovim tabpage ID
local tool = data.request.toolCall
local label = tool.title or tool.kind or "action"
vim.notify("Agent needs permission for: " .. label)
end,
}
}
}
🍚 Customization (Ricing)
Agentic.nvim uses custom highlight groups that you can override to match your
colorscheme.
Available Highlight Groups
| Highlight Group | Purpose | Default |
|---|---|---|
AgenticDiffDelete |
Deleted lines in diff view | Links to DiffDelete |
AgenticDiffAdd |
Added lines in diff view | Links to DiffAdd |
AgenticDiffDeleteWord |
Word-level deletions in diff | bg=#9a3c3c, bold=true |
AgenticDiffAddWord |
Word-level additions in diff | bg=#155729, bold=true |
AgenticStatusPending |
Pending tool call status indicator | bg=#5f4d8f |
AgenticStatusCompleted |
Completed tool call status indicator | bg=#2d5a3d |
AgenticStatusFailed |
Failed tool call status indicator | bg=#7a2d2d |
AgenticPermissionButtonAllow |
Focused button (allow kind) | bg=#2d5a3d, bold=true |
AgenticPermissionButtonReject |
Focused button (reject kind) | bg=#7a2d2d, bold=true |
AgenticPermissionButtonInactive |
Non-focused permission button | bg=#3a3a3a |
AgenticCodeBlockFence |
The left border decoration on tool calls | Links to Directory |
AgenticTitle |
Window titles in sidebar | bg=#2787b0, fg=#000000, bold=true |
AgenticThinking |
Thinking block text in chat buffer | Links to Comment |
If any of these highlight exists, Agentic will use it instead of creating new
ones.
Customizing Diagnostic Icons
You can customize the icons used for diagnostics in the context panel:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
diagnostic_icons = {
error = "❌", -- Diagnostic severity: error
warn = "⚠️", -- Diagnostic severity: warning
info = "ℹ️", -- Diagnostic severity: information
hint = "✨", -- Diagnostic severity: hint
},
},
}
Default icons use emoji characters (❌, ⚠️, ℹ️, ✨) but you can use any string,
including Nerd Font icons or plain text.
Customizing Status Icons
You can customize the icons used to indicate tool call status in the chat:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
status_icons = {
pending = "", -- Tool call awaiting execution
in_progress = "", -- Tool currently executing
completed = "✔", -- Tool executed successfully
failed = "", -- Tool execution failed
},
},
}
Customizing Permission Icons
You can customize the icons used in the permission approval workflow:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
permission_icons = {
allow_once = "", -- Allow this execution only
allow_always = "", -- Allow all future executions
reject_once = "", -- Reject this execution only
reject_always = "", -- Reject all future executions
},
},
}
Customizing Chat Icons
You can customize the icons used to identify user and agent messages in the
chat:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
chat_icons = {
user = " ", -- Icon shown for user messages
agent = " ", -- Icon shown for agent/AI messages
},
},
}
Customizing Message Icons
You can customize the icons used for messages and interaction states:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
message_icons = {
thinking = "🧠", -- Shown when the agent is thinking/reasoning
finished = "🏁", -- Shown when the interaction completes successfully
stopped = "🛑", -- Shown when the user cancels the generation
error = "❌", -- Shown when the interaction ends with an error
},
},
}
Integration with other Plugins
Prompt suggestions with Copilot
To get Copilot suggestions while you are typing your prompt, you need to tell
Copilot to attach to the AgenticInput filetype.
copilot.vim
{
"github/copilot.vim",
-- ....
init = function()
vim.g.copilot_filetypes = {
AgenticInput = true,
}
end,
}
copilot.lua
{
"zbirenbaum/copilot.lua",
-- ....
opts = {
-- Override should_attach to allow copilot in AgenticInput buffers
-- AgenticInput uses buftype = "nofile" which copilot.lua rejects by default
should_attach = function(bufnr, bufname)
local filetype = vim.bo[bufnr].filetype
if filetype == "AgenticInput" then
return true
end
-- Delegate to default behavior for all other buffers
local default_should_attach =
require("copilot.config.should_attach").default
return default_should_attach(bufnr, bufname)
end,
},
}
Lualine
If you're using lualine.nvim or
similar statusline plugins, configure it to ignore Agentic windows to prevent
conflicts with custom window decorations:
require('lualine').setup({
options = {
disabled_filetypes = {
statusline = { 'AgenticChat', 'AgenticInput', 'AgenticCode', 'AgenticFiles', 'AgenticDiagnostics' },
winbar = { 'AgenticChat', 'AgenticInput', 'AgenticCode', 'AgenticFiles', 'AgenticDiagnostics' },
}
}
})
This ensures that Agentic's custom window titles and statuslines render
correctly without interference from your statusline plugin.
Markdown render plugins
Only the AgenticChat buffer is properly set as markdown and starts
Treesitter parser, you only need to mention it in your markdown render plugin
setup.
{
"MeanderingProgrammer/render-markdown.nvim",
-- ...
opts = {
file_types = { "markdown", "md", "AgenticChat" },
}
}
Blink.cmp
You can disable blink.cmp from attaching to Agentic prompt buffers by adding
the following to your blink.cmp setup:
require('blink.cmp').setup({
enabled = function()
return not vim.tbl_contains({"AgenticInput"}, vim.bo.filetype)
end,
})
Alternatively, you can disable Agentic's built-in autocomplete and let blink.cmp handle slash command and file picker completions in the prompt buffer:
{
"carlos-algms/agentic.nvim",
opts = {
slash_commands = {
auto_trigger = false,
},
file_picker = {
auto_trigger = false,
},
},
}
{
'saghen/blink.cmp',
version = '1.*',
opts = {
-- ...
completion = {
menu = {
draw = {
components = {
-- Increase the label description width to show more of the slash
-- command descriptions
label_description = {
width = { max = 100 },
},
},
},
},
},
sources = {
per_filetype = {
-- You can also enable copilot here if you want copilot suggestions in the Prompt buffer
AgenticInput = { 'agentic_slash', 'agentic_at' },
},
providers = {
agentic_slash = {
module = 'blink.cmp.sources.complete_func',
name = 'AgenticSlash',
-- Detect / at the start of the prompt input to trigger slash command completions
enabled = function()
local cursor = vim.api.nvim_win_get_cursor(0)
if cursor[1] ~= 1 then return false end
local before = vim.api.nvim_get_current_line():sub(1, cursor[2])
return before:match('^/[^%s]*$') ~= nil
end,
opts = { complete_func = function() return "v:lua.require'agentic.acp.slash_commands'.complete_func" end },
-- Fix output by removing / added in label details
transform_items = function(_, items)
for _, item in ipairs(items) do
if item.labelDetails then
item.labelDetails.detail = nil
end
end
return items
end,
},
agentic_at = {
module = 'blink.cmp.sources.complete_func',
-- Detect @ is before the cursor to trigger file picker completions
name = 'AgenticAt',
enabled = function()
local col = vim.api.nvim_win_get_cursor(0)[2]
local before = vim.api.nvim_get_current_line():sub(1, col)
return (before:match('^@[^%s]*$') or before:match('[%s]@[^%s]*$')) ~= nil
end,
opts = { complete_func = function() return "v:lua.require'agentic.ui.file_picker'.complete_func" end },
-- Fix output by removing @ added in label details
transform_items = function(_, items)
for _, item in ipairs(items) do
if item.labelDetails then
item.labelDetails.detail = nil
end
end
return items
end,
},
},
},
},
}
nvim-cmp
You can disable nvim-cmp from attaching to Agentic prompt buffers by using
filetype-specific setup or the enabled option:
-- Option 1: Filetype-specific setup (disable all sources)
require('cmp').setup.filetype('AgenticInput', {
sources = {}
})
-- Option 2: Global enabled function
require('cmp').setup({
enabled = function()
return not vim.tbl_contains({"AgenticInput"}, vim.bo.filetype)
end,
})
❤️ Sponsor
If agentic.nvim makes your day better, consider sponsoring development. Pick
whichever channel you prefer - all of them help equally.
🏢 For companies
Does your company have the budget to sponsor open source?
Sponsoring agentic.nvim gets your team:
- Logo placement in this README
- Direct line to the maintainer
- Priority consideration on issues affecting your workflow
Reach out via GitHub Sponsors or
open an issue to
discuss custom terms.
🔧 Development
Health Check
Verify your installation and dependencies:
:checkhealth agentic
This will check:
- Neovim version (≥ 0.11.0 required)
- Current ACP provider installation (We don't install them for security reasons)
- Optional ACP providers (so you know which ones are available and can use at
any time) - Clipboard image paste tooling (
powershell.exe,wslpath,wl-paste, orxclip) - Node.js and package managers (Most of the ACP CLIs require Node.js to install
and run, some have native binaries too, we don't have control over that, it up
to the Creators)
Debug Mode
Enable debug logging to troubleshoot issues:
{
"carlos-algms/agentic.nvim",
--- @type agentic.PartialUserConfig
opts = {
debug = true,
-- ... rest of your options
}
}
View debug logs with :messages (lost after restarting Neovim)
View messages exchanged with the ACP provider in the log file at:
(persistent until you delete it)
~/.cache/nvim/agentic_debug.log
📚 Resources
📄 License
MIT License
Feel free to copy, modify, and distribute, just be a good samaritan and include
the the acknowledgments 😊.
🙏 Acknowledgments
- Built on top of the Agent Client Protocol
specification - CopilotChat.nvim - for
being my entrance point of chatting with AI in Neovim - codecompanion.nvim - for
the buffer writing inspiration - avante.nvim - for the ACP client code
and sidebar structured with multiple panels
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi