CodeCompanion.nvim 源码贡献指南:从开发环境搭建到 Mini.Test 测试与调试实战
【免费下载链接】codecompanion.nvim✨ AI Coding, Vim Style项目地址: https://gitcode.com/GitHub_Trending/co/codecompanion.nvim
导读
CodeCompanion.nvim 是一个采用 "Omakase"(主厨精选)哲学开发的 Neovim AI 编程插件,本指南以仓库 CONTRIBUTING.md 为主线,完整讲解如何为其提交 PR、搭建本地开发环境(Docker/lazy.nvim 两种方式)、利用分层日志与 mitmproxy 代理调试请求、使用 Mini.Test 编写并运行测试,以及遵循 stylua 与 panvimdoc 完成代码格式化和文档构建。读完本文,你将掌握一套可复用的 Neovim 插件级开发工作流,能够独立向该项目贡献高质量功能或修复。
贡献前的三个原则
先讨论,再动手
贡献 PR 之前,请先通过 GitHub Discussions 发起讨论。项目维护者明确表示:欢迎改进插件的贡献,但拒绝"低价值、高臃肿"的功能——插件本体已接近 9,000 行 Lua 代码,任何新增功能都必须经过权衡。同时,项目采用语义化版本(Semantic Versioning),任何破坏现有 API 的 PR 都极不可能被合并,因此贡献前务必检查你的改动是否影响公开接口的兼容性。
Omakase:精选而非堆砌
项目将产品哲学概括为日料中的 "omakase"("交给你了")——食客让主厨精心挑选每一道菜。映射到 LLM 插件领域意味着:
- Intentional over exhaustive:每个新功能都要放到整个"菜单"(功能全景)中权衡,而非只看它自身;
- Complementary:新功能应当与既有功能相得益彰,而不是一个多余的小菜;
- Maintainable:每一行新增代码都是维护者承诺长期维护的债务。
从源码结构看,这一哲学直接体现在目录组织上:lua/codecompanion/下的adapters/(LLM 提供商适配)、interactions/(chat/inline/cmd 三大交互)、providers/(Snacks、Telescope 等集成)与utils/分工清晰,新功能应当落位到对应模块,而非另起炉灶。
AI 辅助贡献的"红线"
CodeCompanion 本身就是 AI 辅助开发的工具,但维护者明确拒绝"vibe-coded"式贡献——即用 LLM 生成代码但提交者自己并不理解的内容。需要警惕的红旗信号包括:无法解释实现决策、代码与既有架构模式不符、测试看似全面但没有真正覆盖边界情况、出现过度防御式编程与冗长注释等通用 LLM 模式。
相反,期待的贡献者画像应是:先理解代码库再动手(用 rules、读测试、探索架构)、为自己的每一行代码负责、写出能证明你理解该功能的测试、基于反馈持续迭代(PR 是对话而非一次性投递)。文档给出的经验法则值得记住:用 LLM 创建一个功能,或者一个测试,但永远不要同时用 LLM 生成两者。
标准贡献流程
按以下 6 步操作即可:
- 打开 discussion 提出想法,先确认该功能契合项目目标;
- Fork 仓库,从
main分支切出你的开发分支; - 在分支上实现功能或修复;
- 确保代码遵循项目的编码风格与约定;
- 保证代码有充分的测试覆盖与良好文档;
- 以清晰的标题和描述提交 Pull Request。
高效上手的两个捷径:Rules 与测试即文档
用内置 Rules 让 LLM 理解架构
在 CodeCompanion 仓库内工作时,你可以加载内置的 rules 文件,让 LLM 掌握插件某个方面的实现方式——这是确保新功能遵循既有实践、让 AI 真正理解架构与设计决策的最佳途径。加载方式有两种:
- 通过 Action Palette 选择加载 rules;
- 在聊天缓冲区中直接使用
/rules斜杠命令。
仓库中与 rules 相关的实现位于 lua/codecompanion/interactions/shared/rules/,对应的测试位于 tests/interactions/shared/rules/,可以对照阅读了解规则解析器的工作机制。
把测试当作第二份文档
项目拥有约 800 个精心编写的测试,它们既是覆盖率保障,也是"第二来源文档"。官方建议直接参照 tests/adapters/test_openai.lua 这类真实测试文件来学习测试写法,具体测试运行方式见下文"Testing"章节。
项目结构速览
理解仓库布局是贡献的第一步:
lua/codecompanion/:插件核心adapters/:不同 LLM 提供商的适配层(OpenAI、Anthropic、Gemini、Ollama 等);interactions/:三大交互形态——chat/(聊天缓冲区)、inline/(行内代码编辑)、cmd/(命令行编辑);providers/:与 Snacks.nvim、Telescope.nvim 等外部组件的集成;utils/:通用工具函数(含日志、异步、文件操作等)。
doc/:CodeCompanion 站点文档与 Neovim 帮助文档(doc/codecompanion.txt);queries/:面向多语言的 Tree-sitter 查询文件(cc_symbols.scm等);tests/:插件各类测试。
开发环境搭建
前置依赖
- Neovim 0.11.0+(测试与运行的最低版本);
- tree-sitter:测试所需(Tree-sitter 解析器);
- lua-language-server:LSP 支持与类型注解检查;
- stylua:Lua 代码格式化;
- pandoc:文档生成(配合 panvimdoc)。
方式一:使用项目内置 Dockerfile
仓库根目录提供 Dockerfile,可构建包含make工具链(含测试)的容器:
# 构建容器镜像 docker build -t codecompanion.nvim . # 拉取依赖并运行测试(挂载当前目录、以当前用户身份运行) docker run --rm -ti -u $(id -u):$(id -g) -v "$(pwd)":/cc -w /cc codecompanion.nvim:latest make deps test方式二:lazy.nvim 本地开发配置
以下以 lazy.nvim 为例(也可使用任意包管理器)。核心思路是让插件指向你的本地 Fork:
{ dir = "/full/path/to/local/codecompanion.nvim", dev = true, dependencies = { { "nvim-lua/plenary.nvim" }, -- 按需补充开发所需的可选依赖 }, opts = { opts = { log_level = "DEBUG", -- 开发期间开启详细日志 }, -- 其余配置 } }dev = true会让 lazy.nvim 直接使用本地目录而不去拉取远程版本,配合log_level = "DEBUG"即可进入开发态。
调试与日志
分层日志系统
CodeCompanion 采用分层日志系统(源码见 lua/codecompanion/utils/log.lua)。从实现看,日志器支持file、notify、echo三种 handler,按级别过滤输出,并采用非阻塞异步写入(async_writer批量落盘),避免影响 Neovim 性能。日志级别对应 Neovim 的vim.log.levels,共五档:ERROR、WARN、INFO、DEBUG、TRACE。
默认级别为ERROR(见 lua/codecompanion/config.lua),开发时可调高:
require("codecompanion").setup({ opts = { log_level = "DEBUG", -- Options: ERROR, WARN, INFO, DEBUG, TRACE } })日志文件位于 Neovim 的 log 目录(stdpath("log")),默认文件名codecompanion.log(M.get_logfile()即返回该路径)。运行:checkhealth codecompanion可查看日志目录位置。
gd调试聊天消息历史
开发聊天功能时,在聊天缓冲区按gd即可打开调试窗口,展示当前消息历史(你和 LLM 的消息)以及适配器设置。其实现位于 lua/codecompanion/interactions/chat/debug.lua,调试窗口支持保存与关闭等操作。
用代理抓取 LLM 请求/响应
当需要排查发给 LLM 提供商的请求与响应时,可启用proxy选项将请求转发到代理服务器。底层实现上,proxy与allow_insecure定义于 lua/codecompanion/config.lua 的adapters.http.opts下,并被 lua/codecompanion/http.lua 及多个适配器(Ollama、HuggingFace、Novita、OpenAI Compatible、Copilot 等)读取。
以 mitmproxy 为例的完整流程:
- 安装 mitmproxy,启动带 Web 界面的代理并监听 4141 端口:
mitmweb --set listen_port=4141; - 配置 CodeCompanion 指向该代理:
{ dir = "/full/path/to/local/codecompanion.nvim", -- 其余配置 ... opts = { adapters = { opts = { allow_insecure = true, proxy = "http://127.0.0.1:4141", }, } -- 其余配置 ... } }此后所有请求都会转发到代理。mitmproxy 的能力远不止查看流量——你可以用自定义脚本/hooks 模拟慢速连接、篡改请求等,参考其官方插件(addons)文档即可。
测试体系:Mini.Test 实战
运行测试
项目全部测试基于Mini.Test(miniprox 生态的测试框架)。在 Makefile 中,测试命令封装如下:
# 运行完整测试套件 make test # 运行指定测试文件 FILE=tests/adapters/test_openai.lua make test_file底层实现分别调用MiniTest.run()与MiniTest.run_file('$(FILE)'),并通过scripts/minimal_init.lua在 headless Neovim 中启动测试环境(见 scripts/minimal_init.lua)。该环境有两点值得注意:
- 会安装并编译
lua、make、markdown、markdown_inline、yaml等 Tree-sitter 解析器,保证渲染一致性; - 强制禁用网络:测试中任何真实 HTTP 请求都会直接报错(
plenary.curl的各方法被替换为抛错函数),确保测试确定性——需要响应的测试必须 mock 其调用层。
新增功能时,请在 tests/ 下对应的测试文件中补充用例。
Windows 原生运行测试
[!Note] 以下为原生 Windows 指南,不适用于 WSL、MSYS2、Cygwin 等 POSIX 模拟环境。
需要满足的前置条件:
git在%PATH%中;- 某种
make在%PATH%中; - C/C++ 编译器在路径中(用于引导 Tree-sitter);
- 定义
%HOME%环境变量指向%HOMEDRIVE%%HOMEPATH%或%USERPROFILE%; - 在 CodeCompanion 根目录创建
deps目录(若不存在)。
make与编译器可来自 Visual Studio Community 2022 的x64 Native Tools Command Prompt(提供 NMake 与 Visual C++ 编译器)。在 cmd.exe 中:
REM 设置环境 IF NOT EXIST deps MD deps SET "HOME=%HOMEDRIVE%%HOMEPATH%" SET "PATH=%PATH%;C:\Program Files\Git\bin" "C:\Program Files (x86)\Microsoft Visual Studio\2022\VC\Auxiliary\Build\vcvars64.bat" REM 运行全部测试 nmake test REM 运行单个测试套件 nmake FILE=tests/interactions/chat/tools/runtime/tests_cmd.lua test_file另外,仓库提供 Make.ps1 PowerShell 脚本,可执行与make相同的命令(format/docs/test/test_file),单独运行Make.ps1则一次执行all。注意传给test_file的参数中斜杠必须使用/,反斜杠会导致 MiniTest 工作异常。
测试技巧:让 LLM 帮你写测试
面对约 800 个测试的代码库,学习成本不低。官方建议把testrules 加载进聊天缓冲区,让 LLM 先了解 Mini.Test 的写法,同时把 tests/adapters/test_openai.lua 这样的真实测试文件分享给 LLM 作为范例。
从 tests/helpers.lua 可以看到测试基建的用心:setup_plugin会 mock Copilot 适配器的外部 HTTP 调用,mock_http/queue_mock_http_response/get_mock_http_requests提供了一套完整的请求-响应 mock 管线,create_mock_adapter可在子 Neovim 实例中构建测试适配器——这些工具都值得在编写新测试时复用。
代码风格与规范
- 使用stylua格式化 Lua 代码,配置见 stylua.toml(
column_width = 120、2 空格缩进、Unix 换行、双引号优先等); - 提交 PR 前运行
make format(实际执行stylua tests/ lua/ -f ./stylua.toml); - 鼓励类型注解:参见 lua/codecompanion/types.lua 与 LuaCATS 注解规范,这能让 lua-language-server 提供更好的 LSP 支持。
构建文档
文档使用panvimdoc从 Markdown 源生成。运行:
make docs从 Makefile 的实现看,该命令以 pandoc 驱动、加载 panvimdoc 的 Lua filters(include-files.lua、skip-blocks.lua及仓库自带的 scripts/panvimdoc-cleanup.lua),把 scripts/vimdoc.md 转换为doc/codecompanion.txt(Neovim 帮助文件),同时生成带目录(toc:true)与 Tree-sitter 高亮的文档。此外,doc/目录下的 Markdown 源也是站点文档(含 doc/usage、doc/configuration、doc/extending 等子模块)的输入,修改功能时务必同步更新对应文档。
贡献检查清单
提交 PR 前请逐项确认:
- 已在 discussion 中与维护者对齐方向,符合 Omakase 哲学;
- 未破坏现有 API(语义化版本约束);
- 功能与测试分别清晰可控("功能与测试二选一由 LLM 生成"的经验法则);
- 代码通过
make format,遵循 stylua.toml 规范并带类型注解; - 在 tests/ 对应文件补充测试,并确认
make test全绿; - 同步更新 doc/ 文档并验证
make docs可正常生成。
遵循这套流程,你就能以维护者认可的方式为 CodeCompanion.nvim 贡献代码,同时借助其 Rules 与测试体系,让 AI 辅助开发真正服务于插件质量的提升。
【免费下载链接】codecompanion.nvim✨ AI Coding, Vim Style项目地址: https://gitcode.com/GitHub_Trending/co/codecompanion.nvim
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考