performance optimizations, read below:

- do not spawn cmd with libuv unless 'file_icons' or 'git_icons' are set
- 'path.starts_with_separator' minor regex optimization
- 'files' cmd fallback order is now fd, **rg** and then find
- 'strip_cwd_prefix' enabled again (default: 'true')
- 'cwd' header line added to 'files' and 'git' providers
main
bhagwan 2 years ago
parent 2f30c9cb21
commit 05e22a4a61

@ -383,13 +383,13 @@ require'fzf-lua'.setup {
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
-- executed command priority is 'cmd' (if exists)
-- otherwise auto-detect prioritizes `fd` over `find`
-- default options are controlled by 'fd|find_opts'
-- otherwise auto-detect prioritizes `fd`:`rg`:`find`
-- default options are controlled by 'fd|rg|find|_opts'
-- NOTE: 'find -printf' requires GNU find
-- cmd = "find . -type f -printf '%P\n'",
find_opts = [[-type f -not -path '*/\.git/*' -printf '%P\n']],
fd_opts = [[--color never --type f --hidden --follow ]] ..
[[--exclude .git --exclude node_modules --exclude '*.pyc']],
rg_opts = "--color=never --files --hidden --follow -g '!.git'",
fd_opts = "--color=never --type f --hidden --follow --exclude .git",
actions = {
-- set bind to 'false' to disable an action
-- default action opens a single selection

@ -417,13 +417,13 @@ Consult the list below for available settings:
file_icons = true, -- show file icons?
color_icons = true, -- colorize file|git icons
-- executed command priority is 'cmd' (if exists)
-- otherwise auto-detect prioritizes `fd` over `find`
-- default options are controlled by 'fd|find_opts'
-- otherwise auto-detect prioritizes `fd`:`rg`:`find`
-- default options are controlled by 'fd|rg|find|_opts'
-- NOTE: 'find -printf' requires GNU find
-- cmd = "find . -type f -printf '%P\n'",
find_opts = [[-type f -not -path '*/\.git/*' -printf '%P\n']],
fd_opts = [[--color never --type f --hidden --follow ]] ..
[[--exclude .git --exclude node_modules --exclude '*.pyc']],
rg_opts = "--color=never --files --hidden --follow -g '!.git'",
fd_opts = "--color=never --type f --hidden --follow --exclude .git",
actions = {
-- set bind to 'false' to disable an action
-- default action opens a single selection

@ -1,3 +1,4 @@
local path = require "fzf-lua.path"
local utils = require "fzf-lua.utils"
local actions = require "fzf-lua.actions"
local previewers = require "fzf-lua.previewer"
@ -165,18 +166,14 @@ M.globals.files = {
git_icons = true,
git_status_cmd = {"git", "status", "-s"},
find_opts = [[-type f -not -path '*/\.git/*' -printf '%P\n']],
fd_opts =
[[--color never --type f --hidden --follow ]] ..
[[--exclude .git --exclude node_modules --exclude '*.pyc']],
rg_opts = "--color=never --files --hidden --follow -g '!.git'",
fd_opts = "--color=never --type f --hidden --follow --exclude .git",
actions = {
["default"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["alt-q"] = actions.file_sel_to_qf,
["ctrl-q"] = function()
utils.info("'ctrl-q|ctrl-a' has been deprecated in favor of 'alt-q|alt-a'")
end
},
}
-- Must construct our opts table in stages
@ -649,6 +646,9 @@ function M.normalize_opts(opts, defaults)
opts.cwd = nil
end
end
-- test for valid git_repo
opts.git_icons = opts.git_icons and path.is_git_repo(opts.cwd, true)
local executable = function(binary, fncerr, strerr)
if binary and vim.fn.executable(binary) ~= 1 then

@ -251,9 +251,9 @@ M.make_entry_file = function(opts, x)
-- fd v8.3 requires adding '--strip-cwd-prefix' to remove
-- the './' prefix, will not work with '--color=always'
-- https://github.com/sharkdp/fd/blob/master/CHANGELOG.md
-- if not (opts.strip_cwd_prefix == false) and path.starts_with_cwd(x) then
-- x = x:sub(3)
-- end
if not (opts.strip_cwd_prefix == false) and path.starts_with_cwd(x) then
x = x:sub(3)
end
if opts.cwd and #opts.cwd > 0 then
-- TODO: does this work if there are ANSI escape codes in x?
x = path.relative(x, opts.cwd)
@ -309,13 +309,39 @@ M.set_fzf_line_args = function(opts)
return opts
end
M.fzf_files = function(opts)
M.set_header = function(opts, type)
if not opts then opts = {} end
if opts.no_header then return opts end
if not opts.cwd_header then opts.cwd_header = "cwd:" end
if not opts.search_header then opts.search_header = "Searching for:" end
local header_str
local cwd_str = opts.cwd and opts.cwd ~= vim.loop.cwd() and
("%s %s"):format(opts.cwd_header, opts.cwd:gsub("^"..vim.env.HOME, "~"))
local search_str = opts.search and #opts.search > 0 and
("%s %s"):format(opts.search_header, opts.search)
-- 1: only search
-- 2: only cwd
-- otherwise, all
if type == 1 then header_str = search_str or ''
elseif type == 2 then header_str = cwd_str or ''
else
header_str = search_str or ''
if #header_str>0 and cwd_str and #cwd_str>0 then
header_str = header_str .. ", "
end
header_str = header_str .. (cwd_str or '')
end
if not header_str or #header_str==0 then return opts end
opts.fzf_opts['--header'] = vim.fn.shellescape(header_str)
return opts
end
M.fzf_files = function(opts, contents)
if not opts then return end
-- reset git tracking
opts.diff_files = nil
if opts.git_icons and not path.is_git_repo(opts.cwd, true) then opts.git_icons = false end
coroutine.wrap(function ()
@ -327,13 +353,7 @@ M.fzf_files = function(opts)
opts.diff_files = get_diff_files(opts)
end
local has_prefix = opts.file_icons or opts.git_icons or opts.lsp_icons
if not opts.filespec then
opts.filespec = utils._if(has_prefix, "{2}", "{1}")
end
local selected = M.fzf(opts, opts.fzf_fn)
local selected = M.fzf(opts, contents or opts.fzf_fn)
if opts.post_select_cb then
opts.post_select_cb()
@ -342,7 +362,8 @@ M.fzf_files = function(opts)
if not selected then return end
if #selected > 1 then
for i = 2, #selected do
local idx = utils.tbl_length(opts.actions)>1 and 2 or 1
for i = idx, #selected do
selected[i] = path.entry_to_file(selected[i], opts.cwd).stripped
if opts.cb_selected then
local cb_ret = opts.cb_selected(opts, selected[i])

@ -8,7 +8,7 @@ M.separator = function()
end
M.starts_with_separator = function(path)
return path:find(M.separator()) == 1
return path:find("^"..M.separator()) == 1
end
M.starts_with_cwd = function(path)

@ -26,6 +26,8 @@ local get_files_cmd = function(opts)
local command = nil
if vim.fn.executable("fd") == 1 then
command = string.format('fd %s', opts.fd_opts)
elseif vim.fn.executable("rg") == 1 then
command = string.format('rg %s', opts.rg_opts)
else
POSIX_find_compat(opts.find_opts)
command = string.format('find -L . %s', opts.find_opts)
@ -40,13 +42,16 @@ M.files = function(opts)
local command = get_files_cmd(opts)
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
{ cmd = command, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return core.make_entry_file(opts, x)
end)
local contents = (opts.git_icons or opts.file_icons) and
libuv.spawn_nvim_fzf_cmd(
{ cmd = command, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return core.make_entry_file(opts, x)
end)
or command
return core.fzf_files(opts)
opts = core.set_header(opts, 2)
return core.fzf_files(opts, contents)
end
local last_query = ""
@ -64,19 +69,11 @@ M.files_resume = function(opts)
last_query = args[1]
end, "{q}")
local command = get_files_cmd(opts)
opts.fzf_opts['--query'] = vim.fn.shellescape(last_query)
opts._fzf_cli_args = ('--bind=change:execute-silent:%s'):
format(vim.fn.shellescape(raw_act))
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
{cmd = command, cwd = opts.cwd},
function(x)
return core.make_entry_file(opts, x)
end)
return core.fzf_files(opts)
return M.files(opts)
end
M.args = function(opts)
@ -100,7 +97,7 @@ M.args = function(opts)
end
entries = nil
opts.fzf_fn = function (cb)
local contents = function (cb)
for _, x in ipairs(args) do
x = core.make_entry_file(opts, x)
if x then
@ -115,7 +112,7 @@ M.args = function(opts)
utils.delayed_cb(cb)
end
return core.fzf_files(opts)
return core.fzf_files(opts, contents)
end
return M

@ -12,13 +12,15 @@ M.files = function(opts)
if not opts then return end
opts.cwd = path.git_root(opts.cwd)
if not opts.cwd then return end
local make_entry_file = core.make_entry_file
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
{ cmd = opts.cmd, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return make_entry_file(opts, x)
end)
return core.fzf_files(opts)
local contents = (opts.git_icons or opts.file_icons) and
libuv.spawn_nvim_fzf_cmd(
{ cmd = opts.cmd, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return core.make_entry_file(opts, x)
end)
or opts.cmd
opts = core.set_header(opts, 2)
return core.fzf_files(opts, contents)
end
M.status = function(opts)
@ -29,7 +31,7 @@ M.status = function(opts)
if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd))
end
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
local contents = libuv.spawn_nvim_fzf_cmd(
{ cmd = opts.cmd, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
-- greedy match anything after last space
@ -42,16 +44,16 @@ M.status = function(opts)
end
return core.make_entry_file(opts, f)
end)
return core.fzf_files(opts)
opts = core.set_header(opts, 2)
return core.fzf_files(opts, contents)
end
local function git_cmd(opts)
opts.cwd = path.git_root(opts.cwd)
if not opts.cwd then return end
coroutine.wrap(function ()
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
{ cmd = opts.cmd, cwd = opts.cwd, pid_cb = opts._pid_cb })
local selected = core.fzf(opts, opts.fzf_fn)
opts = core.set_header(opts, 2)
local selected = core.fzf(opts, opts.cmd)
if not selected then return end
actions.act(opts.actions, selected, opts)
end)()

@ -52,32 +52,6 @@ local get_grep_cmd = function(opts, search_query, no_esc)
return string.format('%s %s %s', command, search_query, search_path)
end
local function set_search_header(opts, type)
if not opts then opts = {} end
if opts.no_header then return opts end
if not opts.cwd_header then opts.cwd_header = "cwd:" end
if not opts.search_header then opts.search_header = "Searching for:" end
local header_str
local cwd_str = opts.cwd and ("%s %s"):format(opts.cwd_header, opts.cwd)
local search_str = opts.search and #opts.search > 0 and
("%s %s"):format(opts.search_header, opts.search)
-- 1: only search
-- 2: only cwd
-- otherwise, all
if type == 1 then header_str = search_str or ''
elseif type == 2 then header_str = cwd_str or ''
else
header_str = search_str or ''
if #header_str>0 and cwd_str and #cwd_str>0 then
header_str = header_str .. ", "
end
header_str = header_str .. (cwd_str or '')
end
if not header_str or #header_str==0 then return opts end
opts.fzf_opts['--header'] = vim.fn.shellescape(header_str)
return opts
end
M.grep = function(opts)
opts = config.normalize_opts(opts, config.globals.grep)
@ -101,7 +75,7 @@ M.grep = function(opts)
end ]]
-- search query in header line
opts = set_search_header(opts)
opts = core.set_header(opts)
-- save the search query so the use can
-- call the same search again
@ -111,18 +85,16 @@ M.grep = function(opts)
local command = get_grep_cmd(opts, opts.search, no_esc)
opts.fzf_fn = libuv.spawn_nvim_fzf_cmd(
{ cmd = command, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return core.make_entry_file(opts, x)
end)
--[[ opts.cb_selected = function(_, x)
return x
end ]]
local contents = (opts.git_icons or opts.file_icons) and
libuv.spawn_nvim_fzf_cmd(
{ cmd = command, cwd = opts.cwd, pid_cb = opts._pid_cb },
function(x)
return core.make_entry_file(opts, x)
end)
or command
opts = core.set_fzf_line_args(opts)
core.fzf_files(opts)
core.fzf_files(opts, contents)
opts.search = nil
end
@ -151,7 +123,7 @@ M.live_grep = function(opts)
end
-- search query in header line
opts = set_search_header(opts, 2)
opts = core.set_header(opts, 2)
opts._reload_command = function(query)
if query and not (opts.save_last_search == false) then
@ -204,7 +176,7 @@ M.live_grep_native = function(opts)
end
-- search query in header line
opts = set_search_header(opts, 2)
opts = core.set_header(opts, 2)
-- fzf already adds single quotes around the placeholder when expanding
-- for skim we surround it with double quotes or single quote searches fail

@ -30,7 +30,7 @@ M.oldfiles = function(opts)
end
end
opts.fzf_fn = function (cb)
local contents = function (cb)
for _, x in ipairs(results) do
x = core.make_entry_file(opts, x)
if x then
@ -45,11 +45,7 @@ M.oldfiles = function(opts)
utils.delayed_cb(cb)
end
--[[ opts.cb_selected = function(_, x)
print("o:", x)
end ]]
return core.fzf_files(opts)
return core.fzf_files(opts, contents)
end
return M

@ -16,7 +16,7 @@ local quickfix_run = function(opts, cfg, locations)
if not opts.cwd then opts.cwd = vim.loop.cwd() end
opts.fzf_fn = function (cb)
local contents = function (cb)
for _, x in ipairs(results) do
x = core.make_entry_file(opts, x)
if x then
@ -36,7 +36,7 @@ local quickfix_run = function(opts, cfg, locations)
end ]]
opts = core.set_fzf_line_args(opts)
return core.fzf_files(opts)
return core.fzf_files(opts, contents)
end
M.quickfix = function(opts)

@ -26,7 +26,7 @@ local fzf_tags = function(opts)
local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd())
local current_file = vim.api.nvim_buf_get_name(0)
local fzf_function = function (cb)
local contents = function (cb)
--[[ local read_line = function(file)
local line
@ -137,8 +137,7 @@ local fzf_tags = function(opts)
end
opts = core.set_fzf_line_args(opts)
opts.fzf_fn = fzf_function
return core.fzf_files(opts)
return core.fzf_files(opts, contents)
end
M.tags = function(opts)

Loading…
Cancel
Save