How do I create interactive selection menus and text input prompts in Neovim Lua scripts?
Answer
vim.ui.select() and vim.ui.input()
Explanation
Neovim provides vim.ui.select() and vim.ui.input() as standardized UI hooks for user interaction. They work out of the box as simple prompts but are overridable by plugins — tools like dressing.nvim or telescope.nvim can replace them with richer UIs, making your Lua config automatically benefit from any UI plugin the user installs.
How it works
vim.ui.select(items, opts, callback) — pick one item from a list:
vim.ui.select(
{ 'tabs', 'spaces', 'mixed' },
{ prompt = 'Choose indent style:' },
function(choice)
if choice then
print('You chose: ' .. choice)
end
end
)
vim.ui.input(opts, callback) — prompt for free-form text:
vim.ui.input(
{ prompt = 'New variable name: ', default = 'myVar' },
function(input)
if input then
vim.cmd('s/\\<oldName\\>/' .. input .. '/g')
end
end
)
Tips
- Always check if the callback argument is non-nil before using it — it is
nilwhen the user cancels - These functions are the standard API for interactive prompts in Neovim plugins; prefer them over raw
vim.fn.input()so users can override them with a fancier UI - Install
dressing.nvimorsnacks.nvimto get telescope-style or floating-window UIs automatically for any code using these functions vim.ui.selectis what Neovim uses internally forvim.lsp.buf.code_action()— overriding it improves the built-in LSP experience