From eb3d2d121f480471a9571b6d9138b4c49a5ed3e0 Mon Sep 17 00:00:00 2001 From: bhagwan Date: Tue, 17 May 2022 20:13:35 -0700 Subject: [PATCH] nvim 0.8 compatibility: refactor preview shell command (closes #409) --- lua/fzf-lua/core.lua | 2 +- lua/fzf-lua/previewer/builtin.lua | 2 +- lua/fzf-lua/previewer/fzf.lua | 28 ++++----- lua/fzf-lua/providers/colorschemes.lua | 2 +- lua/fzf-lua/providers/git.lua | 2 +- lua/fzf-lua/providers/module.lua | 2 +- lua/fzf-lua/providers/nvim.lua | 6 +- lua/fzf-lua/shell.lua | 37 ++++++------ lua/fzf-lua/shell_helper.lua | 82 +++++++++++++++----------- 9 files changed, 90 insertions(+), 73 deletions(-) diff --git a/lua/fzf-lua/core.lua b/lua/fzf-lua/core.lua index 7306d72..4193b52 100644 --- a/lua/fzf-lua/core.lua +++ b/lua/fzf-lua/core.lua @@ -592,7 +592,7 @@ M.set_fzf_interactive_cb = function(opts) close_pipe() end)() - end, placeholder) + end, placeholder, opts.debug) return M.set_fzf_interactive(opts, raw_async_act, placeholder) end diff --git a/lua/fzf-lua/previewer/builtin.lua b/lua/fzf-lua/previewer/builtin.lua index 05270a9..d80b203 100644 --- a/lua/fzf-lua/previewer/builtin.lua +++ b/lua/fzf-lua/previewer/builtin.lua @@ -206,7 +206,7 @@ function Previewer.base:action(_) local act = shell.raw_action(function (items, _, _) self:display_entry(items[1]) return "" - end, "{}") + end, "{}", self.opts.debug) return act end diff --git a/lua/fzf-lua/previewer/fzf.lua b/lua/fzf-lua/previewer/fzf.lua index e77a449..18999ff 100644 --- a/lua/fzf-lua/previewer/fzf.lua +++ b/lua/fzf-lua/previewer/fzf.lua @@ -1,4 +1,5 @@ local path = require "fzf-lua.path" +local libuv = require "fzf-lua.libuv" local shell = require "fzf-lua.shell" local utils = require "fzf-lua.utils" local Object = require "fzf-lua.class" @@ -65,11 +66,15 @@ function Previewer.cmd:new(o, opts) return self end +function Previewer.cmd:sh_wrap(cmd, args, action, extra_args) + return "sh -c " .. libuv.shellescape(("%s %s %s `%s`"):format( + cmd, args or "", extra_args or "", action)) +end + function Previewer.cmd:cmdline(o) o = o or {} o.action = o.action or self:action(o) - return vim.fn.shellescape(string.format('sh -c "%s %s `%s`"', - self.cmd, self.args, o.action)) + return vim.fn.shellescape(self:sh_wrap(self.cmd, self.args, o.action)) end function Previewer.cmd:action(o) @@ -78,7 +83,7 @@ function Previewer.cmd:action(o) -- only preview first item local entry = path.entry_to_file(items[1], self.opts) return entry.bufname or entry.path - end, self.opts.field_index_expr or "{}") + end, self.opts.field_index_expr or "{}", self.opts.debug) return act end @@ -98,8 +103,7 @@ function Previewer.bat:cmdline(o) if self.opts.line_field_index then highlight_line = string.format("--highlight-line={%d}", self.opts.line_field_index) end - return vim.fn.shellescape(string.format('sh -c "%s %s %s `%s`"', - self.cmd, self.args, highlight_line, self:action(o))) + return vim.fn.shellescape(self:sh_wrap(self.cmd, self.args, o.action, highlight_line)) end -- Specialized head previewer @@ -118,8 +122,7 @@ function Previewer.head:cmdline(o) -- if self.opts.line_field_index then -- lines = string.format("--lines={%d}", self.opts.line_field_index) -- end - return vim.fn.shellescape(string.format('sh -c "%s %s %s `%s`"', - self.cmd, self.args, lines, self:action(o))) + return vim.fn.shellescape(self:sh_wrap(self.cmd, self.args, o.action, lines)) end -- new async_action from nvim-fzf @@ -197,7 +200,7 @@ function Previewer.cmd_async:cmdline(o) -- uncomment to see the command in the preview window -- cmd = vim.fn.shellescape(cmd) return cmd - end, "{}") + end, "{}", self.opts.debug) return act end @@ -231,7 +234,7 @@ function Previewer.bat_async:cmdline(o) -- uncomment to see the command in the preview window -- cmd = vim.fn.shellescape(cmd) return cmd - end, "{}") + end, "{}", self.opts.debug) return act end @@ -299,16 +302,13 @@ function Previewer.git_diff:cmdline(o) cmd = ("FZF_PREVIEW_LINES=%d;FZF_PREVIEW_COLUMNS=%d;%s %s") :format(fzf_lines, fzf_columns, cmd, pager) cmd = 'sh -c ' .. vim.fn.shellescape(cmd) - if self.opts.debug then - print("[DEBUG]: "..cmd.."\n") - end -- uncomment to see the command in the preview window -- cmd = vim.fn.shellescape(cmd) return cmd -- we need to add '--' to mark the end of command options -- as git icon customization may contain special shell chars -- which will otherwise choke our preview cmd ('+', '-', etc) - end, "-- {}") + end, "-- {}", self.opts.debug) return act end @@ -330,7 +330,7 @@ function Previewer.man_pages:cmdline(o) -- uncomment to see the command in the preview window -- cmd = vim.fn.shellescape(cmd) return cmd - end, "{}") + end, "{}", self.opts.debug) return act end diff --git a/lua/fzf-lua/providers/colorschemes.lua b/lua/fzf-lua/providers/colorschemes.lua index c1786e1..b55d4c8 100644 --- a/lua/fzf-lua/providers/colorschemes.lua +++ b/lua/fzf-lua/providers/colorschemes.lua @@ -24,7 +24,7 @@ M.colorschemes = function(opts) local colorscheme = args[1] vim.cmd("colorscheme " .. colorscheme) end - end) + end, nil, opts.debug) local current_colorscheme = get_current_colorscheme() local current_background = vim.o.background diff --git a/lua/fzf-lua/providers/git.lua b/lua/fzf-lua/providers/git.lua index 5610e56..9f1f25e 100644 --- a/lua/fzf-lua/providers/git.lua +++ b/lua/fzf-lua/providers/git.lua @@ -132,7 +132,7 @@ M.branches = function(opts) end return opts._preview:gsub("{.*}", branch) -- return "echo " .. branch - end) + end, nil, opts.debug) return git_cmd(opts) end diff --git a/lua/fzf-lua/providers/module.lua b/lua/fzf-lua/providers/module.lua index 62e5bf0..de9d45f 100644 --- a/lua/fzf-lua/providers/module.lua +++ b/lua/fzf-lua/providers/module.lua @@ -16,7 +16,7 @@ M.metatable = function(opts) -- TODO: retreive method help local help = '' return string.format("%s:%s", args[1], help) - end) + end, nil, opts.debug) local methods = {} for k, _ in pairs(opts.metatable) do diff --git a/lua/fzf-lua/providers/nvim.lua b/lua/fzf-lua/providers/nvim.lua index 43575a4..2645c65 100644 --- a/lua/fzf-lua/providers/nvim.lua +++ b/lua/fzf-lua/providers/nvim.lua @@ -20,7 +20,7 @@ M.commands = function(opts) cmd = vim.inspect(commands[cmd]) end return cmd - end) + end, nil, opts.debug) local entries = {} for k, _ in pairs(commands) do @@ -259,7 +259,7 @@ M.registers = function(opts) local r = args[1]:match("%[(.*)%] ") local _, contents = pcall(vim.fn.getreg, r) return contents and register_escape_special(contents) or args[1] - end) + end, nil, opts.debug) local entries = {} for _, r in ipairs(registers) do @@ -324,7 +324,7 @@ M.keymaps = function(opts) k = vim.inspect(v) end return k - end) + end, nil, opts.debug) local entries = {} for _, v in pairs(keymaps) do diff --git a/lua/fzf-lua/shell.lua b/lua/fzf-lua/shell.lua index dd46ff9..2917d5e 100644 --- a/lua/fzf-lua/shell.lua +++ b/lua/fzf-lua/shell.lua @@ -27,7 +27,7 @@ end -- NOT USED ANYMORE, we use `vim.g.fzf_lua_server` instead -- local action_server_address = nil -function M.raw_async_action(fn, fzf_field_expression) +function M.raw_async_action(fn, fzf_field_expression, debug) if not fzf_field_expression then fzf_field_expression = "{+}" @@ -47,23 +47,26 @@ function M.raw_async_action(fn, fzf_field_expression) -- this is for windows WSL and AppImage users, their nvim path isn't just -- 'nvim', it can be something else - local nvim_command = vim.v.argv[1] + local nvim_bin = vim.v.argv[1] - local action_string = string.format("%s -n --headless --clean --cmd %s %s %s %s", - vim.fn.shellescape(nvim_command), - vim.fn.shellescape("luafile " .. path.join{vim.g.fzf_lua_directory, "shell_helper.lua"}), - vim.fn.shellescape(vim.g.fzf_lua_server), - id, + local call_args = ("fzf_lua_server=[[%s]], fnc_id=%d %s"):format( + vim.g.fzf_lua_server, id, debug and ", debug=true" or "") + + local action_cmd = ("%s -n --headless --clean --cmd %s %s"):format( + libuv.shellescape(nvim_bin), + libuv.shellescape(("lua loadfile([[%s]])().rpc_nvim_exec_lua({%s})") + :format(path.join{vim.g.fzf_lua_directory, "shell_helper.lua"}, call_args)), fzf_field_expression) - return action_string, id + + return action_cmd, id end -function M.async_action(fn, fzf_field_expression) - local action_string, id = M.raw_async_action(fn, fzf_field_expression) +function M.async_action(fn, fzf_field_expression, debug) + local action_string, id = M.raw_async_action(fn, fzf_field_expression, debug) return vim.fn.shellescape(action_string), id end -function M.raw_action(fn, fzf_field_expression) +function M.raw_action(fn, fzf_field_expression, debug) local receiving_function = function(pipe, ...) local ret = fn(...) @@ -90,15 +93,15 @@ function M.raw_action(fn, fzf_field_expression) end end - return M.raw_async_action(receiving_function, fzf_field_expression) + return M.raw_async_action(receiving_function, fzf_field_expression, debug) end -function M.action(fn, fzf_field_expression) - local action_string, id = M.raw_action(fn, fzf_field_expression) +function M.action(fn, fzf_field_expression ,debug) + local action_string, id = M.raw_action(fn, fzf_field_expression, debug) return vim.fn.shellescape(action_string), id end -M.preview_action_cmd = function(fn, fzf_field_expression) +M.preview_action_cmd = function(fn, fzf_field_expression, debug) return M.async_action(function(pipe, ...) @@ -123,7 +126,7 @@ M.preview_action_cmd = function(fn, fzf_field_expression) cb_write = on_write, }, false) - end, fzf_field_expression) + end, fzf_field_expression, debug) end M.reload_action_cmd = function(opts, fzf_field_expression) @@ -168,7 +171,7 @@ M.reload_action_cmd = function(opts, fzf_field_expression) -- which will conflict with the 'fn_transform' argument }, opts._fn_transform or false) - end, fzf_field_expression) + end, fzf_field_expression, opts.debug) end return M diff --git a/lua/fzf-lua/shell_helper.lua b/lua/fzf-lua/shell_helper.lua index a633097..478965d 100644 --- a/lua/fzf-lua/shell_helper.lua +++ b/lua/fzf-lua/shell_helper.lua @@ -30,40 +30,54 @@ uv.listen(preview_socket, 100, function(_) end) -local function_id = tonumber(vim.fn.argv(1)) -local success, errmsg = pcall(function () - local nargs = vim.fn.argc() - local args = {} - -- this is guaranteed to be 2 or more, we are interested in those greater than 2 - for i=3,nargs do - -- vim uses zero indexing - table.insert(args, vim.fn.argv(i - 1)) +local function rpc_nvim_exec_lua(opts) + local success, errmsg = pcall(function () + -- fzf selection is unpacked as the argument list + local fzf_selection = {} + for i=1,vim.fn.argc() do + table.insert(fzf_selection, vim.fn.argv(i-1)) + end + -- for skim compatibility + local preview_lines = vim.env.FZF_PREVIEW_LINES or vim.env.LINES + local preview_cols = vim.env.FZF_PREVIEW_COLUMNS or vim.env.COLUMNS + local chan_id = vim.fn.sockconnect("pipe", opts.fzf_lua_server, { rpc = true }) + vim.rpcrequest(chan_id, "nvim_exec_lua", [[ + local luaargs = {...} + local function_id = luaargs[1] + local preview_socket_path = luaargs[2] + local fzf_selection = luaargs[3] + local fzf_lines = luaargs[4] + local fzf_columns = luaargs[5] + local usr_func = require"fzf-lua.shell".get_func(function_id) + return usr_func(preview_socket_path, fzf_selection, fzf_lines, fzf_columns) + ]], { + opts.fnc_id, + preview_socket_path, + fzf_selection, + tonumber(preview_lines), + tonumber(preview_cols) + }) + vim.fn.chanclose(chan_id) + end) + + if not success or opts.debug then + io.stderr:write(("[DEBUG]\tdebug = %s\n"):format(opts.debug)) + io.stderr:write(("[DEBUG]\tfunction ID = %d\n"):format(opts.fnc_id)) + io.stderr:write(("[DEBUG]\tfzf_lua_server = %s\n"):format(opts.fzf_lua_server)) + for i=1,#vim.v.argv do + io.stderr:write(("[DEBUG]\targv[%d] = %s\n"):format(i, vim.v.argv[i])) + end + for i=1,vim.fn.argc() do + io.stderr:write(("[DEBUG]\targ[%d] = %s\n"):format(i, vim.fn.argv(i-1))) + end end - local environ = vim.fn.environ() - local chan_id = vim.fn.sockconnect("pipe", vim.fn.argv(0), { rpc = true }) - -- for skim compatibility - local preview_lines = environ.FZF_PREVIEW_LINES or environ.LINES - local preview_cols = environ.FZF_PREVIEW_COLUMNS or environ.COLUMNS - vim.rpcrequest(chan_id, "nvim_exec_lua", [[ - local luaargs = {...} - local function_id = luaargs[1] - local preview_socket_path = luaargs[2] - local fzf_selection = luaargs[3] - local fzf_lines = luaargs[4] - local fzf_columns = luaargs[5] - local usr_func = require"fzf-lua.shell".get_func(function_id) - return usr_func(preview_socket_path, fzf_selection, fzf_lines, fzf_columns) - ]], { - function_id, - preview_socket_path, - args, - tonumber(preview_lines), - tonumber(preview_cols) - }) - vim.fn.chanclose(chan_id) -end) -if not success then - io.stderr:write("FzfLua Error:\n\n" .. errmsg .. "\n") - vim.cmd [[qall]] + if not success then + io.stderr:write(("FzfLua Error: %s\n"):format(errmsg or "")) + vim.cmd [[qall]] + end end + +return { + rpc_nvim_exec_lua = rpc_nvim_exec_lua +}