1
0
Files
dotfiles/nvim/.config/nvim/lua/plugins/ai/init.lua

134 lines
4.1 KiB
Lua

vim.pack.add({
{ src = "https://github.com/olimorris/codecompanion.nvim" },
{ src = "https://github.com/nvim-lua/plenary.nvim" },
{
src = "https://github.com/saghen/blink.cmp",
version = vim.version.range("^1"),
},
})
local codecompanion = require("codecompanion")
local has_gemini = os.getenv("GEMINI_API_KEY")
codecompanion.setup({
interactions = {
chat = {
adapter = has_gemini and "gemini" or "kiro",
tools = {
["web_search"] = {
opts = { require_approval_before = false },
},
["fetch_webpage"] = {
opts = { require_approval_before = false },
},
},
},
inline = { adapter = has_gemini and "gemini" or nil },
},
adapters = {
http = {
gemini = function()
return require("codecompanion.adapters").extend("gemini", {
env = {
api_key = os.getenv("GEMINI_API_KEY") or "cmd:cat ~/.gemini_api_key",
},
schema = {
model = {
default = "gemini-3.1-pro-preview",
},
},
})
end,
},
acp = {
kiro = function()
return require("codecompanion.adapters").extend("kiro", {
defaults = {
model = "kiro_default",
},
})
end,
},
},
})
-- Optional: Keymaps for CodeCompanion
vim.keymap.set({ "n", "v" }, "<leader>a", "<cmd>CodeCompanionChat Toggle<cr>", { noremap = true, silent = true })
-- Inline prompt for buffer modifications (Generates diffs)
vim.keymap.set({ "n", "v" }, "<leader>ci", "<cmd>CodeCompanion <cr>", { noremap = true, silent = true })
-- Add visual selection to chat
vim.keymap.set("v", "<leader>ca", "<cmd>CodeCompanionChat Add<cr>", { noremap = true, silent = true })
-- Action palette (Use this to Accept/Reject inline diffs)
vim.keymap.set({ "n", "v" }, "<leader>cp", "<cmd>CodeCompanionActions<cr>", { noremap = true, silent = true })
vim.cmd([[cab cc CodeCompanion]])
vim.cmd("packadd blink.cmp")
local blink = require("blink.cmp")
blink.setup({
keymap = { preset = "default" },
appearance = { nerd_font_variant = "mono" },
completion = {
menu = { border = "rounded" },
documentation = { auto_show = true, window = { border = "rounded" } },
ghost_text = { enabled = true }, -- Enables ghost text in insert mode
},
cmdline = {
keymap = { ["<Tab>"] = { "show", "accept" } },
completion = { menu = { auto_show = true }, ghost_text = { enabled = true } },
},
-- By removing `snippets = { preset = 'luasnip' }`, Blink natively
-- defaults to Neovim 0.11+ built-in `vim.snippet` API.
sources = {
-- Added codecompanion, removed emoji
default = { "lsp", "path", "snippets", "buffer", "codecompanion" },
providers = {
cmdline = {
min_keyword_length = function(ctx)
if ctx.mode == "cmdline" and string.find(ctx.line, " ") == nil then
return 3
end
return 0
end,
},
-- Wire up CodeCompanion to Blink
codecompanion = {
name = "CodeCompanion",
module = "codecompanion.providers.completion.blink",
enabled = true,
score_offset = 100, -- Boosts priority so AI suggestions appear first in ghost text
async = true, -- Ensures AI fetching doesn't block the UI
},
},
},
fuzzy = { implementation = "prefer_rust_with_warning" },
})
-- Ensure borders stay colored even after toggling light/dark themes
vim.api.nvim_create_autocmd("ColorScheme", {
pattern = "*",
callback = function()
vim.api.nvim_set_hl(0, "BlinkCmpMenuBorder", { link = "Special" })
vim.api.nvim_set_hl(0, "BlinkCmpDocBorder", { link = "Special" })
vim.api.nvim_set_hl(0, "FloatBorder", { link = "Special" })
end,
})
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = blink.get_lsp_capabilities(capabilities)
-- Safely merge with existing global LSP capabilities so we don't overwrite settings from ink/lsp.lua
local existing_config = vim.lsp.config["*"]
if type(existing_config) == "table" and type(existing_config.capabilities) == "table" then
capabilities = vim.tbl_deep_extend("force", existing_config.capabilities, capabilities)
end
-- Apply to all natively loaded 0.12 LSP servers
vim.lsp.config("*", {
capabilities = capabilities,
-- Note: We DO NOT use vim.lsp.completion.enable() here because
-- Blink is taking over the UI rendering.
})