Skip to main content

Overview

Avante.nvim supports multiple input providers for user input dialogs (like API key entry). You can choose between the native vim input, enhanced UI libraries, or create your own custom provider.

Available Providers

Native (Default)

Uses vim’s built-in vim.ui.input for input dialogs.
require('avante').setup({
  input = {
    provider = "native",
    provider_opts = {},
  },
})
Pros:
  • No additional dependencies
  • Simple and lightweight
  • Always available
Cons:
  • Basic UI
  • Limited customization

Dressing.nvim

stevearc/dressing.nvim provides enhanced input UI with better styling and features.
1

Install dressing.nvim

-- With lazy.nvim
{
  "stevearc/dressing.nvim",
  opts = {}, -- See dressing.nvim docs for options
}
2

Configure Avante

require('avante').setup({
  input = {
    provider = "dressing",
    provider_opts = {},
  },
})
Pros:
  • Better visual styling
  • More customization options
  • Works with other plugins using vim.ui
Configuration Example:
-- Configure dressing.nvim
require('dressing').setup({
  input = {
    enabled = true,
    default_prompt = "Input:",
    prompt_align = "left",
    insert_only = true,
    start_in_insert = true,
    border = "rounded",
    relative = "cursor",
    prefer_width = 40,
    width = nil,
    max_width = { 140, 0.9 },
    min_width = { 20, 0.2 },
    win_options = {
      winblend = 10,
      wrap = false,
    },
  },
})

-- Use with Avante
require('avante').setup({
  input = {
    provider = "dressing",
  },
})

folke/snacks.nvim provides a modern, feature-rich input UI.
1

Install snacks.nvim

-- With lazy.nvim
{
  "folke/snacks.nvim",
  opts = {
    input = { enabled = true },
  },
}
2

Configure Avante

require('avante').setup({
  input = {
    provider = "snacks",
    provider_opts = {
      title = "Avante Input",
      icon = " ",
      placeholder = "Enter your input...",
    },
  },
})
Pros:
  • Modern, polished UI
  • Rich customization
  • Consistent with other snacks.nvim features
  • Great visual feedback
Full Configuration Example:
require('avante').setup({
  input = {
    provider = "snacks",
    provider_opts = {
      -- Snacks.input options
      title = "Avante Input",
      icon = " ",
      placeholder = "Enter your API key...",
      width = 60,
      border = "rounded",
      title_pos = "center",
      -- Styling
      backdrop = true,
      backdrop_blur = true,
      -- Behavior
      insert = true,
      relative = "editor",
      position = "50%",
    },
  },
})

Custom Input Provider

Create a completely custom input provider by providing a function:
require('avante').setup({
  input = {
    ---@param input avante.ui.Input
    provider = function(input)
      local title = input.title ---@type string
      local default = input.default ---@type string
      local conceal = input.conceal ---@type boolean
      local on_submit = input.on_submit ---@type fun(result: string|nil): nil

      -- Your custom input logic here
      -- Create your own UI, buffer, window, etc.
      
      -- Call on_submit when done
      on_submit(user_input)
    end,
  },
})

Custom Provider Example

local function custom_input_provider(input)
  local buf = vim.api.nvim_create_buf(false, true)
  local width = 50
  local height = 1
  
  local win = vim.api.nvim_open_win(buf, true, {
    relative = "editor",
    width = width,
    height = height,
    col = (vim.o.columns - width) / 2,
    row = (vim.o.lines - height) / 2,
    style = "minimal",
    border = "rounded",
    title = input.title,
    title_pos = "center",
  })
  
  -- Set default text
  if input.default then
    vim.api.nvim_buf_set_lines(buf, 0, -1, false, { input.default })
  end
  
  -- Handle submission
  vim.keymap.set("n", "<CR>", function()
    local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
    local result = lines[1] or ""
    vim.api.nvim_win_close(win, true)
    input.on_submit(result)
  end, { buffer = buf })
  
  -- Handle cancellation
  vim.keymap.set("n", "<Esc>", function()
    vim.api.nvim_win_close(win, true)
    input.on_submit(nil)
  end, { buffer = buf })
  
  -- Start in insert mode
  vim.cmd("startinsert")
end

require('avante').setup({
  input = {
    provider = custom_input_provider,
  },
})

Input Provider Parameters

When creating a custom provider, you receive an input object with:
title
string
The title/prompt for the input dialogExample: "Enter API Key"
default
string
Default value to pre-fill in the inputExample: "sk-..."
conceal
boolean
Whether to conceal the input (for passwords/API keys)When true, display asterisks instead of actual characters
on_submit
function
Callback function to call with the resultSignature: fun(result: string|nil): nil
  • Pass the user’s input as a string
  • Pass nil if cancelled

Provider Comparison

FeatureNativeDressingSnacksCustom
DependenciesNonedressing.nvimsnacks.nvimNone
Visual QualityBasicGoodExcellentDepends
CustomizationLimitedGoodExcellentFull
ComplexitySimpleMediumMediumHigh
RecommendedBasic useGeneralBest UXSpecific needs

When to Use Each Provider

Use when:
  • You want minimal dependencies
  • You prefer simplicity over aesthetics
  • You’re running Neovim in limited environments
Example: Remote servers, minimal configs
Use when:
  • You already use dressing.nvim
  • You want consistent vim.ui behavior
  • You need good customization without complexity
Example: Standard Neovim setups with dressing already installed
Use when:
  • You have very specific requirements
  • You want complete control over behavior
  • You’re integrating with other custom UI
Example: Unique workflows, special validation needs

Example Use Cases

API Key Entry with Snacks

input = {
  provider = "snacks",
  provider_opts = {
    title = "API Key Required",
    icon = " ",
    placeholder = "sk-...",
    backdrop = true,
  },
}

Simple Input with Dressing

input = {
  provider = "dressing",
  provider_opts = {},
}

Custom Input with Validation

input = {
  provider = function(input)
    -- Custom UI with validation
    local function validate(value)
      if #value < 10 then
        vim.notify("API key too short", vim.log.levels.ERROR)
        return false
      end
      return true
    end
    
    -- Show input, validate, then submit
    vim.ui.input({
      prompt = input.title,
      default = input.default,
    }, function(result)
      if result and validate(result) then
        input.on_submit(result)
      else
        input.on_submit(nil)
      end
    end)
  end,
}

Troubleshooting

  1. Verify the provider is installed (dressing/snacks)
  2. Check provider configuration is correct
  3. Look for errors in :messages
  4. Try switching to "native" to test
  1. Ensure you’re calling on_submit with a result
  2. Verify the function signature matches expectations
  3. Check for errors in your custom logic
  4. Test with a simple implementation first
  1. Check provider_opts are correct for your provider
  2. Verify colorscheme compatibility
  3. Review provider’s documentation for options
  4. Try default options first, then customize

Best Practices

Start Simple

Begin with native or dressing, then move to snacks or custom if needed.

Consistent Experience

Use the same provider across your config for consistency.

Handle Cancellation

Always handle the case where users cancel input (nil result).

Visual Feedback

Use appropriate icons and titles to help users understand what’s being requested.

Configuration

General Avante configuration

Providers

Configure AI providers and API keys

Build docs developers (and LLMs) love