This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
copilot.lua is a pure Lua Neovim plugin for GitHub Copilot integration, replacing github/copilot.vim. It communicates with the Copilot Language Server via Neovim's built-in LSP client to provide inline suggestions, a completion panel, and next-edit suggestions (NES).
Requirements: Neovim 0.11+, Node.js 22+ (for the default nodejs server mode).
make deps # Clone mini.nvim and osv into deps/
make test # Run all tests (auto-fetches deps)
make test_file FILE=tests/test_client.lua # Run a single test fileCode quality (checked in CI):
- Format: Stylua (config in
.stylua.toml) - Lint: Luacheck (config in
.luacheckrc, vim globals allowed) - Typecheck: Lua type annotations
plugin/copilot.lua registers the :Copilot user command. When require("copilot").setup(opts) is called:
- Validates Neovim version, sets up highlights, merges config
- On
:Copilotor lazy trigger →client.setup()starts the LSP server BufEnterautocmd attaches buffers based on filetype rules andshould_attachsuggestion.setup()andpanel.setup()wire up their keymaps and handlers
The LSP client is lazily initialized — it starts on first buffer attach or explicit command.
| Module | Role |
|---|---|
client/ |
LSP client lifecycle, buffer attach/detach, state tracking |
api/ |
Wraps all LSP requests/notifications (coroutine-based async) |
lsp/ |
Server startup — nodejs.lua (default) or binary.lua (experimental) |
config/ |
Modular config with per-feature defaults, deep merge, validation |
auth/ |
Device code sign-in flow, token caching from ~/.config/github-copilot/ |
suggestion/ |
Inline virtual text completions with accept/dismiss/cycle |
panel/ |
Split window showing multiple completions with navigation |
nes/ |
Next Edit Suggestion (experimental, requires copilot-lsp plugin) |
keymaps/ |
Buffer-local keymap registration with passthrough support |
model.lua |
Model listing, selection, get/set |
logger/ |
Dual file + console logging with configurable levels |
status/ |
LSP status notifications and callback system |
- Coroutine-based async: LSP requests are wrapped in coroutines via
api/init.lua - Passthrough keymaps: Keymaps fall through to original bindings if the action returns
false - Buffer-local state: Suggestion context and keymaps are per-buffer
- Config cascading: User opts deep-merged over module defaults with type validation
Tests use mini.test (from mini.nvim). Test stubs in tests/stubs/ mock the LSP server and Node.js to enable testing without a real Copilot server.
tests/child_helper.luamanages child Neovim processes for integration teststests/scripts/minimal_init.luais the minimal Neovim config used by the test harness- CI runs tests on Ubuntu (ARM), macOS, and Windows against both stable and nightly Neovim