Skip to content

Commit f0e830e

Browse files
phanenibhagwan
authored andcommitted
refactor: patch_shell_action -> shell.stringify_data2
1 parent 07326bb commit f0e830e

3 files changed

Lines changed: 54 additions & 46 deletions

File tree

lua/fzf-lua/core.lua

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -957,45 +957,6 @@ M.set_header = function(opts, hdr_tbl)
957957
return opts
958958
end
959959

960-
961-
-- Use both {q} and {+} as field indexes so we can update last query when
962-
-- executing the action, without this we lose the last query on "hide" as
963-
-- the process never terminates and `--print-query` isn't being printed
964-
-- When no entry selected (with {q} {+}), {+} will be forced expand to ''
965-
-- Use {n} to know if we really select an empty string, or there's just no selected
966-
local patch_shell_action = function(v, opts)
967-
local field_index = v.field_index == false and "" or v.field_index or "{+}"
968-
local overide_f_idx
969-
if not field_index:match("^{q} {n}") then
970-
field_index = "{q} {n} " .. field_index
971-
overide_f_idx = true
972-
end
973-
-- replace the action with shell cmd proxy to the original action
974-
return shell.stringify_data(function(items, _, _)
975-
assert(field_index:match("^{q} {n}"))
976-
local query, idx = unpack(items, 1, 2)
977-
config.resume_set("query", query, opts)
978-
if overide_f_idx then
979-
table.remove(items, 1)
980-
table.remove(items, 1)
981-
end
982-
-- fix side effect of "{q} {+}": {+} is forced expanded to ""
983-
-- only when: user didn't set v.field_index (otherwise it can be complex/unpredictable)
984-
-- {n} used to determine if "zero-selected && zero-match", then patch: "" -> nil
985-
if not v.field_index then
986-
-- When no item is matching (empty list or non-matching query)
987-
-- both {n} and {+} are expanded to "".
988-
-- NOTE1: older versions of fzf don't expand {n} to "" (without match)
989-
-- in such case the (empty) items table will be in `items[2]` (#1833)
990-
-- NOTE2: on Windows, no match {n} is expanded to '' (#1836)
991-
local zero_matched = not tonumber(idx)
992-
local zero_selected = #items == 0 or (#items == 1 and #items[1] == 0)
993-
items = (zero_matched and zero_selected) and {} or items
994-
end
995-
v.fn(items, opts)
996-
end, opts, field_index)
997-
end
998-
999960
-- converts actions defined with "reload=true" to use fzf's `reload` bind
1000961
-- provides a better UI experience without a visible interface refresh
1001962
---@param reload_cmd string?
@@ -1057,18 +1018,18 @@ M.convert_reload_actions = function(reload_cmd, opts)
10571018
if type(v) == "table" and v.reload then
10581019
-- Modified actions should not be considered in `actions.expect`
10591020
opts.actions[k]._ignore = true
1060-
local shell_action = patch_shell_action(v, opts)
10611021
if type(v.prefix) == "string" and not v.prefix:match("%+$") then
10621022
v.prefix = v.prefix .. "+"
10631023
end
10641024
if type(v.postfix) == "string" and not v.postfix:match("^%+") then
10651025
v.postfix = "+" .. v.postfix
10661026
end
1027+
local cmd = shell.stringify_data2(v.fn, opts, v.field_index or "{+}")
10671028
opts.keymap.fzf[k] = {
10681029
string.format("%s%sexecute-silent(%s)+reload(%s)%s",
10691030
type(v.prefix) == "string" and v.prefix or "",
10701031
unbind and (unbind .. "+") or "",
1071-
shell_action,
1032+
cmd,
10721033
reload_cmd,
10731034
type(v.postfix) == "string" and v.postfix or ""),
10741035
desc = v.desc or config.get_action_helpstr(v.fn)
@@ -1097,7 +1058,6 @@ M.convert_exec_silent_actions = function(opts)
10971058
assert(type(v.fn) == "function")
10981059
-- Modified actions should not be considered in `actions.expect`
10991060
opts.actions[k]._ignore = true
1100-
local shell_action = patch_shell_action(v, opts)
11011061
if type(v.prefix) == "string" and not v.prefix:match("%+$") then
11021062
v.prefix = v.prefix .. "+"
11031063
end
@@ -1117,13 +1077,14 @@ M.convert_exec_silent_actions = function(opts)
11171077
-- key-action pairs.
11181078
--
11191079
local has_fzf036 = utils.has(opts, "fzf", { 0, 36 })
1080+
local cmd = shell.stringify_data2(v.fn, opts, v.field_index or "{+}")
11201081
opts.keymap.fzf[k] = {
11211082
string.format("%sexecute-silent%s%s",
11221083
type(v.prefix) == "string" and v.prefix or "",
11231084
-- prefer "execute-silent:..." unless we have postfix
11241085
has_fzf036 and type(v.postfix) == "string"
1125-
and string.format("(%s)", shell_action)
1126-
or string.format(":%s", shell_action),
1086+
and string.format("(%s)", cmd)
1087+
or string.format(":%s", cmd),
11271088
-- can't use postfix since we use "execute-silent:..."
11281089
has_fzf036 and type(v.postfix) == "string" and v.postfix or ""),
11291090
desc = v.desc or config.get_action_helpstr(v.fn)

lua/fzf-lua/previewer/builtin.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ end
443443

444444
function Previewer.base:cmdline(_)
445445
local act = shell.stringify_data(function(items, _, _)
446+
---@type string?, string?, string?
446447
local entry, query, idx = unpack(items, 1, 3)
447448
-- NOTE: see comment regarding {n} in `core.convert_exec_silent_actions`
448449
-- convert empty string to nil

lua/fzf-lua/shell.lua

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,9 @@ M.stringify_mt = function(cmd, opts)
306306
end
307307
end
308308

309+
---Fzf field index expression, e.g. "{+}" (selected), "{q}" (query)
309310
---@param contents table|function|string
310311
---@param opts {}
311-
---Fzf field index expression, e.g. "{+}" (selected), "{q}" (query)
312312
---@param fzf_field_index string?
313313
---@return string?, integer?
314314
M.stringify = function(contents, opts, fzf_field_index)
@@ -498,7 +498,7 @@ M.stringify = function(contents, opts, fzf_field_index)
498498
return cmd, id
499499
end
500500

501-
---@param fn fun(item: string[], fzf_lines: integer, fzf_columns, integer): string|string[]?
501+
---@param fn fun(items: string[], fzf_lines: integer, fzf_columns: integer): string|{ cmd: string|string[], env: table? }?
502502
---@param opts table
503503
---@param fzf_field_index string?
504504
---@return string, integer?
@@ -511,6 +511,10 @@ M.stringify_cmd = function(fn, opts, fzf_field_index)
511511
}, fzf_field_index)
512512
end
513513

514+
---@param fn fun(items: string[], fzf_lines: integer, fzf_columns: integer): string|string[]?
515+
---@param opts table
516+
---@param fzf_field_index string?
517+
---@return string, integer?
514518
M.stringify_data = function(fn, opts, fzf_field_index)
515519
assert(type(fn) == "function", "fn must be of type function")
516520
return M.stringify(function(cb, _, ...)
@@ -526,4 +530,46 @@ M.stringify_data = function(fn, opts, fzf_field_index)
526530
end, { debug = opts.debug }, fzf_field_index)
527531
end
528532

533+
-- Patched version of stringify_data
534+
-- Use both {q} and {+} as field indexes so we can update last query when
535+
-- executing the action, without this we lose the last query on "hide" as
536+
-- the process never terminates and `--print-query` isn't being printed
537+
-- When no entry selected (with {q} {+}), {+} will be forced expand to ''
538+
-- Use {n} to know if we really select an empty string, or there's just no selected
539+
---@param fn fun(items: string[], opts: table): string|string[]?
540+
---@param opts table
541+
---@param field_index string
542+
---@return string
543+
M.stringify_data2 = function(fn, opts, field_index)
544+
local field_index0 = field_index
545+
local did_override = false
546+
if not field_index:match("{q} {n}$") then
547+
field_index = field_index .. " {q} {n}"
548+
did_override = true
549+
end
550+
-- replace the action with shell cmd proxy to the original action
551+
return M.stringify_data(function(items, _, _)
552+
local query, idx = items[#items - 1], items[#items]
553+
FzfLua.config.resume_set("query", query, opts)
554+
if did_override then
555+
table.remove(items)
556+
table.remove(items)
557+
end
558+
-- fix side effect of "{q} {+}": {+} is forced expanded to ""
559+
-- only when field_index is empty (otherwise it can be complex/unpredictable)
560+
-- {n} used to determine if "zero-selected && zero-match", then patch: "" -> nil
561+
if #field_index0 == 0 then
562+
-- When no item is matching (empty list or non-matching query)
563+
-- both {n} and {+} are expanded to "".
564+
-- NOTE1: older versions of fzf don't expand {n} to "" (without match)
565+
-- in such case the (empty) items table will be in `items[2]` (#1833)
566+
-- NOTE2: on Windows, no match {n} is expanded to '' (#1836)
567+
local zero_matched = not tonumber(idx)
568+
local zero_selected = #items == 0 or (#items == 1 and #items[1] == 0)
569+
items = (zero_matched and zero_selected) and {} or items
570+
end
571+
fn(items, opts)
572+
end, opts, field_index)
573+
end
574+
529575
return M

0 commit comments

Comments
 (0)