diff --git a/lua/fzf-lua/actions.lua b/lua/fzf-lua/actions.lua index 3c6e1612..68eddf9a 100644 --- a/lua/fzf-lua/actions.lua +++ b/lua/fzf-lua/actions.lua @@ -8,18 +8,29 @@ local M = {} local _default_action = "default" -- return fzf '--expect=' string from actions keyval tbl -M.expect = function(actions) +-- on fzf >= 0.53 add the `prefix` key to the bind flags +M.expect = function(actions, _) if not actions then return nil end local keys = {} + local binds = {} for k, v in pairs(actions) do - if k ~= _default_action and v ~= false then + local is_default = k == _default_action + if not is_default and v ~= false then table.insert(keys, k) end + -- Although this only works in fzf 0.53 we don't need to limit the use of these + -- actions as `--expect` precets the bind and thus the extra bind has no effect + if type(v) == "table" and type(v.prefix) == "string" then + table.insert(binds, string.format("%s:%s%s", + is_default and "enter" or k, + -- When used with `--expect` "accept" is implied and "+" is erroneous + v.prefix:gsub("accept$", ""):gsub("%+$", ""), + -- Since default accept bind (enter) is excluded from `--expect` + -- we need to add "+accept" to complete the selection and exit fzf + is_default and "+accept" or "")) + end end - if #keys > 0 then - return table.concat(keys, ",") - end - return nil + return #keys > 0 and keys or nil, #binds > 0 and binds or nil end M.normalize_selected = function(actions, selected) diff --git a/lua/fzf-lua/core.lua b/lua/fzf-lua/core.lua index 8f9b66d4..f26ee66d 100644 --- a/lua/fzf-lua/core.lua +++ b/lua/fzf-lua/core.lua @@ -592,7 +592,22 @@ M.build_fzf_cli = function(opts) end opts.fzf_opts["--bind"] = M.create_fzf_binds(opts.keymap.fzf) opts.fzf_opts["--color"] = M.create_fzf_colors(opts) - opts.fzf_opts["--expect"] = actions.expect(opts.actions) + do + -- `actions.expect` parses the actions table and returns a list of + -- keys that trigger completion (accept) to be added to `--expect` + -- If the action contains the prefix key, e.g. `{ fn = ... , prefix = "select-all" }` + -- additional binds will be set for the specific action key + -- NOTE: requires fzf >= 0.53 (https://github.com/junegunn/fzf/issues/3810) + local expect_keys, expect_binds = actions.expect(opts.actions, opts) + if expect_keys and #expect_keys > 0 then + opts.fzf_opts["--expect"] = table.concat(expect_keys, ",") + end + if expect_binds and #expect_binds > 0 then + local bind = opts.fzf_opts["--bind"] + opts.fzf_opts["--bind"] = string.format("%s%s%s", + bind, bind and "," or "", table.concat(expect_binds, ",")) + end + end if opts.fzf_opts["--preview-window"] == nil then opts.fzf_opts["--preview-window"] = M.preview_window(opts) end @@ -878,7 +893,9 @@ M.set_header = function(opts, hdr_tbl) if type(opts.regex_filter) == "string" then return opts.regex_filter elseif type(opts.regex_filter) == "table" and type(opts.regex_filter[1]) == "string" then - return string.format("%s%s", opts.regex_filter.exclude and "not " or "", opts.regex_filter[1]) + return string.format("%s%s", + opts.regex_filter.exclude and "not " or "", + opts.regex_filter[1]) elseif type(opts.regex_filter) == "function" then return "" end