Authenticate with Windsurf
main:Codeium Auth command, which will prompt you to copy a token from your browser and paste it into the Neovim API token request prompt.:Codeium Authrepository·main·Indexed 23 days ago
https://github.com/exafunction/windsurf.nvimA native Neovim plugin for Windsurf that provides AI-powered code completions and chat capabilities. It integrates with nvim-cmp and blink.cmp, offers virtual text completions, and includes configurable workspace root detection. Key commands include :Codeium Auth for authentication, :Codeium Chat for the chat interface, and :Codeium Toggle to enable or disable completions.
:Codeium Auth command, which will prompt you to copy a token from your browser and paste it into the Neovim API token request prompt.:Codeium AuthTo install windsurf.nvim with lazy.nvim, add the following block to your configuration. It requires plenary.nvim and nvim-cmp as dependencies, and uses require("codeium").setup({}) for configuration.
{
"Exafunction/windsurf.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
"hrsh7th/nvim-cmp",
},
config = function()
require("codeium").setup({
})
end
},The plugin needs to identify the workspace root to provide context for autocomplete and chat. It uses the following priority:
workspace_root.find_root function (if provided).workspace_root.use_lsp is not false).workspace_root.paths (e.g., .git, package.json).If you are using coc.nvim, you can provide a custom find_root function.
require('codeium').setup({
workspace_root = {
use_lsp = true,
find_root = function()
return vim.fn.CocAction("currentWorkspacePath")
end,
paths = {
".bzr",
".git",
".hg",
".svn",
"_FOSSIL_",
"package.json",
}
}
})To install windsurf.nvim with packer.nvim, add the following block to your configuration. Note that it requires plenary.nvim and nvim-cmp as dependencies, and uses require("codeium").setup({}) for configuration.
use {
"Exafunction/windsurf.nvim",
requires = {
"nvim-lua/plenary.nvim",
"hrsh7th/nvim-cmp",
},
config = function()
require("codeium").setup({
})
end
}You can display the current Windsurf completion status in your statusline. The function require('codeium.virtual_text').status_string() returns a 3-character string:
'3/8': Third suggestion out of 8.'0': No suggestions returned.'*': Waiting for response.Vimscript (standard statusline):
set statusline+=%3{v:lua.require('codeium.virtual_text').status_string()}Lualine:
Use set_statusbar_refresh to tell the plugin when to trigger a statusline refresh.
require('codeium.virtual_text').set_statusbar_refresh(function()
require('lualine').refresh()
end)Custom Status Logic:
You can use require('codeium.virtual_text').status() to get a detailed object containing the state (e.g., 'idle', 'waiting', 'completions'), current, and total fields for more complex UI implementations.
-- Example of a custom status function
function custom_status()
local status = require('codeium.virtual_text').status()
if status.state == 'idle' then
return ' '
end
if status.state == 'waiting' then
return "Waiting..."
end
if status.state == 'completions' and status.total > 0 then
return string.format('%d/%d', status.current, status.total)
end
return ' 0 '
end:Codeium Toggle command.:Codeium ToggleAfter calling setup, the plugin registers a source named codeium in nvim-cmp. Ensure nvim-cmp is set up before windsurf.nvim to avoid the source appearing as unused.
To use a custom symbol for Windsurf with lspkind, use the Codeium keyword in your symbol_map.
-- Add to nvim-cmp sources
cmp.setup({
-- ...
sources = {
-- ...
{ name = "codeium" }
}
})
-- Custom symbol with lspkind
cmp.setup({
-- ...
formatting = {
format = require('lspkind').cmp_format({
mode = "symbol",
maxwidth = 50,
ellipsis_char = '...',
symbol_map = { Codeium = "", }
})
}
}):Codeium Chat command. This will open the chat interface in your default browser using xdg-open.:Codeium ChatVirtual text allows showing completions directly in the buffer. Enable it by setting virtual_text.enabled = true in the setup function.
manual: If true, completions are only triggered via manual Lua function calls.filetypes: A mapping of filetypes to boolean values to enable/disable virtual text.default_filetype_enabled: Whether to enable virtual text for filetypes not explicitly listed in filetypes.idle_delay: Time in ms to wait after typing stops before requesting completions (default 75).key_bindings: Configuration for accept, accept_word, accept_line, clear, next, and prev.If manual = true, use these functions:
require('codeium.virtual_text').complete(): Request completions immediately.require('codeium.virtual_text').cycle_or_complete(): Request a completion or cycle to the next.require('codeium.virtual_text').debounced_complete(): Complete after idle_delay has passed.require("codeium").setup({
enable_cmp_source = false,
virtual_text = {
enabled = true,
manual = false,
filetypes = {
python = true,
markdown = false
},
default_filetype_enabled = true,
idle_delay = 75,
virtual_text_priority = 65535,
map_keys = true,
accept_fallback = "\t",
key_bindings = {
accept = "<Tab>",
accept_word = false,
accept_line = false,
clear = false,
next = "<M-]>",
prev = "<M-[>",
}
}
})The setup function accepts a configuration object to customize plugin behavior. Key configuration areas include:
config_path: Path to the config file for storing the API key.bin_path: Directory where the Windsurf server is downloaded.api: Configuration for the API server (e.g., host, port, path, portal_url). Required for enterprise mode.enterprise_mode: Boolean to enable enterprise mode.detect_proxy: Boolean to enable/disable proxy detection.enable_chat: Boolean to enable chat functionality.enable_cmp_source: Boolean (defaults to true) to enable/disable the nvim-cmp source.virtual_text: Configuration for the virtual text completion feature (see Virtual Text guide).workspace_root: Configuration for finding the project root (see Workspace Root guide).tools: Paths to required binaries like uname, uuidgen, curl, gzip, and language_server.wrapper: Path to a wrapper script/binary (useful for NixOS).Logs are written to ~/.cache/nvim/codeium/codeium.log.
You can control the logging verbosity by setting the DEBUG_CODEIUM environment variable to one of: trace, debug, info, warn, or error.
To use Windsurf with blink.cmp, add it as a dependency and configure the provider using the codeium.blink module.
{
'saghen/blink.cmp',
dependencies = {
{
'Exafunction/codeium.nvim',
},
},
opts = {
sources = {
default = { 'lsp', 'path', 'snippets', 'buffer', 'codeium' },
providers = {
codeium = { name = 'Codeium', module = 'codeium.blink', async = true },
},
},
},
}