live_grep saves last search term (closes issue #103)

main
bhagwan 3 years ago
parent cc7828d4d2
commit 62024ecf9a

@ -206,6 +206,8 @@ end
M.fzf_files = function(opts)
if not opts then return end
-- reset git tracking
opts.diff_files, opts.untracked_files = nil, nil
if opts.git_icons and not path.is_git_repo(opts.cwd, true) then opts.git_icons = false end
@ -255,4 +257,107 @@ M.fzf_files = function(opts)
end
M.fzf_files_interactive = function(opts)
opts = opts or config.normalize_opts(opts, config.globals.files)
if not opts then return end
local uv = vim.loop
local raw_async_act = require("fzf.actions").raw_async_action(function(pipe, args)
local shell_cmd = opts._cb_live_cmd(args[1])
local output_pipe = uv.new_pipe(false)
local error_pipe = uv.new_pipe(false)
local shell = vim.env.SHELL or "sh"
uv.spawn(shell, {
args = { "-c", shell_cmd },
stdio = { nil, output_pipe, error_pipe }
}, function(code, signal)
end)
local cleaned_up = false
local cleanup = function()
if not cleaned_up then
cleaned_up = true
uv.read_stop(output_pipe)
uv.read_stop(error_pipe)
uv.close(output_pipe)
uv.close(error_pipe)
uv.close(pipe)
end
end
local read_cb = function(err, data)
if err then
cleanup()
assert(not err)
end
if not data then
cleanup()
return
end
uv.write(pipe, data, function(err)
if err then
cleanup()
end
end)
end
output_pipe:read_start(read_cb)
error_pipe:read_start(read_cb)
end)
local act_cmd = raw_async_act
-- cannot be nil
local query = opts._live_query or ''
local placeholder = utils._if(opts._is_skim, '"{}"', '{q}')
-- HACK: nvim-fzf action rg assumes preview placeholder '{+}'
-- replace it with the correct query placeholder
act_cmd = act_cmd:gsub("{%+}", placeholder)
if opts._is_skim then
-- do not run an empty string query unless the user requested
if not opts.exec_empty_query then
act_cmd = "sh -c " .. vim.fn.shellescape(
("[ -z %s ] || %s"):format(placeholder, act_cmd))
else
act_cmd = vim.fn.shellescape(act_cmd)
end
-- skim interactive mode does not need a piped command
opts.fzf_fn = nil
opts._fzf_cli_args = string.format(
"--prompt='*%s' --cmd-prompt='%s' --cmd-query='%s' -i -c %s",
opts.prompt, opts.prompt, query, act_cmd)
else
-- fzf already adds single quotes
-- around the place holder
opts.fzf_fn = {}
if opts.exec_empty_query or (query and #query>0) then
opts.fzf_fn = require("fzf.helpers").cmd_line_transformer(
act_cmd:gsub(placeholder, ('"%s"'):format(query)),
function(x)
return M.make_entry_file(opts, x)
end)
end
opts._fzf_cli_args = string.format('--phony --query="%s" --bind=%s', query,
vim.fn.shellescape(string.format("change:reload:%s || true", act_cmd)))
end
-- we cannot parse any entries as they're not getting called
-- past the initial command, until I can find a solution for
-- that icons must be disabled
opts.git_icons = false
opts.file_icons = false
opts = M.set_fzf_line_args(opts)
M.fzf_files(opts)
end
return M

@ -42,6 +42,7 @@ M.fzf_files = require'fzf-lua.core'.fzf_files
M.files = require'fzf-lua.providers.files'.files
M.grep = require'fzf-lua.providers.grep'.grep
M.live_grep = require'fzf-lua.providers.grep'.live_grep
M.live_grep_old = require'fzf-lua.providers.grep'.live_grep_old
M.grep_last = require'fzf-lua.providers.grep'.grep_last
M.grep_cword = require'fzf-lua.providers.grep'.grep_cword
M.grep_cWORD = require'fzf-lua.providers.grep'.grep_cWORD

@ -8,6 +8,8 @@ local core = require "fzf-lua.core"
local utils = require "fzf-lua.utils"
local config = require "fzf-lua.config"
local last_search = {}
local M = {}
local get_grep_cmd = function(opts, search_query, no_esc)
@ -59,8 +61,10 @@ M.grep = function(opts)
opts = config.normalize_opts(opts, config.globals.grep)
if not opts then return end
local no_esc = false
if opts.continue_last_search or opts.repeat_last_search then
opts.search = config._grep_last_search
no_esc = last_search.no_esc
opts.search = last_search.query
end
-- if user did not provide a search term
@ -79,9 +83,13 @@ M.grep = function(opts)
-- save the search query so the use can
-- call the same search again
config._grep_last_search = opts.search
last_search = {}
last_search.no_esc = no_esc or opts.no_esc
last_search.query = opts.search
local command = get_grep_cmd(opts, opts.search)
local command = get_grep_cmd(opts,
utils._if(no_esc, vim.fn.shellescape(opts.search), opts.search),
no_esc)
opts.fzf_fn = fzf_helpers.cmd_line_transformer(
command,
@ -103,17 +111,65 @@ M.live_grep = function(opts)
opts = config.normalize_opts(opts, config.globals.grep)
if not opts then return end
local no_esc = false
if opts.continue_last_search or opts.repeat_last_search then
opts.search = config._grep_last_search
no_esc = last_search.no_esc
opts.search = last_search.query
end
opts._live_query = opts.search or ''
if opts.search and #opts.search>0 then
-- save the search query so the use can
-- call the same search again
last_search = {}
last_search.no_esc = true
last_search.query = opts.search
-- escape unless the user requested not to
if not no_esc and not opts.no_esc then
opts._live_query = utils.rg_escape(opts.search)
end
end
opts._cb_live_cmd = function(query)
if query and #query>0 and not opts.do_not_save_last_search then
last_search = {}
last_search.no_esc = true
last_search.query = query
end
-- can be nill when called as fzf initial command
query = query or ''
-- TODO: need to empty filespec
-- fix this collision, rename to _filespec
opts.no_esc = nil
opts.filespec = nil
return get_grep_cmd(opts, vim.fn.shellescape(query), true)
end
core.fzf_files_interactive(opts)
end
M.live_grep_old = function(opts)
opts = config.normalize_opts(opts, config.globals.grep)
if not opts then return end
local no_esc = false
if opts.continue_last_search or opts.repeat_last_search then
no_esc = last_search.no_esc
opts.search = last_search.query
end
local query = opts.search or ''
if opts.search and #opts.search>0 then
-- save the search query so the use can
-- call the same search again
config._grep_last_search = opts.search
last_search = {}
last_search.no_esc = true
last_search.query = opts.search
-- escape unless the user requested not to
if not opts.no_esc then query = utils.rg_escape(opts.search) end
if not no_esc and not opts.no_esc then
query = utils.rg_escape(opts.search)
end
end
local placeholder

@ -66,7 +66,7 @@ function M.rg_escape(str)
if not str then return str end
-- [(~'"\/$?'`*&&||;[]<>)]
-- escape "\~$?*|[()"
return str:gsub('[\\~$?*|{\\[()"]', function(x)
return str:gsub('[\\~$?*|{\\[()"`]', function(x)
return '\\' .. x
end)
end

Loading…
Cancel
Save