在Neovim的插件生态中,AI辅助编程插件为开发者带来了极大便利。本文将重点介绍CodeCompanion.nvim插件,涵盖其基础使用、多种高级配置技巧,包括设置中文交互、修复思考过程显示、自定义快捷键等内容,帮助读者更好地运用该插件提升编程效率。

一、选择CodeCompanion.nvim的缘由

如今在Neovim里,AI插件层出不穷,其中avante.nvim和CodeCompanion.nvim备受关注。经过一番体验,我最终选择了CodeCompanion.nvim。avante.nvim虽然功能强大,但它相对复杂,依赖的组件众多,而且侵略性较强。就拿快捷键来说,仅在readme文件里列出的Key Bindings就多得让人头疼,还强制使用Leader键。这对于习惯了自己特定快捷键设置的我来说,要是产生冲突,修改起来十分麻烦,一时半会儿都不知道该改成什么,心理压力很大。另外,它的界面也不太符合我的审美,好多默认元素无法删除,在小屏幕上显示时,看着特别难受。

反观CodeCompanion.nvim就简洁许多,它几乎没有全局快捷键,也没有多余的界面元素。安装完成后,仅仅会多出4条命令,要是有使用快捷键的需求,自己去设置就行,上手毫无压力。虽说在功能方面,它可能比avante.nvim稍逊一筹,但整体使用体验对我来说更友好。之前我制作过一个视频,详细介绍了如何使用和配置这个插件,还实现了集成DeepSeek和Copilot双AI的功能。接下来,我会着重分享一些该插件的高级配置技巧。

二、设置中文交互

默认情况下,使用CodeCompanion.nvim时,不管是用中文还是英文提问,得到的回答都是英文。要是想实现中文问答,就需要对插件进行设置。在配置文件里,通过设置opts项中的language来达成目的,具体代码如下:

require("codecompanion").setup({ adapters = { ..... }, strategies = { ..... }, opts = { language = "Chinese", }, }) 

这段代码的意思是,在调用require("codecompanion").setup函数进行插件配置时,在opts选项里将language设置为Chinese,这样就能让插件以中文形式回答问题啦。

三、修复思考过程显示

在之前的视频中,我们集成了openai_compatible适配器,但是使用这个适配器时,不会显示模型思考的过程。像DeepSeek模型,有时候它反应慢,其实是在思考,只是没有展示出来,让人误以为它运行缓慢。想要显示思考过程的话,就得继承deepseek适配器。比如,自定义两个适配器siliconflow_r1aliyun_deepseek,代码如下:

siliconflow_r1 = function() return require("codecompanion.adapters").extend("deepseek", { name = "siliconflow_r1", url = "https://api.siliconflow.cn/v1/chat/completions", env = { api_key = function() return os.getenv("DEEPSEEK_API_KEY_S") end, }, schema = { model = { default = "deepseek-ai/DeepSeek-R1", choices = { ["deepseek-ai/DeepSeek-R1"] = { opts = { can_reason = true } }, "deepseek-ai/DeepSeek-V3", }, }, }, }) end, aliyun_deepseek = function() return require("codecompanion.adapters").extend("deepseek", { name = "aliyun_deepseek", url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions", env = { api_key = function() return os.getenv("DEEPSEEK_API_ALIYUN") end, }, schema = { model = { default = "deepseek-r1", choices = { ["deepseek-r1"] = { opts = { can_reason = true } }, }, }, }, }) end, 

上面代码中,siliconflow_r1aliyun_deepseek这两个函数,都是基于deepseek适配器进行扩展。每个适配器都设置了名称、请求的URL、获取API密钥的方式以及模型相关的配置等信息。通过这样的自定义适配器,就能实现显示模型思考过程的功能。

四、聊天窗口的Markdown渲染

默认状态下,聊天窗口不会对Markdown进行渲染。如果想要实现Markdown渲染效果,就需要手动安装render - markdown.nvim插件,并指定ftcodecompanion。在配置文件里添加如下代码:

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

这段代码的作用是,在插件配置中引入render - markdown.nvim插件,同时指定它对markdowncodecompanion类型的文件进行渲染,这样在聊天窗口中就能正确展示Markdown格式的内容了。

五、自定义快捷键

自定义快捷键的操作很简单,只需要将快捷键映射到对应的命令或者方法就行。比如,有:CodeCompanionChat命令,对应的方法是require("codecompanion").chat() 。我自己定义了下面这两个快捷键(这里的keymap是我自定义的函数):

keymap({ "n", "v", "x" }, "<leader>cc", function() require("codecompanion").toggle() end) keymap({ "n", "v", "x" }, "<leader>cp", ":CodeCompanionActions<CR>") 

在上述代码里,第一个keymap<leader>cc快捷键映射到require("codecompanion").toggle()方法,当在普通模式(n)、可视模式(v)和选择模式(x)下按下<leader>cc时,就会执行toggle操作;第二个keymap<leader>cp映射到:CodeCompanionActions<CR>命令,在这几种模式下按下<leader>cp,就会触发CodeCompanionActions命令。

六、自定义Prompts

我们可以参考系统自带的Prompts来进行修改。举个例子,我把“Explain”这个提示全部改成了中文,并且指定使用阿里云的deepseek来进行代码解释,具体配置如下(这段代码要放到setup函数中):

 prompt_library = { ["DeepSeek Explain In Chinese"] = { strategy = "chat", description = "中文解释代码", opts = { index = 5, is_default = true, is_slash_cmd = false, modes = { "v" }, short_name = "explain in chinese", auto_submit = true, user_prompt = false, stop_context_insertion = true, adapter = { name = "aliyun_deepseek", model = "deepseek-r1", }, }, prompts = { { role = "system", content = [[当被要求解释代码时,请遵循以下步骤: 1. 识别编程语言。 2. 描述代码的目的,并引用该编程语言的核心概念。 3. 解释每个函数或重要的代码块,包括参数和返回值。 4. 突出说明使用的任何特定函数或方法及其作用。 5. 如果适用,提供该代码如何融入更大应用程序的上下文。]], opts = { visible = false, }, }, { role = "user", content = function(context) local input = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line) return string.format( [[请解释 buffer %d 中的这段代码: ```%s %s ``` ]], context.bufnr, context.filetype, input ) end, opts = { contains_code = true, }, }, }, }, } 

需要注意的是,上面代码块中string.format里的\反斜杠要去掉,因为在网页中,如果不加反斜杠,内容可能会被当成Markdown结束,这是渲染时的问题。在这个自定义的prompt_library里,定义了一个名为“DeepSeek Explain In Chinese”的提示,它使用chat策略,指定了使用aliyun_deepseek适配器和deepseek - r1模型,还详细设置了系统和用户的提示内容,从而实现用中文解释代码的功能。

七、用fidget实现状态提醒

fidget是在LSP加载时,常出现在右下角的状态提醒工具。因为CodeCompanion在请求开始和结束时都有对应的事件,所以我们可以借助fidget来实现状态提醒。我参考了相关讨论,实现了一个简化版,代码如下:

local fidget = pRequire("fidget") local handler if fidget then -- Attach: vim.api.nvim_create_autocmd({ "User" }, { pattern = "CodeCompanionRequest*", group = vim.api.nvim_create_augroup("CodeCompanionHooks", {}), callback = function(request) if request.match == "CodeCompanionRequestStarted" then if handler then handler.message = "Abort." handler:cancel() handler = nil end handler = fidget.progress.handle.create({ title = "", message = "Thinking...", lsp_client = { name = "CodeCompanion" }, }) elseif request.match == "CodeCompanionRequestFinished" then if handler then handler.message = "Done." handler:finish() handler = nil end end end, }) end 

这段代码首先尝试获取fidget模块,如果获取成功,就创建一个自动命令。当CodeCompanionRequestStarted事件触发时,取消之前可能存在的提示,并创建一个新的提示,显示“Thinking…”;当CodeCompanionRequestFinished事件触发时,将提示内容改为“Done.”并结束提示。通过这样的设置,就能在使用CodeCompanion时,通过fidget直观地了解请求的状态。

八、使用技巧分享

在使用聊天框的过程中,如果遇到大语言模型回复卡住的情况,有几个快捷键可以帮助我们处理。按下q键可以取消当前回复,按下gx键能够清空聊天记录,按下ga键则可以快速切换其他模型,方便又实用。

以上就是我目前对CodeCompanion.nvim插件的所有配置和使用心得分享,希望能对大家有所帮助。