16 KiB
fzf ❤️ lua
Installation • Usage • Commands • Customization • Wiki
fzf changed my life, it can change yours too, if you allow it.
Rationale
What more can be said about fzf? It is the single most impactful tool for my command line workflow, once I started using fzf I couldn’t see myself living without it.
To understand fzf properly I highly recommended fzf screencast by @samoshkin
This is my take on the original fzf.vim, written in lua for neovim 0.5, it builds on the elegant nvim-fzf as an async interface to create a performant and lightweight fzf client for neovim that rivals any of the new shiny fuzzy finders for neovim.
Why use this plug-in?
... and not, to name a few, telescope or vim-clap?
As @junegunn himself put it, “because you can
and you love fzf
”.
If you’re happy with your current setup there is absolutely no reason to switch.
That said, without taking anything away from the greatness of other plugins I
found it more efficient having a uniform experience between my shell and my
nvim. In addition fzf
has been a rock for me since I started using it and
hadn’t failed me once, it never hangs and can handle almost anything you throw
at it. That, and colorful file icons and git indicators!.
Dependencies
Linux
orMacOS
only, see nvim-fzf's How it works sectionfzf
orskim
binary installed- nvim-fzf
- nvim-web-devicons (optional)
Optional dependencies (recommended)
- fd - better performance
find
utility - bat - for colorful syntax highlighted previews
- ripgrep - for better grep-like searches
Installation
Using vim-plug
Plug 'ibhagwan/fzf-lua'
Plug 'vijaymarupudi/nvim-fzf'
Plug 'kyazdani42/nvim-web-devicons'
Using packer.nvim
use { 'ibhagwan/fzf-lua',
requires = {
'vijaymarupudi/nvim-fzf',
'kyazdani42/nvim-web-devicons' } -- optional for icons
}
Note: if you already have fzf installed you do not need to install
fzf
orfzf.vim
, however if you do not have it installed, you only need fzf which can be installed with (fzf.vim is not a requirement nor conflict):Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
or with packer.nvim:
use = { 'junegunn/fzf', run = './install --bin', }
Usage
Fzf-lua aims to be as plug and play as possible with sane defaults, you can run any fzf-lua command like this:
:lua require('fzf-lua').files()
-- or using the `FzfLua` vim command:
:FzfLua files
or with arguments:
:lua require('fzf-lua').files({ cwd = '~/.config' })
-- or using the `FzfLua` vim command:
:FzfLua files cwd=~/.config
which can be easily mapped to:
nnoremap <c-P> <cmd>lua require('fzf-lua').files()<CR>
Commands
Buffers & Files
Command | List |
---|---|
buffers |
open buffers |
files |
find or fd on a path |
oldfiles |
opened files history |
quickfix |
quickfix list |
loclist |
location list |
Search
Command | List |
---|---|
grep |
search for a pattern with grep or rg |
grep_last |
run search again with the last pattern |
grep_cword |
search word under cursor |
grep_cWORD |
search WORD under cursor |
grep_visual |
search visual selection |
grep_curbuf |
live grep current buffer |
live_grep |
live grep current project |
Git
Command | List |
---|---|
git_files |
git ls-files |
git_status |
git status |
git_commits |
git commit log (project) |
git_bcommits |
git commit log (buffer) |
git_branch |
git branches |
LSP
Command | List |
---|---|
lsp_references |
References |
lsp_definitions |
Definitions |
lsp_declarations |
Declarations |
lsp_typedefs |
Type Definitions |
lsp_implementations |
Implementations |
lsp_document_symbols |
Document Symbols |
lsp_workspace_symbols |
Workspace Symbols |
lsp_code_actions |
Code Actions |
lsp_document_diagnostics |
Document Diagnostics |
lsp_workspace_diagnostics |
Workspace Diagnostics |
Misc
Command | List |
---|---|
builtin |
fzf-lua builtin methods |
help_tags |
help tags |
man_pages |
man pages |
colorschemes |
color schemes |
commands |
neovim commands |
command_history |
command history |
search_history |
search history |
marks |
:marks |
registers |
:registers |
keymaps |
key mappings |
spell_suggest |
spelling suggestions |
tags |
project tags |
btags |
buffer tags |
Customization
I tried to make it as customizable as possible, if you find you need to change something that isn’t below, open an issue and I’ll do my best to add it.
customization can be achieved by calling the setup()
function or individually sending parameters to a builtin command, for exmaple:
:lua require('fzf-lua').files({ fzf_layout = 'reverse-list' })
Consult the list below for available settings:
local actions = require "fzf-lua.actions"
require'fzf-lua'.setup {
winopts = {
-- split = "new", -- open in a split instead?
win_height = 0.85, -- window height
win_width = 0.80, -- window width
win_row = 0.30, -- window row position (0=top, 1=bottom)
win_col = 0.50, -- window col position (0=left, 1=right)
-- win_border = false, -- window border? or borderchars?
win_border = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' },
window_on_create = function() -- nvim window options override
vim.cmd("set winhl=Normal:Normal") -- popup bg match normal windows
end,
},
-- fzf_bin = 'sk', -- use skim instead of fzf?
fzf_layout = 'reverse', -- fzf '--layout='
fzf_args = '', -- adv: fzf extra args, empty unless adv
fzf_binds = { -- fzf '--bind=' options
'f2:toggle-preview',
'f3:toggle-preview-wrap',
'shift-down:preview-page-down',
'shift-up:preview-page-up',
'ctrl-d:half-page-down',
'ctrl-u:half-page-up',
'ctrl-f:page-down',
'ctrl-b:page-up',
'ctrl-a:toggle-all',
'ctrl-l:clear-query',
},
preview_border = 'border', -- border|noborder
preview_wrap = 'nowrap', -- wrap|nowrap
preview_opts = 'nohidden', -- hidden|nohidden
preview_vertical = 'down:45%', -- up|down:size
preview_horizontal = 'right:60%', -- right|left:size
preview_layout = 'flex', -- horizontal|vertical|flex
flip_columns = 120, -- #cols to switch to horizontal on flex
-- default_previewer = "bat", -- override the default previewer?
-- by default auto-detect bat|cat
previewers = {
cmd = {
-- custom previewer, will execute:
-- `<cmd> <args> <filename>`
cmd = "echo",
args = "",
},
cat = {
cmd = "cat",
args = "--number",
},
bat = {
cmd = "bat",
args = "--style=numbers,changes --color always",
theme = 'Coldark-Dark', -- bat preview theme (bat --list-themes)
config = nil, -- nil uses $BAT_CONFIG_PATH
},
head = {
cmd = "head",
args = nil,
},
git_diff = {
cmd = "git diff",
args = "--color",
},
},
-- provider setup
files = {
-- previewer = "cat", -- uncomment to override previewer
prompt = 'Files❯ ',
cmd = '', -- "find . -type f -printf '%P\n'",
git_icons = true, -- show git icons?
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
actions = {
["default"] = actions.file_edit,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["ctrl-q"] = actions.file_sel_to_qf,
["ctrl-y"] = function(selected) print(selected[2]) end,
}
},
git = {
files = {
prompt = 'GitFiles❯ ',
cmd = 'git ls-files --exclude-standard',
git_icons = true, -- show git icons?
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
},
status = {
prompt = 'GitStatus❯ ',
cmd = "git status -s",
previewer = "git_diff",
file_icons = true,
git_icons = true,
color_icons = true,
},
commits = {
prompt = 'Commits❯ ',
cmd = "git log --pretty=oneline --abbrev-commit --color",
preview = "git show --pretty='%Cred%H%n%Cblue%an%n%Cgreen%s' --color {1}",
actions = {
["default"] = nil,
},
},
bcommits = {
prompt = 'BCommits❯ ',
cmd = "git log --pretty=oneline --abbrev-commit --color --",
preview = "git show --pretty='%Cred%H%n%Cblue%an%n%Cgreen%s' --color {1}",
actions = {
["default"] = nil,
},
},
branches = {
prompt = 'Branches❯ ',
cmd = "git branch --all --color",
preview = "git log --graph --pretty=oneline --abbrev-commit --color {1}",
actions = {
["default"] = actions.git_switch,
},
},
icons = {
["M"] = { icon = "M", color = "yellow" },
["D"] = { icon = "D", color = "red" },
["A"] = { icon = "A", color = "green" },
["?"] = { icon = "?", color = "magenta" },
-- ["M"] = { icon = "★", color = "red" },
-- ["D"] = { icon = "✗", color = "red" },
-- ["A"] = { icon = "+", color = "green" },
},
},
grep = {
prompt = 'Rg❯ ',
input_prompt = 'Grep For❯ ',
-- cmd = "rg --vimgrep",
rg_opts = "--hidden --column --line-number --no-heading " ..
"--color=always --smart-case -g '!{.git,node_modules}/*'",
git_icons = true, -- show git icons?
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
actions = {
["default"] = actions.file_edit,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["ctrl-q"] = actions.file_sel_to_qf,
["ctrl-y"] = function(selected) print(selected[2]) end,
}
},
oldfiles = {
prompt = 'History❯ ',
cwd_only = false,
},
buffers = {
prompt = 'Buffers❯ ',
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
sort_lastused = true, -- sort buffers() by last used
actions = {
["default"] = actions.buf_edit,
["ctrl-s"] = actions.buf_split,
["ctrl-v"] = actions.buf_vsplit,
["ctrl-t"] = actions.buf_tabedit,
["ctrl-x"] = actions.buf_del,
}
},
colorschemes = {
prompt = 'Colorschemes❯ ',
live_preview = true, -- apply the colorscheme on preview?
actions = {
["default"] = actions.colorscheme,
["ctrl-y"] = function(selected) print(selected[2]) end,
},
winopts = {
win_height = 0.55,
win_width = 0.30,
window_on_create = function()
vim.cmd("set winhl=Normal:Normal")
end,
},
post_reset_cb = function()
-- reset statusline highlights after
-- a live_preview of the colorscheme
-- require('feline').reset_highlights()
end,
},
quickfix = {
-- cwd = vim.loop.cwd(),
file_icons = true,
git_icons = true,
},
lsp = {
prompt = '❯ ',
-- cwd = vim.loop.cwd(),
cwd_only = false, -- LSP/diagnostics for cwd only?
async_or_timeout = true, -- timeout(ms) or false for blocking calls
file_icons = true,
git_icons = false,
lsp_icons = true,
severity = "hint",
icons = {
["Error"] = { icon = "", color = "red" }, -- error
["Warning"] = { icon = "", color = "yellow" }, -- warning
["Information"] = { icon = "", color = "blue" }, -- info
["Hint"] = { icon = "", color = "magenta" }, -- hint
},
},
-- placeholders for additional user customizations
loclist = {},
helptags = {},
manpages = {},
-- optional override of file extension icon colors
-- available colors (terminal):
-- clear, bold, black, red, green, yellow
-- blue, magenta, cyan, grey, dark_grey, white
file_icon_colors = {
["lua"] = "blue",
},
}
This can also be run from a .vim
file using
lua << EOF
require('fzf-lua').setup{
-- ...
}
EOF
TODO
- Add more providers
LSP (refs, symbols, etc)(2021-07-20)git commits(2021-08-05)git branches(2021-08-05)- nvim built-in:
commands(2021-08-14)command history(2021-08-14)search history(2021-08-14)registers(2021-08-14)keymaps(2021-08-14)spelling suggestions(2021-08-14)marks(2021-08-14)
tags(2021-08-15)
- Improve previewer for
buffers
,marks
- Built-in previewer with treesitter support
- Add built-in plugin documentation
- Complete the Wiki
Credits
Big thank you to all those I borrowed code/ideas from, I read so many configs and plugin codes that I probably forgot where I found some samples from so if I missed your name feel free to contact me and I'll add it below:
- @vijaymarupudi for his wonderful nvim-fzf plugin which is in the core of this plugin
- @tjdevries for too many great things to list here and for borrowing some of his nvim-telescope provider code
- @lukas-reineke for inspiring the solution after browsing his dotfiles and coming across his fuzzy.lua , and while we're, also here for his great lua plugin indent-blankline
- @sindrets for borrowing utilities from his fantastic lua plugin diffview.nvim