导语

AI 辅助编程工具遍地开花 🌸,但说实话,能真正完美融入 Neovim 工作流的,屈指可数。

这就好比给一辆手动挡的 911 装自动驾驶,装不好就是“车毁人亡” 💥。

很多兄弟可能首选 avante.nvim,它确实是当下的“网红”插件,功能极其强大。但如果你是多环境切换的重度用户,它可能会成为你的噩梦 👻:

avante

还得自己去插件目录手动 build?对于崇尚“开箱即用”或者不爱啃生肉文档的新手来说,这简直是劝退劝退劝退 🛑。

更要命的是,Avante 是个“急性子”。它的机制非常勤劳,会在后台疯狂消耗你的 Token。假如你是 Windows 用户 + 不稳定第三方 API 中转 这种“炼狱级”配置的选手,等着你的就是满屏的 400 错误,和一堆乱码。

这还不是最惨的。一旦触发 Rate limit reached,它还会像个不知疲倦的复读机一样在后台无限重试。如果不手动 Kill 进程,你的余额就会像流水一样逝去——简直是给本不富裕的生活雪上加霜 💸。

当然,如果你是此时此刻手里握着官方 API 的“富哥们” 💎,Avante 的省瓦力的确无可挑剔。但如果你想要更高的可控性、更丝滑的自定义体验,以及更符合 Vimer 直觉的操作逻辑,CodeCompanion 才是你的终极归宿 🏠。

具体怎么选?

  • 🥊 Avante:侵略性强,不管你愿不愿意,它都给你安排得明明白白。
  • 🤝 CodeCompanion:听话、懂事,高度配合你的 LSP 和工作流,打造真正的私人定制。

基础配置:从 0 到 1 的优雅集成 🛠️

1. 安装插件:起步 🏁

首先,把这位“伴侣”请进门。这里以 lazy.nvim 为例,配置极其清爽:

return {
  "olimorris/codecompanion.nvim",
  opts = {}
}

💡 注意: 接下来的所有配置项,我们都会写在 opts 这个表里。为了版面整洁,后面我就不重复写外层的 return 结构了。

2. 快捷键映射 (Keymaps):人剑合一 ⚔️

为了让 AI 像你的手指延伸一样自然,我们需要配置几组符合直觉的快捷键。这一步决定了你后续的使用爽感。

--- lua/config/keymaps.lua
--- CodeCompanion
-- 切换 AI 对话窗口 (类似于打开侧边栏)
keymap("n", "<leader>aa", "<cmd>CodeCompanionChat Toggle<cr>", opts)
-- 针对选中文本输入 AI 指令 (Visual 模式下的核心键)
keymap("v", "<leader>aa", ":CodeCompanion ", { noremap = true, silent = false })
-- 打开 AI 操作面板 (选择预设好的各种 Action)
keymap("n", "<leader>ac", "<cmd>CodeCompanionActions<cr>", opts)

3. 配置模型 API (Adapters):注入灵魂 👻

这是全篇最关键的一步,请集中注意力。

CodeCompanion 之所以强大,是因为它是一个**“模型混元体”** 🧛。它允许你在这个环节用 DeepSeek 进行深度推理,在那个环节用 GPT-4o 进行精准补全。

建议把你所有的 Adapter 配置都集中管理,打造一个强大的军火库:

--- 所有模型配置都写在 adapters 中
adapters = {
  http = {
    --- DeepSeek 配置
    deepseek = function()
      return require("codecompanion.adapters").extend("deepseek", {
        env = {
          -- 推荐使用 cmd 命令读取环境变量,避免 API Key 硬编码在代码里
          api_key = "cmd:echo $DEEPSEEK_KEY",
        },
        schema = {
          model = {
            -- 🔴 关键点:Inline 模式下绝对不要用 deepseek-reasoner (R1)
            -- 因为 Reasoner 模型的输出格式会导致 Inline 替换失败
            default = "deepseek-chat",
          },
          temperature = {
            default = 0.0,
          },
        },
      })
    end,

    --- 第三方 API 配置 (比如我自己在用的云雾)
    --- 注册地址:https://yunwu.zeabur.app/register?aff=EQXn
    yunwu = function()
      return require("codecompanion.adapters").extend("openai_compatible", {
        env = {
          -- 1. Base URL (通常是域名,注意不带 /v1/chat/completions)
          url = "https://yunwu.ai",

          -- 2. API Key
          api_key = "cmd:echo $YUNWU_KEY",

          -- 3. Chat Endpoint (官方文档强调这种分离写法)
          chat_url = "/v1/chat/completions",
        },
        schema = {
          model = {
            default = "gemini-3-pro-preview-thinking", -- 填入你实际使用的模型名称
          },
          -- 可选:针对某些第三方模型可能需要调整参数
          temperature = {
            default = 0.0,
          },
        },
      })
    end,
  },
},

🚩 高能避坑指南:虽然 DeepSeek 的 deepseek-reasoner (R1) 模型强得离谱,但在 Inline 模式(行内修改) 下,请务必将其锁死在 deepseek-chat。

  • 🚫 为什么? 因为 R1 输出的思维链(Chain of Thought)会干扰插件的代码替换逻辑,导致你的代码里出现一堆 AI 的碎碎念。别问我是怎么知道的,全是血泪教训。

接下来,我们要给这位“伴侣”立规矩。告诉它:什么时候该干什么事。

CodeCompanion 贴心地把场景分为了三大战区 🛡️:

  • chat (对话):日常闲聊、问答。
  • inline (行内):外科手术级的代码修改。
  • agent (特工):拥有自主行动力的智能体。
-- 写到 opts={} 中
strategies = {
  -- 将所有策略指向你自定义的适配器
  chat = {
    adapter = "yunwu",
  },
  inline = {
    adapter = "yunwu",
    -- 如果你想用 DeepSeek 做行内修改,可以解开下面这行:
    -- adapter = "deepseek"
  },
  agent = {
    adapter = "yunwu",
  },
},

同样你也可以自定义配置 MCP (Model Context Protocol)。这个协议能让 AI 读取本地文件系统,非常强。

-- 写到 opts={} 中
strategies = {
  agent = {
    tools = {
      ["mcp"] = {
        opts = {
          servers = {
            -- 配置文件系统服务,让 AI 可以“看到”你的项目文件
            ["filesystem"] = {
              cmd = "npx",
              args = { "-y", "@modelcontextprotocol/server-filesystem", vim.fn.getcwd() },
            },
          },
        },
      },
    },
  },
},

重启 Neovim。如果一切顺利,恭喜你,你的编辑器已经觉醒了。虽然它还不会说话,但它已经准备好为你效劳。

如果出现报错“令牌无效”,大概率是环境变量没配好,回去检查一下 echo $DEEPSEEK_KEY 是否有输出。


使用教程:掌握核心心法 🧘

刚上手时,你可能会觉得它的逻辑和 Cursor 或者 Avante 不太一样,甚至有点“怪”。

别急,一旦你理解它设计的**“三种模式”**,你会发现:这才是 Vimer 真正想要的高效逻辑!它不抢夺控制权,而是作为你意志的延伸。

1. Chat 模式:第二大脑 🧠

这是最基础的模式。按下 <leader>aa,右侧会弹出一个熟悉的对话窗口。你可以把它当成内置在 Neovim 里的 ChatGPT。

逻辑和 Avante 一样:输入问题,Ctrl+s 提交。

cc

这时候它就是一个标准的聊天机器人。如果你发现回复里的 Markdown 格式只是原始字符(比如粗体显示为 **bold**),你需要安装 render-markdown.nvim 来渲染它。配置如下:

return {
  "MeanderingProgrammer/render-markdown.nvim",
}

但是! 这里有个大坑。装了这个插件后,它可能会过于热情地渲染你正在写的普通 Markdown 文件,连图片链接都给你折叠起来了,像这样:

如果你也喜欢用 Nvim 写 Markdown,可以设置只针对 CodeCompanion 的 Markdown 文件开启 render-markdown.nvim,配置如下:

return {
  "MeanderingProgrammer/render-markdown.nvim",
  opts = {
    filetypes = { "codecompanion" },
  },
  ft = { "codecompanion" },
}

但这样设置后,图片链接会直接消失:

解决方法:在 /lua/config/option.lua 中设置 vim.opt.conceallevel = 0,这样你的原始 Markdown 文本就能正常显示了。

2. Inline 模式:代码行内大修(爽点所在) ⚡️

这是我最喜欢的功能,没有之一。 如果说 Chat 模式是咨询师,那 Inline 模式就是更衣室里的裁缝。

它允许 AI 直接在你的代码里进行修改,完全不需要打开侧边栏,也不需要复制粘贴。

逻辑非常 Vimer,讲究一个**“指哪打哪”**:选中文本 -> 告诉 AI 怎么改 -> AI 改给你看 -> 你决定要不要。

操作流程:

  1. 进入 Visual 模式选中一段代码。
  2. 按下 <leader>aa(注意这是我们之前配置的 v 模式映射)。
  3. 底部会出现命令行 :'<,'>CodeCompanion。

  1. 输入指令,比如 fix,回车。

AI 会直接生成 diff,当你确认无误后,使用快捷键 gda 应用更改。

即时演示:

此外,你还可以在输入框里使用内置的 Slash Command(斜杠命令):

  • /commit: 生成git提交信息(后面介绍)
  • /explain: 解释代码
  • /fix: 修复 bug报错
  • /lsp: 基于 LSP 报错修复
  • /test: 生成测试用例

不过要注意,这些斜杠命令大部分会打开 Chat 窗口,而不会直接在行内修改,只有直接输入 Prompt 才会触发 Diff 修改。

3. Agent 模式:赋予 AI 真正的“手”和“眼” 👁️✋

如果只是聊天和改代码,那还不够“智能”。充其量只是个高级补全工具。

Agent 模式,才是 CodeCompanion 真正封神的杀手锏。

在 CodeCompanion 里,激活 Agent 不需要像 Cursor 那样点什么特殊的“Agent 模式”开关,你只需要在对话框里使用两个特殊符号,就能解锁无限可能:

  • # (Context) —— 它的“眼睛”:手动指定 AI 应该读取哪些信息。
    • #buffer: 读取当前文件(最常用,哪怕文件有几千行)。
    • #files: 跨文件感知。模糊搜索并引用项目中的其他文件,Context 瞬间拉满。
    • #lsp: 精准医疗。读取当前光标附近的 LSP 报错与诊断信息,修复 Bug 一针见血。
  • @ (Tools) —— 它的“双手”:允许 AI 调用工具执行具体操作。
    • @insert_edit_into_file: 核心能力。允许 AI 直接“拿笔”改你的代码,而不是在聊天框里废话。
    • @cmd_runner: 比如让它运行 npm run test,然后根据报错自己修复代码。
    • @files: 读取或操作项目中的物理文件。
    • @web_search: 遇到不懂的库?让它自己联网去查文档!

举个例子:如果你想让AI帮你把注释改成中文,就需要@insert_edit_into_file 工具的支持。

然后也是 gda 应用更改。

这才是真正的 AI Coding —— 直接修改文件系统,而不仅仅是给你吐一堆 Markdown 让你自己复制。


进阶玩法 🚀

1. 战术性切换模型:拒绝“一根筋” 🔀

虽然我们在 Config 里设置了默认策略,但战场形势瞬息万变。有时候你需要 DeepSeek R1 的深度思考,有时候你只需要普通模型的极速秒回。

不需要反复改配置文件,直接在命令行指定你想要的那个“打手”:

:CodeCompanionChat adapter=deepseek  " 呼叫 DeepSeek 🧠
:CodeCompanionChat adapter=yunwu     " 呼叫云雾 ☁️

💡 小贴士:命令后面也可以直接加上 Slash Command (如 /fix, /explain),这样就会直接用指定的适配器开始工作了。

⚡️ 高阶操作:建议给这两个命令单独绑定快捷键,比如 <leader>ad (DeepSeek) 和 <leader>ay (Yunwu)。这样遇到难题时,一键召唤最强大脑,实现指尖上的战术切换。

2. 自动生成 Git Commit 信息 📝

直接使用斜杠命令 /commit 就会自动打开 chat 窗口,根据你当前已经 git add 的内容自动生成 Commit Message。

commit diff

3. 独家秘籍:自定义 Prompt 生成中文 Commit 🇨🇳

很多时候,AI 生成的英文 Commit 虽然规范,但看着就是不亲切。

我们可以自定义一个 prompt_library 动作,让 AI 严格按照 Conventional Commits 规范,帮我们写出漂亮的中文提交信息。

在 opts 中添加 prompt_library:

-- 写到 opts={} 中
prompt_library = {
  ["Git Commit (CN)"] = {
    strategy = "chat",
    description = "生成中文 Git 提交信息",
    opts = {
      index = 5,
      is_slash_cmd = true, -- 这样你就可以在输入框里用 /commit_cn 调用了
      short_name = "commit_cn",
      auto_submit = true,
    },
    prompts = {
      {
        role = "user",
        content = function()
          return "请根据以下暂存代码的变动(git diff --staged),生成一个 Git 提交信息。\n\n"
            .. "要求:\n"
            .. "1. 使用中文。\n"
            .. "2. 遵循 Conventional Commits 规范 (feat, fix, docs, style, refactor, perf, test, chore)。\n"
            .. "3. 格式为:`<type>(<scope>): <subject>`。\n"
            .. "4. 只要信息本身,不要废话。\n\n"
            .. "Diff 内容:\n"
            .. vim.fn.system("git diff --staged")
        end,
      },
    },
  },
}

配置好后,按 <leader>ac 呼出面板,或者直接在 Chat 里输入 /commit_cn 即可。

假如你想添加其他的action,你也可以安装上面的配置自定义。

4. 重要集成:BlinkCMP 🔌

为了让你在 Chat 输入框里输入 # 和 @ 时能丝滑地弹出自动补全,一定要集成 blink.cmp。

-- blinkcmp.lua 配置
-- 写在 sources.per_filetype 中
sources = {
  per_filetype = {
    codecompanion = { "codecompanion" }, -- 这一点非常重要!
  },
},

效果如下,没有这个补全,Agent 的体验会大打折扣:

5. 界面美化:Loading 动画 🎨

假如你动手跟着我做了上面的步骤,你会发现哪哪不得劲,需要长时间才回复的答案感觉没反应。那你对了,因为默认没有加载动画!

好在大佬比较多,已经有现成插件了。

直接在 codecompanion.lua 中配置:

dependencies = {
  "lalitmee/codecompanion-spinners.nvim",
},

-- 写到 opts={} 中
extensions = {
  spinner = {
    -- style = "cursor-relative", -- 这种是跟随光标的
    style = "lualine",            -- 我个人更喜欢集成在状态栏里
    ["cursor-relative"] = {
      text = "",
      hl_positions = { { 0, 3 }, { 3, 6 }, { 6, 9 } },
      interval = 100,
      hl_group = "Title",
      hl_dim_group = "NonText",
    },
  },
},

然后配置你的 lualine 组件:

-- lualine.lua
require("codecompanion._extensions.spinner.styles.lualine").get_lualine_component(),

这样当你等待 AI 回复时,状态栏就会有悦动的加载提示,看着都心情好:

插件提供了多种加载样式,默认的 cursor-relative 其实也不错,但我个人觉得集成在 Statusline 里更优雅,不遮挡视线。


结语:不仅是工具,更是思维的延伸 🌠

写到这里,相信你已经打造出了一套完全属于你的 AI 编程环境。

与那些“一价全包”的商业 AI 编辑器不同,CodeCompanion 秉承了 Neovim 的核心哲学:极度自由,极度可控 🎮。 你知道每一个请求发向了哪里,你知道每一行代码是如何被改变的。

在这套配置下,AI 不再是一个强势的驾驶员,而是一个坐在副驾、随时待命、懂你心思的顶级领航员。

这,或许才是人机协作编程该有的样子。

如果这篇配置指南帮你也打造了心仪的 AI 助手,不妨点个赞和在看 👍,让更多 Vimer 看到代码世界的另一种可能。


codcompanion.nvim配置教程 | 新青年talks