From 887d6a4cd34ceff08e642a87610c9a6ba07c2291 Mon Sep 17 00:00:00 2001 From: bhagwan Date: Mon, 13 Dec 2021 13:21:58 -0800 Subject: [PATCH] live_grep: multiprocess as default provider, added glob support --- lua/fzf-lua/core.lua | 11 +++++++++-- lua/fzf-lua/init.lua | 5 +++-- lua/fzf-lua/libuv.lua | 10 ---------- lua/fzf-lua/make_entry.lua | 33 +++++++++++++++++++++++++++++++++ lua/fzf-lua/providers/grep.lua | 31 ++++++++++++++++++++++++++++--- 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/lua/fzf-lua/core.lua b/lua/fzf-lua/core.lua index 08ba0c1..d958bec 100644 --- a/lua/fzf-lua/core.lua +++ b/lua/fzf-lua/core.lua @@ -210,7 +210,13 @@ M.mt_cmd_wrapper = function(opts) "file_icons", "color_icons", "strip_cwd_prefix", + "rg_glob", } + -- caller reqested rg with glob support + if o.rg_glob then + table.insert(names, "glob_flag") + table.insert(names, "glob_separator") + end local str = "" for _, name in ipairs(names) do if o[name] ~= nil then @@ -228,10 +234,11 @@ M.mt_cmd_wrapper = function(opts) return '{'..str..'}' end - if not opts.git_icons and not opts.file_icons then + if not opts.force_multiprocess and + not opts.git_icons and not opts.file_icons then -- command does not require any processing return opts.cmd - elseif opts.multiprocess then + elseif opts.multiprocess or opts.force_multiprocess then local fn_preprocess = [[return require("make_entry").preprocess]] local fn_transform = [[return require("make_entry").file]] if not opts.no_remote_config then diff --git a/lua/fzf-lua/init.lua b/lua/fzf-lua/init.lua index e240380..7bb48f3 100644 --- a/lua/fzf-lua/init.lua +++ b/lua/fzf-lua/init.lua @@ -83,10 +83,11 @@ M.files = require'fzf-lua.providers.files'.files M.files_resume = require'fzf-lua.providers.files'.files_resume M.args = require'fzf-lua.providers.files'.args M.grep = require'fzf-lua.providers.grep'.grep -M.live_grep = require'fzf-lua.providers.grep'.live_grep +M.live_grep = require'fzf-lua.providers.grep'.live_grep_mt +M.live_grep_old = require'fzf-lua.providers.grep'.live_grep M.live_grep_native = require'fzf-lua.providers.grep'.live_grep_native M.live_grep_resume = require'fzf-lua.providers.grep'.live_grep_resume -M.live_grep_glob = require'fzf-lua.providers.grep'.live_grep_glob +M.live_grep_glob = require'fzf-lua.providers.grep'.live_grep_glob_mt 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 diff --git a/lua/fzf-lua/libuv.lua b/lua/fzf-lua/libuv.lua index 98d0016..9026c9a 100644 --- a/lua/fzf-lua/libuv.lua +++ b/lua/fzf-lua/libuv.lua @@ -290,16 +290,6 @@ M.spawn_stdio = function(opts, fn_transform, fn_preprocess) -- run the preprocessing fn if fn_preprocess then fn_preprocess(opts) end - -- nifty hack to avoid having to double escape quotations - -- see my comment within the 'live_grep' code initial_command - opts.cmd = opts.cmd:gsub("{argv%d+}", - function(x) - local idx = x:match("{argv(%d+)}") - -- argv1 is actually the 7th argument if we count - -- arguments already supplied by 'wrap_spawn_stdio' - local argv = vim.v.argv[idx+6] - return vim.fn.shellescape(argv) - end) -- for i=0,8 do -- io.stdout:write(("%d %s\n"):format(i, vim.v.argv[i])) diff --git a/lua/fzf-lua/make_entry.lua b/lua/fzf-lua/make_entry.lua index 66cbf24..79e39ef 100644 --- a/lua/fzf-lua/make_entry.lua +++ b/lua/fzf-lua/make_entry.lua @@ -149,6 +149,39 @@ M.preprocess = function(opts) if opts.git_icons then opts.diff_files = M.get_diff_files(opts) end + + local argv = function(i) + -- argv1 is actually the 7th argument if we count + -- arguments already supplied by 'wrap_spawn_stdio' + return i and vim.v.argv[i+6] or nil + end + + -- did the caller request rg with glob support? + -- mannipulation needs to be done before the argv hack + if opts.rg_glob then + local query = argv(1) + if query and query:find(opts.glob_separator) then + local glob_args = "" + local search_query, glob_str = query:match("(.*)"..opts.glob_separator.."(.*)") + for _, s in ipairs(utils.strsplit(glob_str, "%s")) do + glob_args = glob_args .. ("%s %s ") + :format(opts.glob_flag, vim.fn.shellescape(s)) + end + -- reset argv1 so it doesn't get replaced again below + opts.cmd = opts.cmd:gsub("{argv1}", + glob_args .. vim.fn.shellescape(search_query)) + end + end + + -- nifty hack to avoid having to double escape quotations + -- see my comment inside 'live_grep' initial_command code + opts.cmd = opts.cmd:gsub("{argv%d+}", + function(x) + local idx = x:match("{argv(%d+)}") + return vim.fn.shellescape(argv(idx)) + end) + + return opts end diff --git a/lua/fzf-lua/providers/grep.lua b/lua/fzf-lua/providers/grep.lua index 4e80348..e796c59 100644 --- a/lua/fzf-lua/providers/grep.lua +++ b/lua/fzf-lua/providers/grep.lua @@ -144,6 +144,33 @@ end M.live_grep_native = function(opts) + -- backward compatibility, by setting git|files icons to false + -- we forces mt_cmd_wrapper to pipe the command as is so fzf + -- runs the command directly in the 'change:reload' event + opts = opts or {} + opts.git_icons = false + opts.file_icons = false + + return M.live_grep_mt(opts) +end + +M.live_grep_glob_mt = function(opts) + + if vim.fn.executable("rg") ~= 1 then + utils.warn("'--glob|iglob' flags requires 'rg' (https://github.com/BurntSushi/ripgrep)") + return + end + + -- 'rg_glob = true' enables the glob processsing in + -- 'make_entry.preprocess', only supported with multiprocess + opts = opts or {} + opts.rg_glob = true + opts.force_multiprocess = true + return M.live_grep_mt(opts) +end + +M.live_grep_mt = function(opts) + opts = config.normalize_opts(opts, config.globals.grep) if not opts then return end @@ -169,11 +196,9 @@ M.live_grep_native = function(opts) -- search query in header line opts = core.set_header(opts, 2) - -- we do not process any entries in the 'native' version as - -- fzf runs the command directly in the 'change:reload' event -- since the introduction of 'libuv.spawn_stdio' with '--headless' -- we can now run the command externally with minimal overhead - if not opts.multiprocess then + if not opts.multiprocess and not opts.force_multiprocess then opts.git_icons = false opts.file_icons = false end