Using the Chat Buffer 
NOTE
The chat buffer has a filetype of codecompanion and a buftype of nofile.
You can open a chat buffer with the :CodeCompanionChat command or with require("codecompanion").chat() and you can toggle the visibility of the chat buffer with :CodeCompanionChat Toggle or require("codecompanion").toggle().
You can even customize the chat buffer's window options:
require("codecompanion").chat({ window_opts = { layout = "float", width = 0.6 }})
-- or:
require("codecompanion").toggle({ window_opts = { layout = "float", width = 0.6 }})The chat buffer uses markdown as its syntax and H2 headers separate the user and LLM's responses. The plugin is turn-based, meaning that the user sends a response which is then followed by the LLM's. The user's responses are parsed by treesitter and sent via an adapter to an LLM for a response which is then streamed back into the buffer. A response is sent to the LLM by pressing <CR> or <C-s>. This can of course be changed as per the keymaps section.
Changing Adapter 
One of the joys of working with CodeCompanion is being able to switch between conversing with an LLM and an agent, all from within the chat buffer.
To do this, simply press ga to open up the Select Adapter select window. If your chosen adapter has more than one model (in the case of HTTP adapters) or command (in the case of ACP adapters) then you'll be prompted to make another selection.
Messages 
TIP
The message history and adapter settings can be modified via the debug window (gd) in the chat buffer
It's important to note that some messages, such as system prompts or context provided via Slash Commands, will be hidden. This is to keep the chat buffer uncluttered from a UI perspective. Using the gd keymap opens up the debug window, which allows the user to see the full contents of the messages table which will be sent to the LLM on the next turn.
The message history cannot be altered directly in the chat buffer. However, it can be modified in the debug window. This window is simply a Lua buffer which the user can edit as they wish. To persist any changes, the chat buffer keymaps for sending a message (defaults: <CR> or <C-s>) can be used.
Images / Vision 
Many LLMs have the ability to receive images as input (sometimes referred to as vision). CodeCompanion supports the adding of images into the chat buffer via the /image slash command and through the system clipboard with img-clip.nvim. CodeCompanion can work with images in your file system and also with remote URLs, encoding both into a base64 representation.
If your adapter and model doesn't support images, then CodeCompanion will endeavour to ensure that the image is not included in the messages payload that's sent to the LLM.
Context 
Sharing context with an LLM is crucial in order to generate useful responses. In the plugin, context is defined as output that is shared with a chat buffer via a Variable, Slash Command or Tool. They appear in a blockquote entitled Context. In essence, this is context that you're sharing with an LLM.
IMPORTANT
Context items contain the data of an object at a point in time. By default, they are not self-updating
In order to allow for context to self-update, they can be pinned (for files and buffers) or watched (for buffers).
File and buffer context items can be pinned to a chat buffer with the gp keymap (when your cursor is on the line of the shared buffer in the "> Context section). Pinning results in the content from the object being reloaded and shared with the LLM on every turn. The advantage of this is that the LLM will always receive a fresh copy of the source data regardless of any changes. This can be useful if you're working with tools. However, please note that this can consume a lot of tokens.
Buffer context items can be watched via the gw keymap (when your cursor is on the line of the shared buffer in the "> Context section). Watching, whilst similar to pinning, is a more token-conscious way of keeping the LLM up to date on the contents of a buffer. Watchers track changes (adds, edits, deletes) in the underlying buffer and update the LLM on each turn, with only those changes.
If a context item is added by mistake, it can be removed from the chat buffer by simply deleting it from the Context blockquote. On the next turn, all data related to that context item will be removed from the message history.
Finally, it's important to note that all http adapter endpoints require the sending of previous messages that make up the conversation. So even though you've shared context once, many messages ago, the LLM will always be able to refer to it, unless you actively alter the history of the conversation via gd.
Super Diff 
When an LLM uses tools like insert_edit_into_file to make changes across multiple files and buffers, it can be difficult to keep track. This is amplified if the tools are working without requiring approvals (perhaps via automatic tool mode) and it simply isn't impossible to keep track of what an LLM has added, deleted or modified.
Super Diff gives you a single, unified view of all edits made in via the chat buffer. Open it with gD to review every change, grouped by file, with visual diffs and status indicators. You can accept or reject changes before they’re applied, keeping you in control of your codebase. You can even send changes to the quickfix list for easier navigation and review.
Settings 
When conversing with an LLM, it can be useful to tweak model settings in between responses in order to generate the perfect output. If settings are enabled (display.chat.show_settings = true), then a yaml block will be present at the top of the chat buffer which can be modified in between responses. The yaml block is simply a representation of an adapter's schema table.
Completion 
IMPORTANT
As of v17.5.0, variables and tools are wrapped in curly braces automatically, such as #{buffer} or @{files}
You can invoke the completion plugins by typing # or @ followed by the variable or tool name, which will trigger the completion menu. If you don't use a completion plugin, you can use native completions with no setup, invoking them with <C-_> from within the chat buffer.
When using an ACP adapter (such as claude-code), you can also type \ (backslash, by default) to get completions for ACP commands. These are agent-specific commands like /compact (compact chat history) that are dynamically discovered from the agent itself.
NOTE
It typically takes 1-5 seconds after opening a chat buffer for ACP commands to become available. The agent needs to initialize and scan for both built-in and custom commands. If you define a new custom command mid-session, the same delay applies before it appears in the completion list.
The backslash trigger is used to avoid conflicts with CodeCompanion's built-in Slash Commands. When you send a message, \command is automatically transformed to /command for the agent. The trigger character can be customized via strategies.chat.slash_commands.opts.acp.trigger in your config.
It's worth noting that not all commands available in ACP CLI tools are exposed via the SDK. Only a subset of built-in commands are supported, though this is constantly evolving as the underlying SDKs mature.
Keymaps 
The plugin has a host of keymaps available in the chat buffer. Pressing ? in the chat buffer will conveniently display all of them to you.
The keymaps available to the user in normal mode are:
<CR>|<C-s>to send a message to the LLM<C-c>to close the chat bufferqto stop the current requestgato change the adapter for the currentchatgcto insert a codeblock in the chat buffergdto view/debug the chat buffer's contentsgDto view the chat buffer's super diff featuregfto fold any codeblocks in the chat buffergMto clear all memory from the chat buffergpto pin an item to the context in the chat buffergrto regenerate the last responsegRto go to the file under cursor. If the file is already opened, it'll jump to the existing window. Otherwise, it'll be opened in a new tab.gsto toggle the system prompt on/offgSto show copilot usage statsgtato toggle auto tool modegwto watch a buffer as context in the chat buffergxto clear the chat buffer's contentsgyto yank the last codeblock in the chat buffer[[to move to the previous header]]to move to the next header{to move to the previous chat}to move to the next chat
To disable a keymap, you can set it to false in your configuration:
require("codecompanion").setup({
  strategies = {
    chat = {
      keymaps = {
        clear = false,
      }
    }
  }
})