feat(grep_lgrep): save query prompt between toggles

fix(live_grep_resume): when using skim
lsp_workspace_symbols: 'opt.query' -> 'opts.lsp_query'
API adjustments:
- Support for `opts.query` everywhere
- Auto shellescape `opts.preview`
- Removed global default prompt
main
bhagwan 2 years ago
parent 817df87a8e
commit d7de3b51ae

@ -411,7 +411,6 @@ require'fzf-lua'.setup {
-- set to '' for a non-value flag -- set to '' for a non-value flag
-- for raw args use `fzf_args` instead -- for raw args use `fzf_args` instead
['--ansi'] = '', ['--ansi'] = '',
['--prompt'] = '> ',
['--info'] = 'inline', ['--info'] = 'inline',
['--height'] = '100%', ['--height'] = '100%',
['--layout'] = 'reverse', ['--layout'] = 'reverse',

@ -450,7 +450,6 @@ Consult the list below for available settings:
-- set to '' for a non-value flag -- set to '' for a non-value flag
-- for raw args use `fzf_args` instead -- for raw args use `fzf_args` instead
['--ansi'] = '', ['--ansi'] = '',
['--prompt'] = '> ',
['--info'] = 'inline', ['--info'] = 'inline',
['--height'] = '100%', ['--height'] = '100%',
['--layout'] = 'reverse', ['--layout'] = 'reverse',

@ -614,6 +614,12 @@ M.grep_lgrep = function(_, opts)
rg_glob = opts.rg_glob or opts.__call_opts.rg_glob, rg_glob = opts.rg_glob or opts.__call_opts.rg_glob,
-- globs always require command processing with 'multiprocess' -- globs always require command processing with 'multiprocess'
requires_processing = opts.rg_glob or opts.__call_opts.rg_glob, requires_processing = opts.rg_glob or opts.__call_opts.rg_glob,
-- grep has both search string and query prompt, when switching
-- from live_grep to grep we want to restore both:
-- * we save the last query prompt when exiting grep
-- * we set query to the last known when entering grep
__prev_query = not opts.fn_reload and opts.__resume_data.last_query,
query = opts.fn_reload and opts.__call_opts.__prev_query,
}, opts.__call_opts or {}) }, opts.__call_opts or {})
-- 'fn_reload' is set only on 'live_grep' calls -- 'fn_reload' is set only on 'live_grep' calls

@ -132,7 +132,6 @@ M.globals = {
fzf_bin = nil, fzf_bin = nil,
fzf_opts = { fzf_opts = {
['--ansi'] = '', ['--ansi'] = '',
['--prompt'] = '> ',
['--info'] = 'inline', ['--info'] = 'inline',
['--height'] = '100%', ['--height'] = '100%',
['--layout'] = 'reverse', ['--layout'] = 'reverse',

@ -92,7 +92,6 @@ M.fzf_resume = function(opts)
end end
opts.__resume = true opts.__resume = true
opts.query = last_query opts.query = last_query
opts.fzf_opts['--query'] = last_query and vim.fn.shellescape(last_query)
M.fzf_exec(config.__resume_data.contents, opts) M.fzf_exec(config.__resume_data.contents, opts)
end end
@ -130,6 +129,8 @@ M.fzf = function(opts, contents)
-- providers -- providers
config.__resume_data.last_query = nil config.__resume_data.last_query = nil
end end
-- save a ref to resume data for 'grep_lgrep'
opts.__resume_data = config.__resume_data
end end
if opts.save_query or if opts.save_query or
opts.global_resume and opts.global_resume_query then opts.global_resume and opts.global_resume_query then
@ -180,6 +181,9 @@ M.fzf = function(opts, contents)
previewer = preview_opts._ctor()(preview_opts, opts, fzf_win) previewer = preview_opts._ctor()(preview_opts, opts, fzf_win)
end end
if previewer then if previewer then
-- we use fzf_opts because previewer:cmdline is already
-- shellescaped, clear opts.preview so it doesn't override
opts.preview = nil
opts.fzf_opts['--preview'] = previewer:cmdline() opts.fzf_opts['--preview'] = previewer:cmdline()
if type(previewer.preview_window) == 'function' then if type(previewer.preview_window) == 'function' then
-- do we need to override the preview_window args? -- do we need to override the preview_window args?
@ -226,7 +230,7 @@ M.fzf = function(opts, contents)
-- in the first line, save&remove it -- in the first line, save&remove it
if selected and #selected>0 and if selected and #selected>0 and
opts.fzf_opts['--print-query'] ~= nil then opts.fzf_opts['--print-query'] ~= nil then
if opts.fn_save_query then if opts.fn_save_query and not (opts._is_skim and opts.fn_reload) then
-- reminder: this doesn't get called with 'live_grep' when using skim -- reminder: this doesn't get called with 'live_grep' when using skim
-- due to a bug where '--print-query --interactive' combo is broken: -- due to a bug where '--print-query --interactive' combo is broken:
-- skim always prints an emtpy line where the typed query should be -- skim always prints an emtpy line where the typed query should be
@ -329,12 +333,24 @@ M.build_fzf_cli = function(opts)
}) do }) do
opts[o] = opts[o] or config.globals[o] opts[o] = opts[o] or config.globals[o]
end end
-- preview and query have special handling:
-- 'opts.<name>' is prioritized over 'fzf_opts[--name]'
-- 'opts.<name>' is automatically shellescaped
for _, o in ipairs({ 'query', 'preview' }) do
local flag = string.format("--%s", o)
if opts[o] ~= nil then
-- opt can be 'false' (disabled)
-- don't shellescape in this case
opts.fzf_opts[flag] = opts[o] and vim.fn.shellescape(opts[o])
else
opts.fzf_opts[flag] = opts.fzf_opts[flag]
end
end
opts.fzf_opts["--bind"] = M.create_fzf_binds(opts.keymap.fzf) opts.fzf_opts["--bind"] = M.create_fzf_binds(opts.keymap.fzf)
if opts.fzf_colors then if opts.fzf_colors then
opts.fzf_opts["--color"] = M.create_fzf_colors(opts) opts.fzf_opts["--color"] = M.create_fzf_colors(opts)
end end
opts.fzf_opts["--expect"] = actions.expect(opts.actions) opts.fzf_opts["--expect"] = actions.expect(opts.actions)
opts.fzf_opts["--preview"] = opts.preview or opts.fzf_opts["--preview"]
if opts.fzf_opts["--preview-window"] == nil then if opts.fzf_opts["--preview-window"] == nil then
opts.fzf_opts["--preview-window"] = M.preview_window(opts) opts.fzf_opts["--preview-window"] = M.preview_window(opts)
end end
@ -343,7 +359,7 @@ M.build_fzf_cli = function(opts)
opts.fzf_opts["--preview-window"] .. ":" .. opts.preview_offset opts.fzf_opts["--preview-window"] .. ":" .. opts.preview_offset
end end
-- shell escape the prompt -- shell escape the prompt
opts.fzf_opts["--prompt"] = opts.fzf_opts["--prompt"] = (opts.prompt or opts.fzf_opts["--prompt"]) and
vim.fn.shellescape(opts.prompt or opts.fzf_opts["--prompt"]) vim.fn.shellescape(opts.prompt or opts.fzf_opts["--prompt"])
-- multi | no-multi (select) -- multi | no-multi (select)
if opts.nomulti or opts.fzf_opts["--no-multi"] then if opts.nomulti or opts.fzf_opts["--no-multi"] then
@ -645,20 +661,26 @@ M.setup_fzf_interactive_flags = function(command, fzf_field_expression, opts)
if opts._is_skim then if opts._is_skim then
-- skim interactive mode does not need a piped command -- skim interactive mode does not need a piped command
opts.__fzf_init_cmd = nil opts.__fzf_init_cmd = nil
opts.prompt = opts.prompt or opts.fzf_opts['--prompt'] opts.prompt = opts.__prompt or opts.prompt or opts.fzf_opts['--prompt']
if opts.prompt then if opts.prompt then
opts.fzf_opts['--prompt'] = opts.prompt:match("[^%*]+") opts.fzf_opts['--prompt'] = opts.prompt:match("[^%*]+")
opts.fzf_opts['--cmd-prompt'] = libuv.shellescape(opts.prompt) opts.fzf_opts['--cmd-prompt'] = libuv.shellescape(opts.prompt)
-- save original prompt and reset the current one since
-- we're using the '--cmd-prompt' as the "main" prompt
-- required for resume to have the asterisk prompt prefix
opts.__prompt = opts.prompt
opts.prompt = nil opts.prompt = nil
end end
-- since we surrounded the skim placeholder with quotes
-- we need to escape them in the initial query
opts.fzf_opts['--cmd-query'] = libuv.shellescape(utils.sk_escape(opts.query))
-- '--query' was set by 'resume()', skim has the option to switch back and -- '--query' was set by 'resume()', skim has the option to switch back and
-- forth between interactive command and fuzzy matching (using 'ctrl-q') -- forth between interactive command and fuzzy matching (using 'ctrl-q')
-- setting both '--query' and '--cmd-query' will use <query> to fuzzy match -- setting both '--query' and '--cmd-query' will use <query> to fuzzy match
-- on top of our result set double filtering our results (undesierable) -- on top of our result set double filtering our results (undesierable)
opts.fzf_opts['--query'] = nil opts.fzf_opts['--query'] = nil
-- since we surrounded the skim placeholder with quotes opts.query = nil
-- we need to escape them in the initial query -- setup as inetarctive
opts.fzf_opts['--cmd-query'] = libuv.shellescape(utils.sk_escape(opts.query))
opts._fzf_cli_args = string.format("--interactive --cmd %s", opts._fzf_cli_args = string.format("--interactive --cmd %s",
vim.fn.shellescape(reload_command)) vim.fn.shellescape(reload_command))
else else

@ -32,7 +32,7 @@ M.status = function(opts)
opts = set_git_cwd_args(opts) opts = set_git_cwd_args(opts)
if not opts.cwd then return end if not opts.cwd then return end
if opts.preview then if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) opts.preview = path.git_cwd(opts.preview, opts)
end end
-- we don't need git icons since we get them -- we don't need git icons since we get them
-- as part of our `git status -s` -- as part of our `git status -s`
@ -93,7 +93,7 @@ end
M.commits = function(opts) M.commits = function(opts)
opts = config.normalize_opts(opts, config.globals.git.commits) opts = config.normalize_opts(opts, config.globals.git.commits)
if not opts then return end if not opts then return end
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) opts.preview = path.git_cwd(opts.preview, opts)
return git_cmd(opts) return git_cmd(opts)
end end
@ -115,7 +115,7 @@ M.bcommits = function(opts)
.. vim.fn.shellescape(file) .. vim.fn.shellescape(file)
.. after_pipe .. after_pipe
end end
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) opts.preview = path.git_cwd(opts.preview, opts)
return git_cmd(opts) return git_cmd(opts)
end end
@ -123,8 +123,10 @@ M.branches = function(opts)
opts = config.normalize_opts(opts, config.globals.git.branches) opts = config.normalize_opts(opts, config.globals.git.branches)
if not opts then return end if not opts then return end
opts.fzf_opts["--no-multi"] = '' opts.fzf_opts["--no-multi"] = ''
opts._preview = path.git_cwd(opts.preview, opts) opts.__preview = path.git_cwd(opts.preview, opts)
opts.preview = shell.preview_action_cmd(function(items) -- nullify 'opts.preview' doesn't take priority over '--preview'
opts.preview = nil
opts.fzf_opts["--preview"] = shell.preview_action_cmd(function(items)
local branch = items[1]:gsub("%*", "") -- remove the * from current branch local branch = items[1]:gsub("%*", "") -- remove the * from current branch
if branch:find("%)") ~= nil then if branch:find("%)") ~= nil then
-- (HEAD detached at origin/master) -- (HEAD detached at origin/master)
@ -133,7 +135,7 @@ M.branches = function(opts)
-- remove anything past space -- remove anything past space
branch = branch:match("[^ ]+") branch = branch:match("[^ ]+")
end end
return opts._preview:gsub("{.*}", branch) return opts.__preview:gsub("{.*}", branch)
-- return "echo " .. branch -- return "echo " .. branch
end, nil, opts.debug) end, nil, opts.debug)
return git_cmd(opts) return git_cmd(opts)
@ -144,7 +146,7 @@ M.stash = function(opts)
if not opts then return end if not opts then return end
if opts.preview then if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) opts.preview = path.git_cwd(opts.preview, opts)
end end
if opts.fzf_opts['--header'] == nil then if opts.fzf_opts['--header'] == nil then

@ -443,7 +443,7 @@ M.workspace_symbols = function(opts)
opts = set_async_default(opts, true) opts = set_async_default(opts, true)
opts = normalize_lsp_opts(opts, config.globals.lsp) opts = normalize_lsp_opts(opts, config.globals.lsp)
if not opts then return end if not opts then return end
opts.lsp_params = {query = opts.query or ''} opts.lsp_params = {query = opts.lsp_query or ''}
opts = core.set_header(opts, opts.headers or {"cwd","query","regex_filter"}) opts = core.set_header(opts, opts.headers or {"cwd","query","regex_filter"})
opts = core.set_fzf_field_index(opts) opts = core.set_fzf_field_index(opts)
if opts.force_uri == nil then opts.force_uri = true end if opts.force_uri == nil then opts.force_uri = true end

@ -24,16 +24,25 @@ function FzfWin.save_query(key)
if not self then return end if not self then return end
local lines = vim.api.nvim_buf_get_lines(self.fzf_bufnr, 0, 1, false) local lines = vim.api.nvim_buf_get_lines(self.fzf_bufnr, 0, 1, false)
if not lines or vim.tbl_isempty(lines) then return end if not lines or vim.tbl_isempty(lines) then return end
-- 'live_grep' prepends an asterisk to the prompt local query = nil
-- remove '*' from the start of the line & prompt if not self.prompt then
local query = lines[1]:gsub("^%*+", "") -- no prompt specifed, assume default '> '
:gsub("^"..utils.lua_escape(self.prompt:match("[^%*]+")), "") -- or 'c> ' in skim interactive mode
-- remove '--info=inline' query = lines[1]:match(".->%s(.*)")
query = query and query:gsub("[<%-]%s%d+/%d+.*$", "") else
-- remove '< [Command failed: ...] -- 'live_grep' prepends an asterisk to the prompt
query = query and query:gsub("<%s%[Command failed:.*$", "") -- remove '*' from the start of the line & prompt
-- trim whitespaces at the end query = lines[1]:gsub("^%*+", "")
query = query and query:gsub("%s*$", "") :gsub("^"..utils.lua_escape(self.prompt:match("[^%*]+")), "")
end
if query then
-- remove '--info=inline'
query = query:gsub("[<%-]%s%d+/%d+.*$", "")
-- remove '< [Command failed: ...]
query = query:gsub("<%s%[Command failed:.*$", "")
-- trim whitespaces at the end
query = query:gsub("%s*$", "")
end
if self.fn_save_query then if self.fn_save_query then
self.fn_save_query(query) self.fn_save_query(query)
end end

Loading…
Cancel
Save