windsurf.nvim

repository·main·Indexed 23 days ago

https://github.com/exafunction/windsurf.nvim

A 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.

Tokens
2.5K
Snippets
10
Records
12
Agent score
30%

What's inside windsurf.nvim

  1. Install windsurf.nvim using lazy.nvim

    main

    To 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
    },
  2. Configure Workspace Root detection

    main

    The plugin needs to identify the workspace root to provide context for autocomplete and chat. It uses the following priority:

    1. The workspace_root.find_root function (if provided).
    2. Neovim's built-in LSP support (if workspace_root.use_lsp is not false).
    3. Searching upward for files/directories listed in 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",
            }
        }
    })
  3. Install windsurf.nvim using packer.nvim

    main

    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
    }
  4. Show Windsurf status in statusline

    main

    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.

    Integration Examples

    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
  5. Integrate with nvim-cmp

    main

    After 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 = "", }
            })
        }
    })
  6. Configure and use Virtual Text completions

    main

    Virtual text allows showing completions directly in the buffer. Enable it by setting virtual_text.enabled = true in the setup function.

    Key Options

    • 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.

    Manual Triggering

    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-[>",
            }
        }
    })
  7. Configure windsurf.nvim options

    main

    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).
  8. Integrate with blink.cmp

    main

    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 },
          },
        },
      },
    }