picker.nvim is a lightweight, high-performance fuzzy finder for Neovim,
built around a simple and extensible design.
It provides a fast fzy-based matcher, flexible UI layouts,
and an easy-to-write source API that lets you create custom pickers with minimal code.
Whether you need file search, LSP symbols, diagnostics, or fully custom workflows,
picker.nvim offers a clean and composable approach without the overhead of larger frameworks.
- β¨ Features
- π¦ Installation
- π§ Configuration
- βοΈ Basic Usage
- π Builtin sources
- π Third party sources
- π§© Custom source
- πͺ Custom layout
- β FAQ
- π£ Self-Promotion
- π¬ Feedback
- π Credits
- π License
- β‘ High-performance fuzzy matching powered by the fzy algorithm
- π§ Simple yet extensible source API
- πͺ Flexible UI layouts (floating window, preview panel)
- π§© built-in picker sources
- π¦ Growing ecosystem of third-party extensions
- β¨οΈ Fully configurable actions & key mappings
- π Live preview and asynchronous loading support
picker.nvim works with all major Neovim plugin managers. Neovim 0.11+ is recommended for best compatibility.
- Using nvim-plug
require("plug").add({
{
"wsdjeg/picker.nvim",
},
})Using lazy.nvim
{
"wsdjeg/picker.nvim",
event = "VeryLazy",
config = function()
require("picker").setup()
end,
}Using packer.nvim
use({
"wsdjeg/picker.nvim",
config = function()
require("picker").setup()
end,
})Using luarocks
luarocks install picker.nvim
require("plug").add({
{
"wsdjeg/picker.nvim",
config = function()
require("picker").setup({
filter = {
ignorecase = false, -- ignorecase (boolean): defaults to false
},
window = {
width = 0.8, -- set picker screen width, default is 0.8 * vim.o.columns
height = 0.8,
col = 0.1,
row = 0.1,
current_icon = ">",
current_icon_hl = "CursorLine",
enable_preview = false,
preview_timeout = 500,
show_score = false, -- display/hide match score at the end of each item.
},
highlight = {
matched = "Tag",
score = "Comment",
},
prompt = {
position = "bottom", -- set prompt position, bottom or top
icon = ">",
icon_hl = "Error",
insert_timeout = 100,
title = true, -- display/hide source name
},
mappings = {
close = "<Esc>",
next_item = "<Tab>",
previous_item = "<S-Tab>",
open_item = "<Enter>",
toggle_preview = "<C-p>",
},
})
end,
},
})- fuzzy finder picker source.
run :Picker command without source name.
:Picker
- open picker source.
run :Picker command with a name of source.
:Picker <name>
- specific default input
with --input option, users also can specific default input text.
:Picker file --input=foo
or use <cword> for word under cursor.
:Picker help_tags --input=<cword>
In picker prompt window, the these mappings are defined by default.
| key binding | description |
|---|---|
Tab |
next item |
S-Tab |
previous item |
Enter |
default action |
Esc |
close picker |
| source | description |
|---|---|
| buffers | listed buffers |
| buftags | ctags outline for current buffer |
| cmd_history | results from :history : |
| colorscheme | all colorschemes |
| files | files in current dir |
| help_tags | neovim help tags source |
| highlights | highlight group source |
| jumps | jump list |
| lines | lines in current buffer |
| loclist | location list source |
| lsp_document_symbols | document symbols result from lsp client |
| lsp_references | lsp references |
| lsp_workspace_symbols | workspace symbols |
| marks | marks list |
| picker_config | picker config source |
| qflist | quickfix source |
| registers | registers context |
| emoji | emoji entries |
| key-mappings | key mappings |
The default commands for listing files is {'rg', '--files'}. this can be changed via:
require("picker.sources.files").set({ cmd = { "rg", "--files" } })| key binding | description |
|---|---|
<Enter> |
open select file |
<C-v> |
open select file in vertical split |
<C-t> |
open select file in new tabpage |
filter results from :history cmd.
| key binding | description |
|---|---|
<Enter> |
execute select command |
<C-d> |
delete select command history |
filter and setup picker.nvim without changing configuration file.
| items | description |
|---|---|
| prompt-top | change the prompt position to top |
| prompt-bottom | change the prompt position to bottom |
| show-score | display matched score |
| hide-score | hide matched score |
| ignrecase | change filter ignrecase to true |
| noignrecase | change filter ignrecase to false |
| key binding | description |
|---|---|
<Enter> |
set selected picker config |
filter results from :highlight
| key binding | description |
|---|---|
<Enter> |
yank selected highlight group name |
same as files source, but require job.nvim.
| key binding | description |
|---|---|
<Enter> |
open select file |
filter colorschemes.
| key binding | description |
|---|---|
<Enter> |
change to selected colorscheme |
filter ctags outline, require ctags command.
| key binding | description |
|---|---|
<Enter> |
jump to select tag |
file results from nvim_list_bufs()
| key binding | description |
|---|---|
<Enter> |
switch to select buffer |
| key binding | description |
|---|---|
<Enter> |
jump to selected line |
| key binding | description |
|---|---|
<Enter> |
jump selected help tag |
| key binding | description |
|---|---|
<Enter> |
jump selected quickfix list item |
| key binding | description |
|---|---|
<Enter> |
jump selected loclist item |
| key binding | description |
|---|---|
<Enter> |
paste selected context |
| key binding | description |
|---|---|
<Enter> |
jump selected position |
| key binding | description |
|---|---|
<Enter> |
jump selected position |
| key binding | description |
|---|---|
<Enter> |
jump selected symbol |
| key binding | description |
|---|---|
<Enter> |
jump selected symbol |
| key binding | description |
|---|---|
<Enter> |
jump selected reference |
filter emoji entries from muan/unicode-emoji-json.
This source will try to use job.nvim to download emoji json data, if job.nvim is not installed, vim.fn.system() will be used.
| key binding | description |
|---|---|
<Enter> |
insert selected emoji |
| key binding | description |
|---|---|
<Enter> |
trigger selected key mapping |
| source | description |
|---|---|
| mru | most recent used files, need mru.nvim |
| project | project history, need rooter.nvim |
| bookmarks | all bookmarks, need bookmarks.nvim |
| zettelkasten | zettelkasten notes source from zettelkasten.nvim |
| zettelkasten_tags | zettelkasten tags source from zettelkasten.nvim |
| git-branch | git branch source from git.nvim |
| music-player | music-player source form music-player.nvim |
| plug | plugins source for nvim-plug |
| async_files | async files source, require job.nvim |
a source main module should be picker.sources.<name>,
that means you can create a custom source in lua/picker/sources/ directory in your plugin.
--- @class PickerSource
--- @field get function
--- @field default_action function
--- @field __results nil | table<string>
--- @field preview_win boolean
--- @field preview function
--- @field set function
--- @field actions? tablepicker.nvim use default layout by default. a layout should provide following public functions:
local M = {}
---@class PickerLayout
---@field prompt_buf integer
---@field prompt_win integer
---@field list_buf integer
---@field list_win integer
---@field preview_buf integer
---@field preview_win integer
---@param source PickerSource
---@param config PickerConfig
---@return PickerLayout
function M.render_windows(source, config)
end
return M- how to disable nvim-cmp in picker.nvim buffer?
require("cmp").setup({
enabled = function()
if vim.bo.filetype == "picker-prompt" then
return false
end
return true
end,
})- how to use picker.nvim as
vim.ui.select?
vim.ui.select = function(items, opt, callback)
local source = {}
opt = opt or {}
if opt.prompt then
source.name = opt.prompt
else
source.name = "Select one of:"
end
source.get = function()
local entrys = {}
for idx, item in ipairs(items) do
local entry = {
value = item,
idx = idx, -- this also can be nil
}
if opt.format_item then
entry.str = opt.format_item(item)
else
entry.str = item
end
table.insert(entrys, entry)
end
return entrys
end
source.default_action = function(entry)
if callback then
callback(entry.value, entry.idx)
end
end
require("picker.windows").open(source, {
buf = vim.api.nvim_get_current_buf(),
})
endLike this plugin? Star the repository on GitHub.
Love this plugin? Follow me on GitHub.
If you encounter any bugs or have suggestions, please file an issue in the issue tracker
Licensed under GPL-3.0.
