Skip to main content

CopilotChat GlobFile Configuration

CopilotChat GlobFile Configuration

Want to feed multiple files into GitHub Copilot Chat from Neovim without listing each one manually? Let's add a tiny feature that does exactly that: a file glob that includes full file contents. In this post, we'll walk through what CopilotChat.nvim offers out of the box, why the missing piece matters, and how to implement a custom #file_glob:<pattern> function to include the contents of all files matching a glob.

Using Copilot Chat with Neovim

CopilotChat.nvim brings GitHub Copilot's chat right into your editing flow. No context switching, no browser hopping — just type your prompt in a Neovim buffer and let the AI help you refactor code, write tests, or explain tricky functions.

You can open the chat (for example) with a command like :CopilotChat, then provide extra context using built-in functions. That “extra context” is where the magic really happens.

Built-in functions in CopilotChat.nvim

Inside the chat window, you can inject context using special functions. Two handy ones are:

  • #file:<filename> — includes the full contents of that file.
  • #glob:<pattern> — expands to a list of filenames matching a pattern (filenames only, not contents).

For example, you could paste multiple files with:

#file:src/main.ts
#file:src/utils/strings.ts
#file:src/utils/dates.ts

Or you can ask Copilot to consider filenames that match a glob (again, names only):

#glob:src/**/*.ts

That's useful, but sometimes you really need the content of a bunch of files at once. Enter the missing piece.

The missing piece: #file_glob:<pattern>

We want to write something like:

#file_glob:src/**/*.ts

and have CopilotChat include the full contents of every matching file. This is incredibly convenient when you're:

  • Refactoring a feature that spans multiple files.
  • Writing tests across a directory.
  • Porting utilities from one folder to another.

CopilotChat.nvim doesn't ship this function by default, but the plugin is extensible, so we can add it ourselves in just a few lines of Lua.

Implementation: add file_glob to CopilotChat

Drop the following into your CopilotChat.nvim setup (for example, inside your plugin manager config). It extends the existing functions with a new one called file_glob that gathers files via a glob and returns their contents as resources for the chat.

local file_glob_function = {
  file_glob = {
    group = 'copilot',
    uri = 'files://glob_contents/{pattern}',
    description = 'Includes the full contents of every file matching a specified glob pattern.',
    schema = {
      type = 'object',
      required = { 'pattern' },
      properties = {
        pattern = {
          type = 'string',
          description = 'Glob pattern to match files.',
          default = '**/*',
        },
      },
    },
    resolve = function(input, source)
      local files = require('CopilotChat.utils.files').glob(source.cwd(), {
        pattern = input.pattern,
      })

      local resources = {}
      for _, file_path in ipairs(files) do
        local data, mimetype = require('CopilotChat.resources').get_file(file_path)
        if data then
          table.insert(resources, {
            uri = 'file://' .. file_path,
            name = file_path,
            mimetype = mimetype,
            data = data,
          })
        end
      end

      return resources
    end,
  },
}

require("CopilotChat").setup {
  -- other configuration
  functions = vim.tbl_deep_extend('force', require("CopilotChat.config.functions"), file_glob_function),
  -- other configuration
}

What this does

  • Extends the plugin's functions with file_glob, which:
    • Finds files using the provided pattern (relative to the workspace root).
    • Loads each file's content and MIME type.
    • Returns a list of resources that CopilotChat will attach to your conversation.

How to use #file_glob in chat

Inside an open Copilot Chat buffer, type a prompt and include a glob pattern. A few examples:

Please review the following TypeScript utils and suggest a common refactor.
#file_glob:src/utils/**/*.ts
Generate Jest tests for all reducers.
#file_glob:src/store/**/reducers/*.ts
Summarize the docs.
#file_glob:docs/**/*.md

Patterns are typically relative to your project root. Keep them as specific as possible to avoid pulling in huge numbers of files.

Tips, caveats, and troubleshooting

  • Token budgets are real: Including dozens of large files can exceed model context limits. Prefer narrower globs like src/**/parser/*.ts over project-wide patterns.
  • Binary or large files: The resolver reads file contents. If you match binaries or huge assets, you'll waste tokens and time. Use patterns that target source code (e.g., **/*.ts, **/*.py, **/*.lua).
  • Nothing happens? Verify your pattern is correct relative to the project root.
  • De-duplication is built-in: The resolver won't attach the same file twice.
  • Performance: If the glob is very broad (like **/*), it may scan a lot of files. Narrow it down to the folder or extension you actually need.

Wrapping up

With a small extension, CopilotChat.nvim becomes even more powerful for multi-file prompts. The custom #file_glob:<pattern> function lets you pull entire sets of files into context with a single line. It's a simple change with outsized impact on your day-to-day workflow.

Give it a try, tune your patterns, and enjoy a more fluid conversation with your code.

Popular posts from this blog

Undefined global vim

Defining vim as global outside of Neovim When developing plugins for Neovim, particularly in Lua, developers often encounter the "Undefined global vim" warning. This warning can be a nuisance and disrupt the development workflow. However, there is a straightforward solution to this problem by configuring the Lua Language Server Protocol (LSP) to recognize 'vim' as a global variable. Getting "Undefined global vim" warning when developing Neovim plugin While developing Neovim plugins using Lua, the Lua language server might not recognize the 'vim' namespace by default. This leads to warnings about 'vim' being an undefined global variable. These warnings are not just annoying but can also clutter the development environment with unnecessary alerts, potentially hiding other important warnings or errors. Defining vim as global in Lua LSP configuration to get rid of the warning To resolve the "Undefined global vi...

wget maven ntlm proxy

How to make wget, curl and Maven download behind an NTLM Proxy Working on CentOS, behind an NTLM proxy: yum can deal without problem with a NTLM Proxy wget, curl and Maven cannot The solution is to use " cntlm ". " cntlm " is a NTLM client for proxies requiring NTLM authentication. How it works Install "cntlm" Configure "cntlm"  by giving it your credentials by giving it the NTLM Proxy Start "cntlm" deamon (it listens to "127.0.0.1:3128") Configure wget, curl and Maven to use "cntlm" instead of using directly the NTLM Proxy Note: You will have then a kind of 2 stages Proxy : cntlm + the NTLM proxy Configure CNTLM After installing cntlm, the configuration file is in "cntlm.conf". You must have your domain (in the Windows meaning), proxy login and  proxy password. Mine are respectively: rktmb.org, mihamina, 1234abcd (yes, just for the example) You must have you NTLM Proxy Hostnama or IP ...

npm run build base-href

Using NPM to specify base-href When building an Angular application, people usually use "ng" and pass arguments to that invocation. Typically, when wanting to hard code "base-href" in "index.html", one will issue: ng build --base-href='https://ngx.rktmb.org/foo' I used to build my angular apps through Bamboo or Jenkins and they have a "npm" plugin. I got the habit to build the application with "npm run build" before deploying it. But the development team once asked me to set the "--base-href='https://ngx.rktmb.org/foo'" parameter. npm run build --base-href='https://ngx.rktmb.org/foo did not set the base href in indext.html After looking for a while, I found https://github.com/angular/angular-cli/issues/13560 where it says: You need to use −− to pass arguments to npm scripts. This did the job! The command to issue is then: npm run build -- --base-href='https://ngx.rktmb.org/foo...