Using the Chat Buffer
The chat buffer is where you converse with an LLM or an agent. It's a markdown buffer, with a filetype of codecompanion, where H2 headers separate your messages from the LLM's responses.
To open a chat buffer:
:CodeCompanionChatTo show or hide it:
:CodeCompanionChat ToggleThe Lua equivalents, require("codecompanion").chat() and require("codecompanion").toggle(), also accept window options:
require("codecompanion").chat({ window_opts = { layout = "float", width = 0.6 } })Press <CR> or <C-s> in normal mode, or <C-s> in insert mode, to send your message. The response streams back into the buffer. Whilst the LLM is responding, press gm to send it a follow-up, which CodeCompanion delivers once it's safe to do so. To write your messages in a separate split instead, see Customising the Chat Experience.
Action Palette
From a chat buffer, :CodeCompanionActions opens the chat's own Action Palette, listing its keymaps and slash commands.
Changing Adapter and Model
Press ga to pick a different adapter. If the adapter has more than one model, you're asked to pick one of those too. This works for both HTTP and ACP adapters, so you can move between an LLM and an agent in the same chat.
Changing ACP Command
ACP adapters start the agent with a command from your configuration, default unless you choose otherwise. To start one with a different command:
:CodeCompanionChat adapter=gemini_cli command=yoloFrom inside a chat buffer, use the /command slash command.
Completion
Type a trigger character to open the completion menu:
| Trigger | Completes |
|---|---|
# | Editor context, such as #{buffer} |
@ | Tools, such as @{agent} |
/ | Slash commands |
\ | Commands from an ACP agent, such as \compact |
Completion works with blink.cmp, nvim-cmp and coc.nvim. Without a completion plugin, press <C-_> for native completion. The trigger characters can be changed under opts.triggers.
ACP commands come from the agent itself, and CodeCompanion turns \command into /command when you send the message. The backslash keeps them apart from CodeCompanion's own slash commands.
NOTE
ACP commands take a few seconds to appear after you open a chat buffer, and only the commands an agent exposes through its SDK are listed
Context
Add context with editor context, slash commands and tools. Each item is listed in a Context blockquote at the top of your message.
IMPORTANT
A context item is a snapshot of its source at the time it was added. Only #{buffer} and #{buffers} stay in sync by default
To keep any other buffer or file up to date, sync it to the chat buffer. Put your cursor on the context item and press:
gbato send its entire content on every turngbdto send only what's changed since the last turn
Sending the entire content means the LLM always sees the latest version, at the cost of more tokens. Sending the diff is cheaper.
Some file types are worth syncing as soon as they're added. Jupyter Notebooks change on disk every time a cell runs, so they're synced by default. To add more, see Syncing.
HTTP adapters send the whole conversation on every turn, so the LLM can refer to context you shared many messages ago. To change that history, use the debug window.
Adding via Paths
To attach a file or URL, write it as a markdown link:
I want to share [File](~/Code/Neovim/codecompanion.nvim/README.md) with youWhen you send the message, the file is attached and the link is replaced with its path. This works for text files, images and PDFs. URLs are fetched with the fetch slash command's adapter, without a cache.
Markdown can't parse a bare space in a link, so wrap a path that contains one:
| Link | Attached |
|---|---|
[File](/Users/Oli/Downloads/report.txt) | Yes |
[File](</Users/Oli/Downloads/some report.txt>) | Yes |
[File]('/Users/Oli/Downloads/some report.txt') | Yes |
[File]("/Users/Oli/Downloads/some report.txt") | Yes |
[File](/Users/Oli/Downloads/some report.txt) | No |
Removing
To remove a context item, delete its line from the Context blockquote. On the next turn, everything it added is removed from the message history.
Debug Window
Press gd to open the debug window. It shows what's sent to the LLM on the next turn: the adapter's settings, the context items and the full message history, including the system prompt and other messages hidden from the chat buffer.
The debug window is a Lua buffer. Edit it, then press <C-s> to write your changes back to the chat buffer.
Generating Titles
CodeCompanion can give each chat buffer a title, written by a background interaction. To turn it on:
require("codecompanion").setup({
interactions = {
background = {
chat = {
opts = {
enabled = true,
},
},
},
},
})See Chat Titles to choose the model that writes them.
Images
Add images from disk with /file, from a URL with /file-from-url, or from the clipboard with img-clip.nvim. Both local and remote images are base64 encoded.
If the model doesn't accept images, CodeCompanion leaves them out of the request.
Keymaps
Press ? in a chat buffer to list every keymap. The defaults in normal mode are:
| Keymap | Name | Description |
|---|---|---|
<CR> <C-s> | send | Send the message to the LLM |
<C-c> | close | Close the chat buffer |
q | stop | Stop the current request |
ga | change_adapter | Change adapter and model |
gba | sync_all | Toggle live-syncing of a context item |
gbd | sync_diff | Toggle diff-only syncing of a context item |
gc | codeblock | Insert an empty codeblock |
gd | debug | Open the debug window |
gf | fold_code | Fold all codeblocks |
gm | _btw | Send a follow-up whilst the LLM is responding |
gM | rules | Remove rules from the chat |
gr | regenerate | Regenerate the last response |
gR | goto_file_under_cursor | Open the file path under the cursor |
gs | system_prompt | Toggle the system prompt on and off |
gS | copilot_stats | Show Copilot usage statistics |
gtx | clear_approvals | Reset cached tool approvals |
gty | yolo_mode | Choose how tool calls are approved |
gx | clear | Clear all messages from the chat |
gy | yank_code | Yank code from the last codeblock |
K | tool_call_details | Show the tool call under the cursor |
} { | next_chat previous_chat | Move to the next or previous chat |
]] [[ | next_header previous_header | Jump to the next or previous header |
In insert mode, <C-s> sends the message, <C-c> closes the chat buffer and <C-_> opens the completion menu. To change any of them, see Keymaps.
Multiple Chats
Open as many chat buffers as you like. Cycle through them with { and }, and use :CodeCompanionChat Toggle to show or hide the last one.
By default, opening or cycling to a chat hides the one that's visible. To give each tab its own chat, so a chat in one tab is never closed or replaced from another:
require("codecompanion").setup({
display = {
chat = {
window = {
pertab = true,
},
},
},
})With pertab enabled, { and } only cycle through chats that are visible in the current tab or hidden everywhere, and :CodeCompanionChat Toggle jumps to the tab a chat lives in.
Settings
To tweak the model's settings between responses, show them as a YAML block at the top of the chat buffer:
require("codecompanion").setup({
display = {
chat = {
show_settings = true,
},
},
})The block mirrors the adapter's schema table. Edit a value and it's used from the next response onwards.