diff --git a/README.md b/README.md index 0c323d9..8a364eb 100644 --- a/README.md +++ b/README.md @@ -411,7 +411,6 @@ require'fzf-lua'.setup { -- set to '' for a non-value flag -- for raw args use `fzf_args` instead ['--ansi'] = '', - ['--prompt'] = '> ', ['--info'] = 'inline', ['--height'] = '100%', ['--layout'] = 'reverse', diff --git a/doc/fzf-lua.txt b/doc/fzf-lua.txt index b462891..41e3931 100644 --- a/doc/fzf-lua.txt +++ b/doc/fzf-lua.txt @@ -450,7 +450,6 @@ Consult the list below for available settings: -- set to '' for a non-value flag -- for raw args use `fzf_args` instead ['--ansi'] = '', - ['--prompt'] = '> ', ['--info'] = 'inline', ['--height'] = '100%', ['--layout'] = 'reverse', diff --git a/lua/fzf-lua/actions.lua b/lua/fzf-lua/actions.lua index 69e018e..2f3877d 100644 --- a/lua/fzf-lua/actions.lua +++ b/lua/fzf-lua/actions.lua @@ -614,6 +614,12 @@ M.grep_lgrep = function(_, opts) rg_glob = opts.rg_glob or opts.__call_opts.rg_glob, -- globs always require command processing with 'multiprocess' 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 {}) -- 'fn_reload' is set only on 'live_grep' calls diff --git a/lua/fzf-lua/config.lua b/lua/fzf-lua/config.lua index 88e4a7d..2808dac 100644 --- a/lua/fzf-lua/config.lua +++ b/lua/fzf-lua/config.lua @@ -132,7 +132,6 @@ M.globals = { fzf_bin = nil, fzf_opts = { ['--ansi'] = '', - ['--prompt'] = '> ', ['--info'] = 'inline', ['--height'] = '100%', ['--layout'] = 'reverse', diff --git a/lua/fzf-lua/core.lua b/lua/fzf-lua/core.lua index 714d232..a9523e3 100644 --- a/lua/fzf-lua/core.lua +++ b/lua/fzf-lua/core.lua @@ -92,7 +92,6 @@ M.fzf_resume = function(opts) end opts.__resume = true opts.query = last_query - opts.fzf_opts['--query'] = last_query and vim.fn.shellescape(last_query) M.fzf_exec(config.__resume_data.contents, opts) end @@ -130,6 +129,8 @@ M.fzf = function(opts, contents) -- providers config.__resume_data.last_query = nil end + -- save a ref to resume data for 'grep_lgrep' + opts.__resume_data = config.__resume_data end if opts.save_query or 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) end 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() if type(previewer.preview_window) == 'function' then -- 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 if selected and #selected>0 and 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 -- due to a bug where '--print-query --interactive' combo is broken: -- skim always prints an emtpy line where the typed query should be @@ -329,12 +333,24 @@ M.build_fzf_cli = function(opts) }) do opts[o] = opts[o] or config.globals[o] end + -- preview and query have special handling: + -- 'opts.' is prioritized over 'fzf_opts[--name]' + -- 'opts.' 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) if opts.fzf_colors then opts.fzf_opts["--color"] = M.create_fzf_colors(opts) end 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 opts.fzf_opts["--preview-window"] = M.preview_window(opts) end @@ -343,7 +359,7 @@ M.build_fzf_cli = function(opts) opts.fzf_opts["--preview-window"] .. ":" .. opts.preview_offset end -- 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"]) -- multi | no-multi (select) 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 -- skim interactive mode does not need a piped command 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 opts.fzf_opts['--prompt'] = opts.prompt:match("[^%*]+") 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 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 -- forth between interactive command and fuzzy matching (using 'ctrl-q') -- setting both '--query' and '--cmd-query' will use to fuzzy match -- on top of our result set double filtering our results (undesierable) opts.fzf_opts['--query'] = nil - -- 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)) + opts.query = nil + -- setup as inetarctive opts._fzf_cli_args = string.format("--interactive --cmd %s", vim.fn.shellescape(reload_command)) else diff --git a/lua/fzf-lua/providers/git.lua b/lua/fzf-lua/providers/git.lua index dd81bae..0fcbd0f 100644 --- a/lua/fzf-lua/providers/git.lua +++ b/lua/fzf-lua/providers/git.lua @@ -32,7 +32,7 @@ M.status = function(opts) opts = set_git_cwd_args(opts) if not opts.cwd then return end if opts.preview then - opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) + opts.preview = path.git_cwd(opts.preview, opts) end -- we don't need git icons since we get them -- as part of our `git status -s` @@ -93,7 +93,7 @@ end M.commits = function(opts) opts = config.normalize_opts(opts, config.globals.git.commits) 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) end @@ -115,7 +115,7 @@ M.bcommits = function(opts) .. vim.fn.shellescape(file) .. after_pipe end - opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) + opts.preview = path.git_cwd(opts.preview, opts) return git_cmd(opts) end @@ -123,8 +123,10 @@ M.branches = function(opts) opts = config.normalize_opts(opts, config.globals.git.branches) if not opts then return end opts.fzf_opts["--no-multi"] = '' - opts._preview = path.git_cwd(opts.preview, opts) - opts.preview = shell.preview_action_cmd(function(items) + opts.__preview = path.git_cwd(opts.preview, opts) + -- 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 if branch:find("%)") ~= nil then -- (HEAD detached at origin/master) @@ -133,7 +135,7 @@ M.branches = function(opts) -- remove anything past space branch = branch:match("[^ ]+") end - return opts._preview:gsub("{.*}", branch) + return opts.__preview:gsub("{.*}", branch) -- return "echo " .. branch end, nil, opts.debug) return git_cmd(opts) @@ -144,7 +146,7 @@ M.stash = function(opts) if not opts then return end if opts.preview then - opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) + opts.preview = path.git_cwd(opts.preview, opts) end if opts.fzf_opts['--header'] == nil then diff --git a/lua/fzf-lua/providers/lsp.lua b/lua/fzf-lua/providers/lsp.lua index 3f8a9dd..1b6c381 100644 --- a/lua/fzf-lua/providers/lsp.lua +++ b/lua/fzf-lua/providers/lsp.lua @@ -443,7 +443,7 @@ M.workspace_symbols = function(opts) opts = set_async_default(opts, true) opts = normalize_lsp_opts(opts, config.globals.lsp) 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_fzf_field_index(opts) if opts.force_uri == nil then opts.force_uri = true end diff --git a/lua/fzf-lua/win.lua b/lua/fzf-lua/win.lua index 8e555c7..7c869d2 100644 --- a/lua/fzf-lua/win.lua +++ b/lua/fzf-lua/win.lua @@ -24,16 +24,25 @@ function FzfWin.save_query(key) if not self then return end 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 - -- 'live_grep' prepends an asterisk to the prompt - -- remove '*' from the start of the line & prompt - local query = lines[1]:gsub("^%*+", "") - :gsub("^"..utils.lua_escape(self.prompt:match("[^%*]+")), "") - -- remove '--info=inline' - query = query and query:gsub("[<%-]%s%d+/%d+.*$", "") - -- remove '< [Command failed: ...] - query = query and query:gsub("<%s%[Command failed:.*$", "") - -- trim whitespaces at the end - query = query and query:gsub("%s*$", "") + local query = nil + if not self.prompt then + -- no prompt specifed, assume default '> ' + -- or 'c> ' in skim interactive mode + query = lines[1]:match(".->%s(.*)") + else + -- 'live_grep' prepends an asterisk to the prompt + -- remove '*' from the start of the line & prompt + query = lines[1]:gsub("^%*+", "") + :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 self.fn_save_query(query) end