Code Companion: AI
{ lib, pkgs, ... }: {
Q: Why mkAfter
here?
A: As codecompanion will change the nvim-cmp config,
therefore we need to make codecompanion is setup after nvim-cmp.
Use mkAfter
, make config of codecompanion is placed after all
other normal configs in ~/.config/nvim/init.lua
.
programs.neovim.plugins = lib.mkAfter [{
plugin = pkgs.vimUtils.buildVimPlugin {
pname = "codecompanion.nvim";
# currently lastest
version = "2025-1-27";
src = pkgs.fetchFromGitHub {
owner = "olimorris";
repo = "codecompanion.nvim";
rev = "f8b9dce0468708c3b280abb045927c6864a17869";
hash = "sha256-1EMzh3TaQxj+eMLjizHwntl/6ZqTHRlxFF6IOSROnuA=";
};
# vertical split current window (including multiple buffers), instead of vsplit current buffer
postPatch = ''
substituteInPlace lua/codecompanion/strategies/chat/ui.lua \
--replace-fail "vsplit" "vertical topleft new"
''
# fix the chat window
+ ''
sed -i '/ui.set_win_options/i vim.cmd("set winfixwidth")' lua/codecompanion/strategies/chat/ui.lua
''
Use telescope as selection provider. Though it can be configured like, each slash_commands needs to be configured, which is very cumbersome!
strategies = {
chat = {
slash_commands = {
["file"] = {
callback = "strategies.chat.slash_commands.file",
description = "Select a file using Telescope",
opts = {
provider = "telescope",
contains_code = true,
},
},
["buffer"] = {...}
},
},
},
So I decided to replace all the provider in source code like below:
+ ''
sed -i 's/provider = .*telescope.*/provider = "telescope",/' lua/codecompanion/config.lua
'';
meta.homepage = "https://github.com/olimorris/codecompanion.nvim/";
};
type = "lua";
# https://codecompanion.olimorris.dev/configuration/adapters.html
config = ''
require("codecompanion").setup({
adapters = {
deepseek = function()
return require("codecompanion.adapters").extend("deepseek", {
env = {
api_key = "cmd:cat ~/Gist/Vault/deepseek_api_key_nvim.txt",
},
schema = {
model = {
default = "deepseek-chat",
},
},
})
end,
},
display = {
chat = {
window = {
width = 40,
},
diff = {
enabled = true,
},
},
},
strategies = {
chat = {
adapter = "deepseek",
slash_commands = {
["file"] = {
callback = "strategies.chat.slash_commands.file",
description = "Select a file using Telescope",
opts = {
provider = "telescope",
contains_code = true,
},
},
},
},
inline = {
adapter = "deepseek",
},
},
})
-- key bindings of AI
vim.keymap.set('n', '<leader>a', ':CodeCompanionChat Toggle<CR>')
vim.keymap.set('v', '<leader>a', ':CodeCompanionChat Add<CR>')
'';
}];
}