@@ -41,7 +41,7 @@ CopilotChat.nvim brings GitHub Copilot Chat capabilities directly into Neovim
4141with a focus on transparency and user control.
4242
4343- 🤖 **Multiple AI Models** - GitHub Copilot (including GPT-4o, Gemini 2.5 Pro, Claude 4 Sonnet, Claude 3.7 Sonnet, Claude 3.5 Sonnet, o3-mini, o4-mini) + custom providers (Ollama, Mistral.ai). The exact list of available models depends on your GitHub Copilot settings <https://github.com/settings/copilot/features > and the models provided by GitHub’s API.
44- - 🔧 **Tool Calling** - LLM can call workspace functions (file reading, git operations, search) with your explicit approval
44+ - 🔧 **Tool Calling** - LLM can call workspace functions (file reading, git operations, search) with manual approval or automatic execution for trusted tools
4545- 🔒 **Privacy First** - Only shares what you explicitly request - no background data collection
4646- 📝 **Interactive Chat** - Interactive UI with completion, diffs, and quickfix integration
4747- 🎯 **Smart Prompts** - Composable templates and sticky prompts for consistent context
@@ -126,7 +126,7 @@ VIM-PLUG *CopilotChat-vim-plug*
1261262. Core Concepts *CopilotChat-core-concepts*
127127
128128- **Resources** (`#<name> ` ) - Add specific content (files, git diffs, URLs) to your prompt
129- - **Tools** (`@ <name> ` ) - Give LLM access to functions it can call with your approval
129+ - **Tools** (`@ <name> ` ) - Give LLM access to functions it can call during the chat, with manual approval by default
130130- **Sticky Prompts** (`> <text> `) - Persist context across single chat session
131131- **Models** (`$ <model> ` ) - Specify which AI model to use for the chat
132132- **Prompts** (`/PromptName` ) - Use predefined prompt templates for common tasks
@@ -149,10 +149,17 @@ EXAMPLES *CopilotChat-examples*
149149 > You are a helpful coding assistant
150150<
151151
152- When you use `@c opilot` , the LLM can call functions like `bash` , `edit ` ,
153- `file ` , `glob ` , `grep ` , `gitdiff` etc. You’ll see the proposed function call
154- and can approve/reject it before execution.
152+ When you use `@c opilot` , the LLM can call functions from the `copilot` group
153+ such as `bash` , `edit ` , `file ` , `glob ` , `grep ` , and `gitdiff` .
155154
155+ - By default, proposed tool calls wait for your approval.
156+ - You can configure `trusted_tools` to automatically run specific tools or groups.
157+ - Resources added with `#... ` are resolved immediately and shared as context.
158+ - Tool call results are sent back to the model as plain output, while manual resources keep their `##<uri> ` references in chat.
159+
160+
161+ [!WARNING ] `trusted_tools = true` allows the model to run every enabled tool
162+ without asking. Only use it if you fully trust the tool set and workspace.
156163
157164==============================================================================
1581653. Usage *CopilotChat-usage*
@@ -177,16 +184,15 @@ COMMANDS *CopilotChat-commands*
177184CHAT KEY MAPPINGS *CopilotChat-chat-key-mappings*
178185
179186 Insert Normal Action
180- -------- -------- --------------------------------------------
187+ -------- -------- -------------------------------------------
181188 <Tab> - Trigger/accept completion menu for tokens
182189 <C-c> q Close the chat window
183190 <C-l> <C-l> Reset and clear the chat window
184191 <C-s> <CR> Submit the current prompt
185- - grr Toggle sticky prompt for line under cursor
186192 <C-y> <C-y> Accept nearest diff
187193 - gj Jump to section of nearest diff
188- - gqa Add all answers from chat to quickfix list
189- - gqd Add all diffs from chat to quickfix list
194+ - gqa Add all answers from chat to quickfix
195+ - gqd Add all diffs from chat to quickfix
190196 - gy Yank nearest diff to register
191197 - gd Show diff between source and nearest diff
192198 - gc Show info about current chat
@@ -205,39 +211,44 @@ PREDEFINED FUNCTIONS *CopilotChat-predefined-functions*
205211
206212All predefined functions belong to the `copilot` group.
207213
208- -------------------------------------------------------------------------------------
209- Function Type Description Example Usage
210- ----------- ---------- ----------------------------------------- --------------------
211- bash Tool Executes a bash command and returns @copilot only
212- output
214+ ----------------------------------------------------------------------------------
215+ Function Manual Description Example Usage
216+ #...
217+ ----------- --------- --------------------------------------- --------------------
218+ bash No Executes a bash command and returns @copilot
219+ output
213220
214- buffer Resource Retrieves content from buffer(s) with #buffer:active
215- diagnostics
221+ buffer Yes Retrieves content from buffer(s) with #buffer:active
222+ diagnostics
216223
217- clipboard Resource Provides access to system clipboard #clipboard
218- content
224+ clipboard Yes Provides access to system clipboard #clipboard
225+ content
219226
220- edit Tool Applies a unified diff to a file @copilot only
227+ edit No Applies a unified diff to a file @copilot
221228
222- file Resource Reads content from a specified file path #file:path/to/file
229+ file Yes Reads content from a specified file #file:path/to/file
230+ path
223231
224- gitdiff Resource Retrieves git diff information #gitdiff:staged
232+ gitdiff Yes Retrieves git diff information #gitdiff:staged
225233
226- glob Resource Lists filenames matching a pattern in #glob:**/*.lua
227- workspace
234+ glob Yes Lists filenames matching a pattern in #glob:**/*.lua
235+ workspace
228236
229- grep Resource Searches for a pattern across files in #grep:TODO
230- workspace
237+ grep Yes Searches for a pattern across files in #grep:TODO
238+ workspace
231239
232- selection Resource Includes the current visual selection #selection
233- with diagnostics
240+ selection Yes Includes the current visual selection #selection
241+ with diagnostics
234242
235- url Resource Fetches content from a specified URL #url:https://...
236- -------------------------------------------------------------------------------------
237- **Type Legend:**
243+ url Yes Fetches content from a specified URL #url:https://...
244+ ----------------------------------------------------------------------------------
245+ `# ... ` resolves a function immediately and adds its output as chat context.
238246
239- - **Resource**: Can be used manually via `#function ` syntax
240- - **Tool**: Can only be called by LLM via `@c opilot` (for safety/complexity reasons)
247+ `@c opilot` shares the enabled functions with the model so it can choose when to
248+ call them.
249+
250+ Only `bash` and `edit ` are tool-only. The rest can be used both as manual
251+ resources and as callable tools.
241252
242253
243254PREDEFINED PROMPTS *CopilotChat-predefined-prompts*
@@ -276,6 +287,7 @@ Most users only need to configure a few options:
276287 {
277288 model = 'gpt-4.1', -- AI model to use
278289 temperature = 0.1, -- Lower = focused, higher = creative
290+ trusted_tools = nil, -- Require approval for all tool calls
279291 window = {
280292 layout = 'vertical' , -- 'vertical' , 'horizontal' , 'float'
281293 width = 0.5, -- 50% of screen width
@@ -309,13 +321,15 @@ WINDOW & APPEARANCE *CopilotChat-window-&-appearance*
309321 }
310322<
311323
324+ `window .layout` also supports `' replace' ` to reuse the current window.
325+
312326
313327BUFFER BEHAVIOR *CopilotChat-buffer-behavior*
314328
315329>lua
316330 -- Auto-command to customize chat buffer behavior
317331 vim.api.nvim_create_autocmd('BufEnter', {
318- pattern = 'copilot-* ',
332+ pattern = 'copilot-chat ',
319333 callback = function()
320334 vim.opt_local.relativenumber = false
321335 vim.opt_local.number = false
@@ -348,6 +362,7 @@ Types of copilot highlights:
348362- `CopilotChatModel` - Model highlight in chat buffer (e.g. `$gpt - 4.1 ` )
349363- `CopilotChatUri` - URI highlight in chat buffer (e.g. `##https: // ... ` )
350364- `CopilotChatAnnotation` - Annotation highlight in chat buffer (file headers, tool call headers, tool call body)
365+ - `CopilotChatAnnotationHeader` - Annotation header highlight in chat buffer
351366
352367
353368PROMPTS *CopilotChat-prompts*
@@ -376,14 +391,45 @@ Define your own prompts in the configuration:
376391
377392FUNCTIONS *CopilotChat-functions*
378393
394+ Use `trusted_tools` to control which tool calls are executed automatically:
395+
396+ >lua
397+ {
398+ trusted_tools = nil, -- default: require approval for all tool calls
399+
400+ -- trust all functions in a group
401+ -- trusted_tools = 'copilot' ,
402+
403+ -- trust specific functions by name or groups by name
404+ -- trusted_tools = { 'file' , 'glob' , 'grep' },
405+
406+ -- trust every enabled tool call
407+ -- trusted_tools = true,
408+ }
409+ <
410+
411+ A tool is trusted when any of these match:
412+
413+ - Its function definition sets `trusted = true`
414+ - Its function name appears in `trusted_tools`
415+ - Its function group appears in `trusted_tools`
416+ - `trusted_tools = true`
417+
418+ For most setups, trusting a few read-only functions such as `file ` , `glob ` , or
419+ `grep ` is safer than trusting everything.
420+
421+
422+ [!WARNING ] Trusted tools run without asking for confirmation. Be especially
423+ careful with tools like `bash` and `edit ` , which can change your workspace.
379424Define your own functions in the configuration with input handling and schema:
380425
381426>lua
382427 {
383428 functions = {
384429 birthday = {
385- description = "Retrieves birthday information for a person",
386- uri = "birthday://{name} ",
430+ description = 'Retrieves birthday information for a person',
431+ uri = 'birthday://{name} ',
432+ trusted = false,
387433 schema = {
388434 type = 'object' ,
389435 required = { 'name' },
@@ -401,14 +447,17 @@ Define your own functions in the configuration with input handling and schema:
401447 uri = 'birthday://' .. input.name,
402448 mimetype = 'text/plain',
403449 data = input.name .. ' birthday info',
404- }
450+ },
405451 }
406- end
407- }
452+ end,
453+ },
408454 }
409455 }
410456<
411457
458+ If a function has a `uri` , it can be used manually with `#birthday:Alice` .
459+ Functions without a `uri` are tool-only and can only be called by the model.
460+
412461
413462PROVIDERS *CopilotChat-providers*
414463
@@ -418,9 +467,9 @@ Add custom AI providers:
418467 {
419468 providers = {
420469 my_provider = {
421- get_url = function(opts) return " https://api.example.com/chat " end,
422- get_headers = function() return { [" Authorization" ] = " Bearer " .. api_key } end,
423- get_models = function() return { { id = " gpt-4.1" , name = " GPT-4.1 model" } } end,
470+ get_url = function(opts) return ' https://api.example.com/chat ' end,
471+ get_headers = function() return { [' Authorization' ] = ' Bearer ' .. api_key } end,
472+ get_models = function() return { { id = ' gpt-4.1' , name = ' GPT-4.1 model' } } end,
424473 prepare_input = require('CopilotChat.config.providers').copilot.prepare_input,
425474 prepare_output = require('CopilotChat.config.providers').copilot.prepare_output,
426475 }
@@ -436,7 +485,7 @@ Add custom AI providers:
436485 disabled?: boolean,
437486
438487 -- Optional: Extra info about the provider displayed in info panel
439- get_info?(): string[]
488+ get_info?(headers: table ): string[]
440489
441490 -- Optional: Get extra request headers with optional expiration time
442491 get_headers?(): table<string,string>, number?,
@@ -452,13 +501,16 @@ Add custom AI providers:
452501
453502 -- Optional: Get available models
454503 get_models?(headers: table): table<CopilotChat.Provider.model>,
504+
505+ -- Optional: Resolve a user-facing model id to a provider model id
506+ resolve_model?(headers: table, model: string): string,
455507 }
456508<
457509
458510**Built-in providers:**
459511
460512- `copilot` - GitHub Copilot (default)
461- - `github_models` - GitHub Marketplace models (disabled by default)
513+ - `github_models` - GitHub Models (disabled by default)
462514
463515
464516==============================================================================
@@ -468,7 +520,7 @@ Add custom AI providers:
468520CORE *CopilotChat-core*
469521
470522>lua
471- local chat = require(" CopilotChat" )
523+ local chat = require(' CopilotChat' )
472524
473525 -- Basic Chat Functions
474526 chat.ask(prompt, config) -- Ask a question with optional config
@@ -499,7 +551,7 @@ CHAT WINDOW *CopilotChat-chat-window*
499551You can also access the chat window UI methods through the `chat.chat` object:
500552
501553>lua
502- local window = require(" CopilotChat" ).chat
554+ local window = require(' CopilotChat' ).chat
503555
504556 -- Chat UI State
505557 window:visible() -- Check if chat window is visible
@@ -518,8 +570,8 @@ You can also access the chat window UI methods through the `chat.chat` object:
518570 window:finish() -- Finish writing to chat window
519571
520572 -- Source Management
521- window. get_source() -- Get the current source buffer and window
522- window. set_source(winnr) -- Set the source window
573+ window: get_source() -- Get the current source buffer and window
574+ window: set_source(winnr) -- Set the source window
523575
524576 -- Navigation
525577 window:follow() -- Move cursor to end of chat content
@@ -533,10 +585,11 @@ You can also access the chat window UI methods through the `chat.chat` object:
533585PROMPT PARSER *CopilotChat-prompt-parser*
534586
535587>lua
536- local parser = require(" CopilotChat.prompts" )
588+ local parser = require(' CopilotChat.prompts' )
537589
538590 parser.resolve_prompt() -- Resolve prompt references
539- parser.resolve_tools() -- Resolve tools that are available for automatic use by LLM
591+ parser.resolve_tools() -- Resolve tools shared with the model via @...
592+ parser.resolve_functions() -- Resolve manual function/resource references via #...
540593 parser.resolve_model() -- Resolve model from prompt (WARN: async, requires plenary.async.run)
541594<
542595
@@ -545,22 +598,26 @@ EXAMPLE USAGE *CopilotChat-example-usage*
545598
546599>lua
547600 -- Open chat, ask a question and handle response
548- require(" CopilotChat" ).open()
549- require(" CopilotChat" ).ask(" #buffer Explain this code" , {
601+ require(' CopilotChat' ).open()
602+ require(' CopilotChat' ).ask(' #buffer Explain this code' , {
550603 callback = function(response)
551- vim.notify("Got response: " .. response:sub(1, 50) .. "...")
552- return response
604+ vim.notify('Got response: ' .. vim.trim(response.content):sub(1, 50) .. '...')
553605 end,
554606 })
555607
556608 -- Save and load chat history
557- require(" CopilotChat" ).save(" my_debugging_session" )
558- require(" CopilotChat" ).load(" my_debugging_session" )
609+ require(' CopilotChat' ).save(' my_debugging_session' )
610+ require(' CopilotChat' ).load(' my_debugging_session' )
559611
560612 -- Use custom sticky and model
561- require("CopilotChat").ask("How can I optimize this?", {
562- model = "gpt-4.1",
563- sticky = {"#buffer", "#gitdiff:staged"}
613+ require('CopilotChat').ask('How can I optimize this?', {
614+ model = 'gpt-4.1',
615+ sticky = { '#buffer', '#gitdiff:staged' },
616+ })
617+
618+ -- Automatically trust a small read-only tool set
619+ require('CopilotChat').setup({
620+ trusted_tools = { 'file' , 'glob' , 'grep' },
564621 })
565622<
566623
@@ -595,6 +652,12 @@ To run tests:
595652 make test
596653<
597654
655+ To run the same formatting check as CI:
656+
657+ >bash
658+ stylua --check .
659+ <
660+
598661
599662CONTRIBUTING *CopilotChat-contributing*
600663
0 commit comments