diff --git a/lua/fff/main.lua b/lua/fff/main.lua index f8d48945..1418a2d7 100644 --- a/lua/fff/main.lua +++ b/lua/fff/main.lua @@ -8,7 +8,9 @@ function M.setup(config) vim.g.fff = config end --- Find files in current directory. --- When opts.resume is true, resumes the last find_files picker (or opens a new one if none saved). ---- @param opts? table Optional configuration {renderer = custom_renderer, resume = boolean} +--- When opts.on_submit is set, it replaces the default `:edit` action on user selection. +--- Signature: `fun(item: table, ctx: { action: string, path: string, relative_path: string, location: table|nil, query: string, mode: string|nil })`. +--- @param opts? table Optional configuration {renderer = custom_renderer, resume = boolean, on_submit = function} function M.find_files(opts) local picker_ok, picker_ui = pcall(require, 'fff.picker_ui.picker_ui') if not picker_ok then diff --git a/lua/fff/picker_ui/picker_ui.lua b/lua/fff/picker_ui/picker_ui.lua index bf01dc26..c8d72831 100644 --- a/lua/fff/picker_ui/picker_ui.lua +++ b/lua/fff/picker_ui/picker_ui.lua @@ -483,38 +483,52 @@ function M.select(action) vim.cmd('stopinsert') M.close() + local on_submit = config and config.on_submit + -- Defer file open past picker float teardown. Without this, foldexpr is not -- recomputed on the new window (folds appear missing) on some platforms. vim.schedule(function() - if config and config.select and type(config.select.select_window) == 'function' then - local ok, win = pcall(config.select.select_window, vim.api.nvim_get_current_buf(), action) - if not ok then - vim.notify('FFF: select.select_window error: ' .. tostring(win), vim.log.levels.WARN) - elseif type(win) == 'number' and vim.api.nvim_win_is_valid(win) then - vim.api.nvim_set_current_win(win) + if type(on_submit) == 'function' then + local ok, err = pcall(on_submit, item, { + action = action, + path = abs_path, + relative_path = relative_path, + location = location, + query = query, + mode = mode, + }) + if not ok then vim.notify('FFF: on_submit error: ' .. tostring(err), vim.log.levels.ERROR) end + else + if config and config.select and type(config.select.select_window) == 'function' then + local ok, win = pcall(config.select.select_window, vim.api.nvim_get_current_buf(), action) + if not ok then + vim.notify('FFF: select.select_window error: ' .. tostring(win), vim.log.levels.WARN) + elseif type(win) == 'number' and vim.api.nvim_win_is_valid(win) then + vim.api.nvim_set_current_win(win) + end end - end - if action == 'edit' then - -- Hard guard against E1513 ("Cannot switch buffer. 'winfixbuf' is enabled"): - -- if the (post-hook) current window is pinned, fall back to :split. - local opened_via_split = false - if window_has_winfixbuf(vim.api.nvim_get_current_win()) then + if action == 'edit' then + -- Hard guard against E1513 ("Cannot switch buffer. 'winfixbuf' is enabled"): + -- if the (post-hook) current window is pinned, fall back to :split. + local opened_via_split = false + if window_has_winfixbuf(vim.api.nvim_get_current_win()) then + vim.cmd('split ' .. vim.fn.fnameescape(relative_path)) + opened_via_split = true + end + + if not opened_via_split then vim.cmd('edit ' .. vim.fn.fnameescape(relative_path)) end + elseif action == 'split' then vim.cmd('split ' .. vim.fn.fnameescape(relative_path)) - opened_via_split = true + elseif action == 'vsplit' then + vim.cmd('vsplit ' .. vim.fn.fnameescape(relative_path)) + elseif action == 'tab' then + vim.cmd('tabedit ' .. vim.fn.fnameescape(relative_path)) end - if not opened_via_split then vim.cmd('edit ' .. vim.fn.fnameescape(relative_path)) end - elseif action == 'split' then - vim.cmd('split ' .. vim.fn.fnameescape(relative_path)) - elseif action == 'vsplit' then - vim.cmd('vsplit ' .. vim.fn.fnameescape(relative_path)) - elseif action == 'tab' then - vim.cmd('tabedit ' .. vim.fn.fnameescape(relative_path)) + if location then location_utils.jump_to_location(location) end end - if location then location_utils.jump_to_location(location) end - if query and query ~= '' then local cfg = config or conf.get() if cfg.history and cfg.history.enabled then