Skip to content

Neovim

Codive integrates with Neovim through the Language Server Protocol (LSP). This guide covers setup with popular plugin managers.

  • Neovim 0.8+ (0.10+ recommended for inline completions)
  • nvim-lspconfig
  • Codive CLI installed
-- ~/.config/nvim/lua/plugins/codive.lua
return {
{
"neovim/nvim-lspconfig",
opts = {
servers = {
codive = {
cmd = { "codive", "lsp" },
filetypes = { "rust", "typescript", "javascript", "python", "go", "lua" },
root_dir = function(fname)
return require("lspconfig.util").root_pattern(
".git",
"Cargo.toml",
"package.json",
"pyproject.toml",
"go.mod"
)(fname)
end,
},
},
},
},
}
-- ~/.config/nvim/lua/plugins.lua
use {
"neovim/nvim-lspconfig",
config = function()
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
-- Define Codive as a custom server
if not configs.codive then
configs.codive = {
default_config = {
cmd = { "codive", "lsp" },
filetypes = { "rust", "typescript", "javascript", "python", "go", "lua" },
root_dir = lspconfig.util.root_pattern(".git", "Cargo.toml", "package.json"),
settings = {},
},
}
end
lspconfig.codive.setup({
on_attach = function(client, bufnr)
-- Your on_attach function
end,
})
end,
}
-- ~/.config/nvim/lua/config/codive.lua
local M = {}
function M.setup()
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
-- Register Codive server
if not configs.codive then
configs.codive = {
default_config = {
cmd = { "codive", "lsp" },
filetypes = {
"rust", "typescript", "javascript", "typescriptreact",
"javascriptreact", "python", "go", "lua", "c", "cpp",
},
root_dir = lspconfig.util.root_pattern(
".git", "Cargo.toml", "package.json",
"pyproject.toml", "go.mod", "Makefile"
),
settings = {
codive = {
-- Provider settings
provider = "anthropic",
model = "claude-sonnet-4-20250514",
-- Feature toggles
inlineCompletion = true,
codeLens = true,
diagnostics = true,
-- Context settings
context = {
maxFiles = 50,
ignorePatterns = {
"node_modules/**",
"target/**",
".git/**",
},
},
},
},
},
}
end
-- Setup with capabilities
local capabilities = vim.lsp.protocol.make_client_capabilities()
-- Add completion capabilities if using nvim-cmp
local has_cmp, cmp_lsp = pcall(require, "cmp_nvim_lsp")
if has_cmp then
capabilities = cmp_lsp.default_capabilities(capabilities)
end
lspconfig.codive.setup({
capabilities = capabilities,
on_attach = M.on_attach,
})
end
function M.on_attach(client, bufnr)
local opts = { buffer = bufnr, silent = true }
-- Codive-specific keymaps
vim.keymap.set("n", "<leader>ce", function()
vim.lsp.buf.execute_command({
command = "codive.explain",
arguments = { vim.api.nvim_buf_get_name(bufnr) },
})
end, vim.tbl_extend("force", opts, { desc = "Codive: Explain" }))
vim.keymap.set("v", "<leader>ce", function()
local start_line = vim.fn.getpos("'<")[2]
local end_line = vim.fn.getpos("'>")[2]
vim.lsp.buf.execute_command({
command = "codive.explain",
arguments = {
vim.api.nvim_buf_get_name(bufnr),
{ start_line = start_line, end_line = end_line },
},
})
end, vim.tbl_extend("force", opts, { desc = "Codive: Explain Selection" }))
vim.keymap.set("n", "<leader>cr", function()
vim.lsp.buf.execute_command({
command = "codive.refactor",
arguments = { vim.api.nvim_buf_get_name(bufnr) },
})
end, vim.tbl_extend("force", opts, { desc = "Codive: Refactor" }))
vim.keymap.set("n", "<leader>ct", function()
vim.lsp.buf.execute_command({
command = "codive.test",
arguments = { vim.api.nvim_buf_get_name(bufnr) },
})
end, vim.tbl_extend("force", opts, { desc = "Codive: Generate Tests" }))
vim.keymap.set("n", "<leader>cd", function()
vim.lsp.buf.execute_command({
command = "codive.document",
arguments = { vim.api.nvim_buf_get_name(bufnr) },
})
end, vim.tbl_extend("force", opts, { desc = "Codive: Add Documentation" }))
end
return M

Use it in your init.lua:

require("config.codive").setup()

Recommended keybindings:

-- ~/.config/nvim/lua/config/keymaps.lua
-- Codive keymaps (assuming <leader> is space)
local codive_maps = {
{ "n", "<leader>cc", "<cmd>Codive chat<cr>", "Open Chat" },
{ "n", "<leader>ce", "<cmd>Codive explain<cr>", "Explain" },
{ "v", "<leader>ce", "<cmd>Codive explain<cr>", "Explain Selection" },
{ "n", "<leader>cr", "<cmd>Codive refactor<cr>", "Refactor" },
{ "v", "<leader>cr", "<cmd>Codive refactor<cr>", "Refactor Selection" },
{ "n", "<leader>ct", "<cmd>Codive test<cr>", "Generate Tests" },
{ "n", "<leader>cd", "<cmd>Codive document<cr>", "Add Documentation" },
{ "n", "<leader>cf", "<cmd>Codive fix<cr>", "Fix Issue" },
}
for _, map in ipairs(codive_maps) do
vim.keymap.set(map[1], map[2], map[3], { desc = "Codive: " .. map[4] })
end

For inline completions (ghost text), Neovim 0.10+ is recommended. Configure with:

-- Enable inline completions
vim.g.codive_inline_completions = true
-- Accept completion with Tab
vim.keymap.set("i", "<Tab>", function()
if vim.fn.pumvisible() == 1 then
return "<C-n>"
elseif vim.b.codive_suggestion then
return vim.fn["codive#accept_suggestion"]()
else
return "<Tab>"
end
end, { expr = true })
-- Dismiss with Escape
vim.keymap.set("i", "<Esc>", function()
if vim.b.codive_suggestion then
vim.fn["codive#dismiss_suggestion"]()
end
return "<Esc>"
end, { expr = true })

Use Codive suggestions alongside nvim-cmp:

-- ~/.config/nvim/lua/plugins/cmp.lua
return {
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
},
config = function()
local cmp = require("cmp")
cmp.setup({
sources = cmp.config.sources({
{ name = "nvim_lsp" }, -- Includes Codive
{ name = "buffer" },
}),
-- ... rest of config
})
end,
}

Add Codive commands to which-key:

-- ~/.config/nvim/lua/plugins/which-key.lua
return {
"folke/which-key.nvim",
config = function()
local wk = require("which-key")
wk.register({
["<leader>c"] = {
name = "+Codive",
c = { "<cmd>Codive chat<cr>", "Chat" },
e = { "<cmd>Codive explain<cr>", "Explain" },
r = { "<cmd>Codive refactor<cr>", "Refactor" },
t = { "<cmd>Codive test<cr>", "Tests" },
d = { "<cmd>Codive document<cr>", "Document" },
f = { "<cmd>Codive fix<cr>", "Fix" },
},
})
end,
}

Search Codive chat history with Telescope:

-- Custom Telescope picker for Codive
local function codive_history()
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local conf = require("telescope.config").values
pickers.new({}, {
prompt_title = "Codive History",
finder = finders.new_table({
results = vim.fn["codive#get_history"](),
entry_maker = function(entry)
return {
value = entry,
display = entry.prompt,
ordinal = entry.prompt,
}
end,
}),
sorter = conf.generic_sorter({}),
}):find()
end
vim.keymap.set("n", "<leader>ch", codive_history, { desc = "Codive: History" })

Check if Codive is in PATH:

:!which codive

Verify LSP is attached:

:LspInfo
  1. Ensure LSP is attached: :LspInfo
  2. Check Codive logs: :lua vim.cmd('e ' .. vim.lsp.get_log_path())
  3. Verify API key is set

Try these optimizations:

settings = {
codive = {
-- Use faster model
model = "claude-3-haiku-20240307",
-- Reduce context
context = {
maxFiles = 20,
},
-- Increase trigger delay
inlineCompletion = {
triggerDelay = 1000,
},
},
}