@ 261105.2

251129.19 · 18fe1aa95a5c9da55ac99620cf4ed8a1653c35e3

chore!: fix nil check, param mismatch

reading declarations

.emmyrc.json

@@ -11,8 +11,6 @@     "enable": true,     "disable": [       "unnecessary-if",-      "param-type-not-match",-      "need-check-nil",       "await-in-sync",       "global-in-non-module"     ]

.luarc.jsonc

@@ -29,6 +29,7 @@       "different-requires",       "unknown-diag-code",       "unknown-cast-variable",+      "luadoc-miss-local-name",     ],     "unusedLocalExclude": ["_*"],   },@@ -47,6 +48,9 @@     "checkThirdParty": false,     "maxPreload": 2000,     "preloadFileSize": 1000,+    "ignoreDir": [+      "lua/fzf-lua/actions.lua"+    ],   },   "type": {     "weakNilCheck": true,

README.md

@@ -48,7 +48,9 @@ Using [lazy.nvim](https://github.com/folke/lazy.nvim)   -- dependencies = { "nvim-mini/mini.icons" },   ---@module "fzf-lua"   ---@type fzf-lua.Config|{}+  ---@diagnostics disable: missing-fields   opts = {}+  ---@diagnostics enable: missing-fields } ``` 

lua/fzf-lua/actions.lua

@@ -1,14 +1,21 @@+---@diagnostic disable: need-check-nil ---@diagnostic disable-next-line: deprecated local uv = vim.uv or vim.loop local utils = require "fzf-lua.utils" local path = require "fzf-lua.path" local libuv = require "fzf-lua.libuv" +---@class fzf-lua.actions+---@field expect fun(actions: table, opts: fzf-lua.config.Resolved|{}):string[]?, string[]?+---@field [string] fun(items: string[], opts: fzf-lua.config.Resolved|{}):any local M = {}  -- return fzf '--expect=' string from actions keyval tbl -- on fzf >= 0.53 add the `prefix` key to the bind flags -- https://github.com/junegunn/fzf/issues/3829#issuecomment-2143235993+---@param actions table+---@param opts table+---@return string[]?, string[]? M.expect = function(actions, opts)   if not actions then return nil end   local expect = {}@@ -54,12 +61,15 @@ M.expect = function(actions, opts)   return #expect > 0 and expect or nil, #binds > 0 and binds or nil end +---@param selected string[]+---@param opts fzf-lua.config.Resolved|{}+---@return string?, string[]? M.normalize_selected = function(selected, opts)   -- The below separates the keybind from the item(s)   -- and makes sure 'selected' contains only item(s) or {}   -- so it can always be enumerated safely   if not selected then return end-  local actions = opts.actions+  local actions = assert(opts.actions)   -- Backward compat, "default" action trumps "enter"   if actions.default then actions.enter = actions.default end   if utils.has(opts, "fzf", { 0, 53 }) or utils.has(opts, "sk", { 0, 14 }) then@@ -102,7 +112,7 @@ M.act = function(selected, opts)   local actions = opts.actions   local keybind, entries = M.normalize_selected(selected, opts)   -- fzf >= 0.53 and `--exit-0`-  if not keybind then return end+  if not keybind or not entries then return end   local action = actions[keybind]   -- Backward compat, was action defined as "default"   if not action and keybind == "enter" then@@ -121,7 +131,7 @@ M.act = function(selected, opts)     end   elseif type(action) == "function" then     action(entries, opts)-  elseif type(action) == "string" then+  elseif type(action) == "string" then ---@cast action string     vim.cmd(action)   else     utils.warn(("unsupported action: '%s', type:%s"):format(keybind, type(action)))@@ -152,7 +162,7 @@ local edit_entry = function(entry, fullpath, will_replace_curbuf, opts)     -- We normalize the path or Windows will fail with directories starting     -- with special characters, for example "C:\app\(web)" will be translated     -- by neovim to "c:\app(web)" (#1082)-    local relpath = path.normalize(path.relative_to(fullpath, uv.cwd()))+    local relpath = path.normalize(path.relative_to(fullpath, utils.cwd()))     local bufnr0 = vim.fn.bufadd(relpath)     if bufnr0 == 0 and not opts.silent then       utils.warn("Unable to add buffer %s", relpath)@@ -187,7 +197,7 @@ end  ---@param vimcmd string ---@param selected string[]----@param opts fzf-lua.Config+---@param opts fzf-lua.config.Resolved|{} ---@param bufedit boolean? ---@return string? M.vimcmd_entry = function(vimcmd, selected, opts, bufedit)@@ -205,7 +215,7 @@ M.vimcmd_entry = function(vimcmd, selected, opts, bufedit)       if not path.is_absolute(fullpath) then         -- cwd priority is first user supplied, then original call cwd         -- technically we should never get to the `uv.cwd()` fallback-        fullpath = path.join({ opts.cwd or opts._cwd or uv.cwd(), fullpath })+        fullpath = path.join({ opts.cwd or opts._cwd or utils.cwd(), fullpath })       end       -- Can't be called from term window (for example, "reload" actions) due to       -- nvim_exec2(): Vim(normal):Can't re-enter normal mode from terminal mode@@ -243,7 +253,7 @@ M.vimcmd_entry = function(vimcmd, selected, opts, bufedit)           return         end       else-        local relpath = path.normalize(path.relative_to(fullpath, uv.cwd()))+        local relpath = path.normalize(path.relative_to(fullpath, utils.cwd()))         vim.cmd(("%s %s"):format(vimcmd, relpath))       end       -- Reload actions from fzf's (buf/arg del, etc) window end here@@ -263,10 +273,8 @@ M.vimcmd_entry = function(vimcmd, selected, opts, bufedit)       elseif not opts.no_action_set_cursor and entry.line > 0 or entry.col > 0 then         -- Make sure we have valid line/column         -- e.g. qf lists from files (no line/col), dap_breakpoints-        pcall(vim.api.nvim_win_set_cursor, 0, {-          math.max(1, entry.line),-          math.max(1, entry.col) - 1-        })+        ---@diagnostic disable-next-line: param-type-mismatch+        pcall(vim.api.nvim_win_set_cursor, 0, { math.max(1, entry.line), math.max(1, entry.col) - 1 })       end       -- Only "zz" after the last entry is loaded into the origin buffer       if i == #selected and not opts.no_action_zz and not utils.is_term_buffer(0) then@@ -302,7 +310,7 @@ local sel_to_qf = function(selected, opts, is_loclist)   local qf_list = {}   for i = 1, #selected do     local file = path.entry_to_file(selected[i], opts)-    local text = file.stripped:match(":%d+:%d?%d?%d?%d?:?(.*)$")+    local text = assert(file.stripped):match(":%d+:%d?%d?%d?%d?:?(.*)$")     table.insert(qf_list, {       bufnr = file.bufnr,       filename = file.bufname or file.path or file.uri,@@ -355,7 +363,7 @@ local sel_to_qf = function(selected, opts, is_loclist) end  M.list_del = function(selected, opts)-  local winid = opts.__CTX.winid+  local winid = assert(opts.__CTX.winid)   local list = opts.is_loclist and vim.fn.getloclist(winid) or vim.fn.getqflist()    local buf_del = (function()@@ -400,9 +408,9 @@ end M.file_switch = function(selected, opts)   if not selected[1] then return false end   -- If called from `:FzfLua tabs` switch to requested tab/win-  local tabh, winid = selected[1]:match("(%d+)\t(%d+)%)")-  tabh = utils.tointeger(tabh)-  winid = utils.tointeger(winid)+  local tabh0, winid0 = selected[1]:match("(%d+)\t(%d+)%)")+  local tabh = utils.tointeger(tabh0)+  local winid = utils.tointeger(winid0)   if tabh and winid then     vim.api.nvim_set_current_tabpage(tabh)     vim.api.nvim_set_current_win(winid)@@ -411,9 +419,9 @@ M.file_switch = function(selected, opts)   local entry = path.entry_to_file(selected[1], opts)   if not entry.bufnr then     -- Search for the current entry's filepath in buffer list-    local fullpath = entry.path+    local fullpath = assert(entry.path)     if not path.is_absolute(fullpath) then-      fullpath = path.join({ opts.cwd or uv.cwd(), fullpath })+      fullpath = path.join({ opts.cwd or utils.cwd(), fullpath })     end     for _, b in ipairs(vim.api.nvim_list_bufs()) do       local bname = vim.api.nvim_buf_get_name(b)@@ -429,11 +437,8 @@ M.file_switch = function(selected, opts)   winid = utils.winid_from_tabh(0, entry.bufnr)   if not winid then return false end   vim.api.nvim_set_current_win(winid)-  if entry.line > 0 or entry.col > 0 then-    pcall(vim.api.nvim_win_set_cursor, 0, {-      math.max(1, entry.line),-      math.max(1, entry.col) - 1-    })+  if entry.line > 0 or entry.col > 0 then ---@diagnostic disable-next-line: param-type-mismatch+    pcall(vim.api.nvim_win_set_cursor, 0, { math.max(1, entry.line), math.max(1, entry.col) - 1 })   end   if not utils.is_term_buffer(0) and not opts.no_action_zz then vim.cmd("norm! zvzz") end   return true@@ -478,7 +483,7 @@ local function arg_exec(cmd, selected, opts)       assert(relpath, "entry doesn't contain filepath")       if not relpath then return end       if path.is_absolute(relpath) then-        relpath = path.relative_to(relpath, vim.uv.cwd())+        relpath = path.relative_to(relpath, utils.cwd())       end       vim.cmd(cmd .. " " .. string.gsub(relpath, " ", [[\ ]]))     end)()@@ -496,7 +501,7 @@ M.arg_del = function(selected, opts) end  M.colorscheme = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local dbkey, idx = selected[1]:match("^(.-):(%d+):")   if dbkey then     opts._apply_awesome_theme(dbkey, idx, opts)@@ -506,6 +511,8 @@ M.colorscheme = function(selected, opts)   end end +---@param selected string[]+---@param opts fzf-lua.config.AwesomeColorschemes|{} M.cs_delete = function(selected, opts)   for _, s in ipairs(selected) do     local dbkey = s:match("^(.-):%d+:")@@ -513,6 +520,8 @@ M.cs_delete = function(selected, opts)   end end +---@param selected string[]+---@param opts fzf-lua.config.AwesomeColorschemes|{} M.cs_update = function(selected, opts)   local dedup = {}   for _, s in ipairs(selected) do@@ -531,20 +540,20 @@ M.toggle_bg = function(_, _) end  M.hi = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local hl = selected[1]:match("^[^%s]+")   vim.cmd("hi " .. hl)   vim.cmd("echo") end  M.run_builtin = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local method = selected[1]   pcall(require "fzf-lua"[method]) end  M.ex_run = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local cmd = selected[1]   vim.cmd("stopinsert")   vim.fn.feedkeys(string.format(":%s", cmd), "nt")@@ -552,21 +561,21 @@ M.ex_run = function(selected) end  M.ex_run_cr = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local cmd = selected[1]   vim.cmd(cmd)   vim.fn.histadd("cmd", cmd) end  M.exec_menu = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local cmd = selected[1]   vim.cmd("emenu " .. cmd) end   M.search = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local query = selected[1]   vim.cmd("stopinsert")   vim.fn.feedkeys(@@ -580,9 +589,9 @@ M.search_cr = function(selected, opts) end  M.goto_mark = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local mark = selected[1]-  mark = mark:match("[^ ]+")+  mark = assert(mark:match("[^ ]+"))   vim.cmd("stopinsert")   vim.cmd("normal! `" .. mark)   -- vim.fn.feedkeys(string.format("'%s", mark))@@ -608,7 +617,7 @@ M.mark_del = function(selected)   local buf = utils.CTX().bufnr   vim.api.nvim_win_call(win, function()     vim.tbl_map(function(s)-      local mark = s:match "[^ ]+"+      local mark = assert(s:match("[^ ]+"))       local ok, res = pcall(vim.api.nvim_buf_del_mark, buf, mark)       if ok and res then return end       return vim.cmd.delm(mark)@@ -617,7 +626,7 @@ M.mark_del = function(selected) end  M.goto_jump = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   if opts.jump_using_norm then     local jump, _, _, _ = selected[1]:match("(%d+)%s+(%d+)%s+(%d+)%s+(.*)")     if tonumber(jump) then@@ -642,14 +651,17 @@ M.goto_jump = function(selected, opts) end  M.keymap_apply = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   -- extract lhs in the keymap. The lhs can't contain a whitespace.-  local key = selected[1]:match("[│]%s+([^%s]*)%s+[│]")+  local key = (assert(selected[1]:match("[│]%s+([^%s]*)%s+[│]"), selected[1]))   vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, false, true), "t", true) end  for _, fname in ipairs({ "edit", "split", "vsplit", "tabedit" }) do+  ---@param selected string[]+  ---@param opts fzf-lua.config.Resolved   M["keymap_" .. fname] = function(selected, opts)+    if not selected[1] then return end     local entry = path.keymap_to_entry(selected[1], opts)     if entry.path then       M["file_" .. fname]({ entry.stripped }, opts)@@ -692,7 +704,7 @@ local nvim_opt_edit = function(selected, opts, scope)     end   end -  local parts = vim.split(selected[1], opts.separator)+  local parts = vim.split(selected[1], opts.separator) ---@cast parts [string, string]   local option = vim.trim(parts[1])   local old = vim.trim(parts[2])   local info = vim.api.nvim_get_option_info2(option, {})@@ -733,6 +745,7 @@ M.spell_suggest = function(selected, opts) end  M.set_filetype = function(selected)+  if not selected[1] then return end   vim.bo.filetype = selected[1]:match("[^" .. utils.nbsp .. "]+$") end @@ -758,12 +771,12 @@ local function helptags(s, opts) end  M.help = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   vim.cmd("help " .. helptags(selected, opts)[1]) end  M.help_curwin = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local helpcmd   local is_shown = false   local current_win_number = 1@@ -786,12 +799,12 @@ M.help_curwin = function(selected, opts) end  M.help_vert = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   vim.cmd("vert help " .. helptags(selected, opts)[1]) end  M.help_tab = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   -- vim.cmd("tab help " .. helptags(selected, opts)[1])   utils.with({ go = { splitkeep = "cursor" } }, function()     vim.cmd("tabnew | setlocal bufhidden=wipe | help " .. helptags(selected, opts)[1] .. " | only")@@ -803,17 +816,17 @@ local function mantags(s) end  M.man = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   vim.cmd("Man " .. mantags(selected)[1]) end  M.man_vert = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   vim.cmd("vert Man " .. mantags(selected)[1]) end  M.man_tab = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   utils.with({ go = { splitkeep = "cursor" } }, function()     vim.cmd("tabnew | setlocal bufhidden=wipe | Man " .. mantags(selected)[1] .. " | only")   end)@@ -822,7 +835,6 @@ end M.git_switch = function(selected, opts)   if not selected[1] then return end   local cmd = path.git_cwd({ "git", "checkout" }, opts)-  ---@cast cmd -string   local git_ver = utils.git_version()   -- git switch was added with git version 2.23   if git_ver and git_ver >= 2.23 then@@ -830,6 +842,7 @@ M.git_switch = function(selected, opts)   end   -- remove anything past space   local marker, branch = selected[1]:match("%s-([%+%*]?)%s+([^ ]+)")+  if not branch then return utils.error("unable to parse branch: '%s'", selected[1]) end   -- do nothing for active branch   if marker == "*" then     utils.warn("already on branch '%s'", branch)@@ -844,6 +857,7 @@ M.git_switch = function(selected, opts)   end   table.insert(cmd, branch)   local output, rc = utils.io_systemlist(cmd)+  assert(output[1])   if marker == "+" then     assert(rc ~= 0) -- should err with worktree path     local worktree_path = output[1]:match([[([^']+)'$]])@@ -858,6 +872,8 @@ M.git_switch = function(selected, opts)   end end +---@param selected string[]+---@param opts fzf-lua.config.GitBranches|{} M.git_branch_add = function(selected, opts)   -- "reload" actions (fzf version >= 0.36) use field_index = "{q}"   -- so the prompt input will be found in `selected[1]`@@ -867,6 +883,7 @@ M.git_branch_add = function(selected, opts)   if type(branch) ~= "string" or #branch == 0 then     utils.warn("Branch name cannot be empty, use prompt for input.")   else+    assert(opts.cmd_add)     local cmd_add_branch = path.git_cwd(opts.cmd_add, opts)     table.insert(cmd_add_branch, branch)     local output, rc = utils.io_systemlist(cmd_add_branch)@@ -879,8 +896,9 @@ M.git_branch_add = function(selected, opts) end  M.git_branch_del = function(selected, opts)-  if #selected == 0 then return end-  local cmd_del_branch = path.git_cwd(opts.cmd_del, opts)+  if not selected[1] then return end+  ---@diagnostic disable-next-line: param-type-mismatch, assign-type-mismatch+  local cmd_del_branch = path.git_cwd(opts.cmd_del, opts) ---@type string[]   local cmd_cur_branch = path.git_cwd({ "git", "rev-parse", "--abbrev-ref", "HEAD" }, opts)   local branch = selected[1]:match("^[%*+]*[%s]*[(]?([^%s)]+)")   local cur_branch = utils.io_systemlist(cmd_cur_branch)[1]@@ -901,11 +919,11 @@ end  M.git_worktree_cd = function(selected, opts)   if not selected[1] then return end-  local cwd = selected[1]:match("^[^%s]+")+  local cwd = assert(selected[1]:match("^[^%s]+"))   if not path.is_absolute(cwd) then-    cwd = path.join({ uv.cwd(), cwd })+    cwd = path.join({ utils.cwd(), cwd })   end-  if cwd == vim.uv.cwd() then+  if cwd == utils.cwd() then     utils.warn(("cwd already set to '%s'"):format(cwd))     return   end@@ -921,22 +939,22 @@ end  M.git_worktree_add = function(selected, opts)   local branch = selected[1] or opts.last_query+  if not branch then return end   branch = branch:match("[^%*%+%s]+")   if type(branch) ~= "string" or #branch == 0 then     utils.warn("Branch name cannot be empty, use prompt for input.")   else     local worktree_path = path.join({ "..", branch }) +    ---@type string[]     local cmd_branch_check = path.git_cwd(       { "git", "show-ref", "--verify", "--quiet", "refs/heads/" .. branch }, opts)     local _, check_rc = utils.io_systemlist(cmd_branch_check) -    local cmd_add-    if check_rc == 0 then-      cmd_add = path.git_cwd({ "git", "worktree", "add", worktree_path, branch }, opts)-    else-      cmd_add = path.git_cwd({ "git", "worktree", "add", worktree_path, "-b", branch }, opts)-    end+    ---@type string[]+    local cmd_add = check_rc == 0+        and path.git_cwd({ "git", "worktree", "add", worktree_path, branch }, opts)+        or path.git_cwd({ "git", "worktree", "add", worktree_path, "-b", branch }, opts)      local output, rc = utils.io_systemlist(cmd_add)     if rc ~= 0 then@@ -948,15 +966,15 @@ M.git_worktree_add = function(selected, opts) end  M.git_worktree_del = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local worktree_path = selected[1]:match("^[^%s]+")-  local current_cwd = vim.uv.cwd()-  if worktree_path == current_cwd or path.normalize(worktree_path) == path.normalize(current_cwd) then+  local current_cwd = utils.cwd()+  if not worktree_path or worktree_path == current_cwd or path.normalize(worktree_path) == path.normalize(current_cwd) then     utils.warn("Cannot delete current worktree '%s'", worktree_path)     return   end   if vim.fn.confirm("Delete worktree " .. worktree_path .. "?", "&Yes\n&No") == 1 then-    local cmd_del = path.git_cwd({ "git", "worktree", "remove", worktree_path }, opts)+    local cmd_del = path.git_cwd({ "git", "worktree", "remove", worktree_path }, opts) ---@type string[]     local output, rc = utils.io_systemlist(cmd_del)     if rc ~= 0 then       utils.error(table.concat(output, "\n"))@@ -1018,7 +1036,7 @@ end local git_exec = function(selected, opts, cmd, silent)   local success   for _, e in ipairs(selected) do-    local file = path.relative_to(path.entry_to_file(e, opts).path, opts.cwd)+    local file = path.relative_to(assert(path.entry_to_file(e, opts).path), opts.cwd)     local _cmd = vim.deepcopy(cmd)     table.insert(_cmd, file)     local output, rc = utils.io_systemlist(_cmd)@@ -1100,9 +1118,9 @@ M.git_stash_apply = function(selected, opts) end  M.git_buf_edit = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local cmd = path.git_cwd({ "git", "show" }, opts)-  local git_root = path.git_root(opts, true)+  local git_root = assert(path.git_root(opts, true), "not in git directory")   local win = vim.api.nvim_get_current_win()   local buffer_filetype = vim.bo.filetype   local file = path.relative_to(path.normalize(vim.fn.expand("%:p")), git_root)@@ -1136,7 +1154,7 @@ M.git_buf_vsplit = function(selected, opts) end  M.git_goto_line = function(selected, _)-  if #selected == 0 then return end+  if not selected[1] then return end   local line = utils.tointeger(selected[1]:match("^.-(%d+)%)"))   if line then vim.api.nvim_win_set_cursor(0, { line, 0 }) end end@@ -1167,13 +1185,15 @@ M.toggle_flag = function(_, opts)     -- command without the search argument     cmd = utils.toggle_cmd_flag(assert(opts._cmd or opts.cmd), assert(opts.toggle_flag)),     resume = true-  }, opts.__call_opts)+  }, opts.__call_opts or {})   opts.__call_fn(o) end +---@param opts fzf-lua.config.Resolved|{}+---@param opt_name string M.toggle_opt = function(opts, opt_name)   -- opts.__call_opts[opt_name] = not opts[opt_name]-  local o = vim.tbl_deep_extend("keep", { resume = true }, opts.__call_opts)+  local o = vim.tbl_deep_extend("keep", { resume = true }, opts.__call_opts or {})   o[opt_name] = not opts[opt_name]   opts.__call_fn(o) end@@ -1191,7 +1211,7 @@ M.toggle_follow = function(_, opts) end  M.tmux_buf_set_reg = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local buf = selected[1]:match("^%[(.-)%]")   local data, rc = utils.io_system({ "tmux", "show-buffer", "-b", buf })   if rc == 0 and data and #data > 0 then@@ -1206,29 +1226,25 @@ M.tmux_buf_set_reg = function(selected, opts) end  M.paste_register = function(selected)-  if #selected == 0 then return end+  if not selected[1] then return end   local reg = selected[1]:match("%[(.-)%]")-  local ok, data = pcall(vim.fn.getreg, reg)-  if ok and #data > 0 then-    vim.api.nvim_paste(data, false, -1)-  end+  local data = vim.fn.getreg(reg)+  if #data > 0 then vim.api.nvim_paste(data, false, -1) end end  M.set_qflist = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local nr = selected[1]:match("[(%d+)]")   vim.cmd(string.format("%d%s", tonumber(nr),     opts._is_loclist and "lhistory" or "chistory"))   vim.cmd(opts._is_loclist and "lopen" or "copen") end ----@param selected string[]----@param opts table M.apply_profile = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local entry = path.entry_to_file(selected[1])-  local fname = entry.path-  local profile = entry.stripped:sub(#fname + 2):match("[^%s]+")+  local fname = assert(entry.path)+  local profile = assert(entry.stripped):sub(#fname + 2):match("[^%s]+")   local ok = utils.load_profile_fname(fname, profile, opts.silent)   if ok then     require("fzf-lua").setup({ profile })@@ -1238,7 +1254,7 @@ end ---@param selected string[] ---@param opts fzf-lua.config.Resolved M.complete = function(selected, opts)-  if #selected == 0 then+  if not selected[1] then     if opts.__CTX.mode == "i" then       vim.cmd [[noautocmd lua vim.api.nvim_feedkeys('i', 'n', true)]]     end@@ -1286,15 +1302,17 @@ M.dap_bp_del = function(selected, opts)   end end +---@param selected string[]+---@param opts fzf-lua.config.Zoxide|{} M.zoxide_cd = function(selected, opts)-  if #selected == 0 then return end+  if not selected[1] then return end   local cwd = selected[1]:match("[^\t]+$") or selected[1]   if opts.cwd then     cwd = path.join({ opts.cwd, cwd })   end   local git_root = opts.git_root and path.git_root({ cwd = cwd }, true) or nil   cwd = git_root or cwd-  if cwd == vim.uv.cwd() then+  if cwd == utils.cwd() then     utils.warn(("cwd already set to '%s'"):format(cwd))     return   end@@ -1315,7 +1333,7 @@ local parse_entry    = function(e) return e and e:match("%((.-)%)") or nil end M.serverlist_kill    = function(sel)   vim.iter(sel):map(parse_entry):each(function(addr)     local ok, err = utils.rpcexec(addr, "nvim_exec2", "qa!", {})-    assert(ok or err and err:match("Invalid channel"), err)+    assert(ok or tostring(err):match("Invalid channel"), err)   end) end 

lua/fzf-lua/cmd.lua

@@ -1,7 +1,7 @@ local builtin = require "fzf-lua" local path = require "fzf-lua.path" local utils = require "fzf-lua.utils"-local defaults = require "fzf-lua.defaults".defaults+local defaults = require "fzf-lua.defaults".defaults ---@type table local serpent = require "fzf-lua.lib.serpent"  local M = {}@@ -104,7 +104,7 @@ function M._candidates(line, cmp_items)     local commands = utils.tbl_flatten({ builtin_list })     table.sort(commands) -    commands = vim.tbl_filter(function(val)+    commands = vim.tbl_filter(function(val) ---@diagnostic disable-next-line: param-type-mismatch       return vim.startswith(val, l[2])     end, commands) @@ -175,7 +175,7 @@ function M._candidates(line, cmp_items)    table.sort(opts) -  opts = vim.tbl_filter(function(val)+  opts = vim.tbl_filter(function(val) ---@diagnostic disable-next-line: param-type-mismatch     return vim.startswith(val, l[#l])   end, opts) 

lua/fzf-lua/cmp_src.lua

@@ -1,4 +1,4 @@----@diagnostic disable: unused+---@diagnostic disable local Src = {}  Src.new = function(_)

lua/fzf-lua/complete.lua

@@ -1,5 +1,4 @@ ---@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local core = require "fzf-lua.core" local path = require "fzf-lua.path" local utils = require "fzf-lua.utils"@@ -28,14 +27,14 @@ local function find_toplevel_cwd(maybe_cwd, postfix, orig_cwd)     local disp_cwd, cwd = maybe_cwd, libuv.expand(maybe_cwd)     -- returned cwd must be full path     if path.has_cwd_prefix(cwd) then-      cwd = uv.cwd() .. (#cwd > 1 and cwd:sub(2) or "")+      cwd = utils.cwd() .. (#cwd > 1 and cwd:sub(2) or "")       -- inject "./" only if original path started with it       -- otherwise ignore the "." retval from fnamemodify       if #orig_cwd > 0 and orig_cwd:sub(1, 1) ~= "." then         disp_cwd = nil       end     elseif not path.is_absolute(cwd) then-      cwd = path.join({ uv.cwd(), cwd })+      cwd = path.join({ utils.cwd(), cwd })     end     return disp_cwd, cwd, postfix   end@@ -52,7 +51,7 @@ local set_cmp_opts_path = function(opts)   local match = opts.word_pattern or "[^%s\"']*"   local line = vim.api.nvim_get_current_line()   local col = vim.api.nvim_win_get_cursor(0)[2] + 1-  local before = col > 1 and line:sub(1, col - 1):reverse():match(match):reverse() or ""+  local before = col > 1 and assert(line:sub(1, col - 1):reverse():match(match)):reverse() or ""   local after = line:sub(col):match(match) or ""   -- special case when the cursor is on the left surrounding char   if #before == 0 and #after == 0 and #line > col then@@ -62,13 +61,14 @@ local set_cmp_opts_path = function(opts)   local cwd   opts._cwd, cwd, opts.query = find_toplevel_cwd(before .. after, nil, nil)   opts.prompt = path.add_trailing(opts._cwd or ".")-  opts.cwd = cwd or opts.cwd or uv.cwd()+  opts.cwd = cwd or opts.cwd or utils.cwd()   -- completion function rebuilds the line with the full path   opts.complete = function(selected, o, l, _)     -- query fuzzy matching is empty     if #selected == 0 then return end     local replace_at = col - #before-    local relpath = path.relative_to(path.entry_to_file(selected[1], o).path, opts.cwd)+    local path0 = assert(path.entry_to_file(selected[1], o).path)+    local relpath = path.relative_to(path0, opts.cwd)     local before_path = replace_at > 1 and l:sub(1, replace_at - 1) or ""     local rest_of_line = #l >= (col + #after) and l:sub(col + #after) or ""     local resolved_path = opts._cwd and path.join({ opts._cwd, relpath }) or relpath@@ -120,6 +120,7 @@ M.file = function(opts)     end   end)()   opts = set_cmp_opts_path(opts)+  ---@diagnostic disable-next-line: param-type-mismatch   return core.fzf_exec(opts.cmd, opts) end @@ -135,6 +136,7 @@ M.line = function(opts)     return vim.trim(line:sub(1, col))   end)()   opts.complete = function(selected, _, _, _)+    if not selected[1] then return end     local newline = selected[1]:match(" (.-)$")     return newline, #newline   end

lua/fzf-lua/config.lua

@@ -6,6 +6,9 @@ local libuv = require "fzf-lua.libuv" local actions = require "fzf-lua.actions" local devicons = require "fzf-lua.devicons" +---@class fzf-lua.config+---@field globals fzf-lua.config.Defaults+---@field __HLS_STATE { colorscheme: string, bg: string } local M = {}  -- set this so that make_entry won't get nil err when setting remotely@@ -60,8 +63,10 @@ function M.resume_opts(opts) end  -- proxy table (with logic) for accessing the global config-M.setup_opts = {} ---@type fzf-lua.Config|{}+M.setup_opts = {}++---@type fzf-lua.config.Defaults M.globals = setmetatable({}, {   __index = function(_, index)     local function setup_opts()@@ -166,11 +171,11 @@ local normalize_tbl = function(opts) end  ---@generic T table----@param opts T|{}|fun():T?+---@param opts T?|{}|(fun():T?) ---@param globals string|(fzf-lua.Config|{})? ---@param __resume_key string? ---@return T-function M.normalize_opts(opts, globals, __resume_key)+function M.normalize_opts(opts, globals, __resume_key) ---@diagnostic disable   -- opts can also be a function that returns an opts table   ---@type fzf-lua.config.Resolved   opts = eval(opts) or {}@@ -624,7 +629,7 @@ function M.normalize_opts(opts, globals, __resume_key)   -- other user scenarios which need to use `opts._cwd`, for   -- exmaple, using the "hide" profile and resuming fzf-lua   -- from another tab after a `:tcd <dir>` (#1854)-  opts._cwd = uv.cwd()+  opts._cwd = utils.cwd()    if opts.cwd and #opts.cwd > 0 then     -- NOTE: on Windows, `expand` will replace all backslashes with forward slashes@@ -640,7 +645,7 @@ function M.normalize_opts(opts, globals, __resume_key)         -- relative paths in cwd are inaccessible when using multiprocess         -- as the external process have no awareness of our current working         -- directory so we must convert to full path (#375)-        opts.cwd = path.join({ uv.cwd(), opts.cwd })+        opts.cwd = path.join({ utils.cwd(), opts.cwd })       elseif utils.__IS_WINDOWS and opts.cwd:sub(2) == ":" then         -- TODO: upstream bug? on Windows: starting jobs with `cwd = C:` (without separator)         -- ignores the cwd argument and starts the job in the current working directory@@ -1005,16 +1010,15 @@ function M.normalize_opts(opts, globals, __resume_key)   opts._normalized = true    return opts-end+end ---@diagnostic enable -M.bytecode = function(s, datatype)+M.bytecode = function(s, _)   local keys = utils.strsplit(s, "%.")   local iter = M   for i = 1, #keys do-    ---@diagnostic disable-next-line: assign-type-mismatch     iter = iter[keys[i]]     if not iter then break end-    if i == #keys and type(iter) == datatype then+    if i == #keys and type(iter) == "function" then       -- string.dump (function [, strip])       -- Returns a string containing a binary representation (a binary chunk) of the given       -- function, so that a later load on this string returns a copy of the function (but

lua/fzf-lua/core.lua

@@ -1,5 +1,3 @@----@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local fzf = require "fzf-lua.fzf" local path = require "fzf-lua.path" local utils = require "fzf-lua.utils"@@ -11,6 +9,8 @@ local shell = require "fzf-lua.shell"  local M = {} +---@class fzf-lua.action_defs+---@field [function] table M.ACTION_DEFINITIONS = {   -- list of supported actions with labels to be displayed in the headers   -- no pos implies an append to header array@@ -154,7 +154,6 @@ end M.fzf_exec = function(contents, opts)   if not contents then error("must supply contents") end   ---@type fzf-lua.config.Resolved-  ---@diagnostic disable-next-line: assign-type-mismatch   opts = config.normalize_opts(opts or {}, {})   if not opts then return end   if type(contents) == "table" and type(contents[1]) == "table" then@@ -210,10 +209,9 @@ end ---@param opts? fzf-lua.config.Resolved ---@return thread?, string?, table? M.fzf_live = function(contents, opts)+  ---@type fzf-lua.config.Resolved   opts = opts or {}   opts.is_live = true-  ---@diagnostic disable-next-line: assign-type-mismatch-  ---@type fzf-lua.config.Resolved   opts = config.normalize_opts(opts, {})   if not opts then return end   local fzf_field_index = M.fzf_field_index(opts)@@ -227,7 +225,7 @@ M.fzf_live = function(contents, opts)     local mtcmd = shell.stringify_mt(contents, opts)     if mtcmd then       cmd = M.expand_query(mtcmd, fzf_field_index)-    elseif not is_fnc and nop(opts) then+    elseif type(contents) == "string" and nop(opts) then       cmd = M.expand_query(contents, fzf_field_index)     else       cmd = shell.stringify(cmd2fnc(contents), opts, fzf_field_index)@@ -277,7 +275,7 @@ M.fzf_wrap = function(cmd, opts, convert_actions)       if type(opts.cb_co) == "function" then opts.cb_co(_co) end       local selected, exit_code = M.fzf(cmd, opts)       -- If aborted (e.g. unhide process kill), do nothing-      if not tonumber(exit_code) then return end+      if not exit_code or not selected then return end       -- Default fzf exit callback acts upon the selected items       fn_selected = opts.fn_selected or actions.act       if not fn_selected then return end@@ -296,7 +294,7 @@ M.fzf_wrap = function(cmd, opts, convert_actions) end  ---@param contents string?----@param opts? fzf-lua.config.Resolved+---@param opts? fzf-lua.config.Resolved|{} ---@return string[]? ---@return integer? exit_code M.fzf = function(contents, opts)@@ -351,7 +349,7 @@ M.fzf = function(contents, opts)     -- Attach the previewer to the windows     fzf_win:attach_previewer(previewer)     -- Setup --preview/--preview-window/--bind=zero:... etc-    if type(previewer.setup_opts) == "function" then ---@diagnostic disable-next-line: assign-type-mismatch+    if type(previewer.setup_opts) == "function" then       opts = previewer:setup_opts(opts)     end   elseif opts.preview and type(opts.preview) ~= "string" then@@ -471,19 +469,20 @@ local function translate_border(winopts, metadata)   return border end ----@param o fzf-lua.config.Resolved+---@param o fzf-lua.config.Resolved|{} ---@param fzf_win fzf-lua.Win ---@return string M.preview_window = function(o, fzf_win)   local layout+  local preview = assert(o.winopts and o.winopts.preview)   local prefix = string.format("%s:%s%s",-    o.winopts.preview.hidden and "hidden" or "nohidden",-    o.winopts.preview.wrap and "wrap" or "nowrap",+    preview.hidden and "hidden" or "nohidden",+    preview.wrap and "wrap" or "nowrap",     (function()       local border = (function()         local preview_str = fzf_win:fzf_preview_layout_str()         local preview_pos = preview_str:match("[^:]+") or "right"-        return translate_border(o.winopts.preview,+        return translate_border(preview,           { type = "fzf", name = "prev", layout = preview_pos, opts = o })       end)()       return border and string.format(":%s", border) or ""@@ -493,8 +492,9 @@ M.preview_window = function(o, fzf_win)       -- fzf v0.45 added transform, v0.46 added resize event       -- which we use for changing the layout on resize       and not utils.has(o, "fzf", { 0, 46 })-      and o.winopts.preview.layout == "flex"-      and tonumber(o.winopts.preview.flip_columns) > 0+      and preview.layout == "flex"+      and preview.flip_columns+      and preview.flip_columns > 0   then     -- Fzf's alternate layout calculates the available preview width in a horizontal split     -- (left/right), for the "<%d" condition to trigger the width should be test against a@@ -503,17 +503,18 @@ M.preview_window = function(o, fzf_win)     -- NOTE: sending `true` as first arg gets the no fullscreen width, otherwise we'll get     -- incosstent behavior when starting fullscreen     local columns = fzf_win:columns(true)-    local fzf_prev_percent = tonumber(o.winopts.preview.horizontal:match(":(%d+)%%"))+    local hor = assert(preview.horizontal)+    local fzf_prev_percent = tonumber(hor:match(":(%d+)%%"))     local fzf_prev_width = not fzf_prev_percent and-        tonumber(o.winopts.preview.horizontal:match(":(%d+)")) or nil+        tonumber(hor:match(":(%d+)")) or nil     fzf_prev_percent = fzf_prev_percent or 50     local fzf_main_width = fzf_prev_width and (columns - fzf_prev_width)         or math.ceil(columns * (100 - fzf_prev_percent) / 100)-    local horizontal_min_width = o.winopts.preview.flip_columns - fzf_main_width + 1+    local horizontal_min_width = preview.flip_columns - fzf_main_width + 1     if horizontal_min_width > 0 then       layout = string.format("%s:%s,<%d(%s:%s)",-        prefix, o.winopts.preview.horizontal, horizontal_min_width,-        prefix, o.winopts.preview.vertical)+        prefix, hor, horizontal_min_width,+        prefix, preview.vertical)     end   end   layout = layout or string.format("%s:%s", prefix, fzf_win:fzf_preview_layout_str())@@ -802,17 +803,17 @@ M.set_header = function(opts)   ---@param cwd string   ---@return string   local function normalize_cwd(cwd)-    if path.is_absolute(cwd) and not path.equals(cwd, uv.cwd()) then+    if path.is_absolute(cwd) and not path.equals(cwd, utils.cwd()) then       -- since we're always converting cwd to full path       -- try to convert it back to relative for display-      cwd = path.relative_to(cwd, uv.cwd())+      cwd = path.relative_to(cwd, utils.cwd())     end     -- make our home dir path look pretty     return path.HOME_to_tilde(cwd)   end    if opts.cwd_prompt then-    opts.prompt = normalize_cwd(opts.cwd or uv.cwd())+    opts.prompt = normalize_cwd(opts.cwd or utils.cwd())     if tonumber(opts.cwd_prompt_shorten_len) and         #opts.prompt >= tonumber(opts.cwd_prompt_shorten_len) then       opts.prompt = path.shorten(opts.prompt, tonumber(opts.cwd_prompt_shorten_val) or 1)@@ -833,10 +834,10 @@ M.set_header = function(opts)         if opts.cwd_header == false or             opts.cwd_prompt and opts.cwd_header == nil or             opts.cwd_header == nil and-            (not opts.cwd or path.equals(opts.cwd, uv.cwd())) then+            (not opts.cwd or path.equals(opts.cwd, utils.cwd())) then           return         end-        return normalize_cwd(opts.cwd or uv.cwd())+        return normalize_cwd(opts.cwd or utils.cwd())       end     },     search = {@@ -888,7 +889,6 @@ M.set_header = function(opts)             local def, to = nil, type(v) == "table" and v.header or nil             if not to and type(action) == "function" and defs[action] then               def = defs[action]-              ---@diagnostic disable-next-line: undefined-field               to = def[1]             end             if to then

lua/fzf-lua/ctx.lua

@@ -30,7 +30,7 @@ M.reset = function() ctx = {} end ---conditionally update the context if fzf-lua ---interface isn't open ---@param opts? { includeBuflist?: boolean, buf?: integer|string, bufnr?: integer|string }----@return fzf-lua.Ctx|{}+---@return fzf-lua.Ctx M.refresh = function(opts)   opts = opts or {}   -- save caller win/buf context, ignore when fzf@@ -83,11 +83,12 @@ M.refresh = function(opts)     end   end   -- custom bufnr from caller? (#1757)-  local bufnr = utils.tointeger(opts.buf) or utils.tointeger(opts.bufnr)+  local bufnr = utils.tointeger(opts.buf or opts.bufnr)   if bufnr then     ctx.bufnr = bufnr     ctx.bname = vim.api.nvim_buf_get_name(bufnr)   end+  ---@diagnostic disable-next-line: return-type-mismatch   return ctx end 

lua/fzf-lua/defaults.lua

@@ -1,3 +1,4 @@+---@diagnostic disable: missing-fields local path = require "fzf-lua.path" local utils = require "fzf-lua.utils" local actions = require "fzf-lua.actions"@@ -40,7 +41,7 @@ function M._man_cmd_fn(bat_pager) end  ---missing fields are injected later, not sure how to tell luals about it----@type fzf-lua.config.Defaults|{}+---@class fzf-lua.config.Defaults M.defaults        = {   nbsp          = utils.nbsp,   winopts       = {@@ -153,6 +154,8 @@ M.defaults        = {   },   fzf_tmux_opts = { ["-p"] = "80%,80%", ["--margin"] = "0,0" },   ---@class fzf-lua.config.Previewers+  ---@field builtin fzf-lua.config.BuiltinPreviewer+  ---@field git_diff fzf-lua.config.GitDiffPreviewer   ---@field [string] fzf-lua.config.Previewer   previewers    = {     cat = {@@ -179,6 +182,7 @@ M.defaults        = {       args  = nil,       _ctor = previewers.fzf.head,     },+    ---@class fzf-lua.config.GitDiffPreviewer: fzf-lua.config.Previewer     git_diff = {       pager         = M._preview_pager_fn,       cmd_deleted   = "git diff --color HEAD --",@@ -202,6 +206,7 @@ M.defaults        = {     help_tags = { _ctor = previewers.builtin.help_tags },     help_native = { _ctor = previewers.fzf.help_tags },     swiper = { _ctor = previewers.swiper.default },+    ---@class fzf-lua.config.BuiltinPreviewer: fzf-lua.config.Previewer     builtin = {       syntax            = true,       syntax_delay      = 0,@@ -221,6 +226,7 @@ M.defaults        = {       snacks_image      = { enabled = true, render_inline = true },       _ctor             = previewers.builtin.buffer_or_file,     },+    ---@class fzf-lua.config.CodeActionPreviewer: fzf-lua.config.Previewer     codeaction = {       _ctor     = previewers.builtin.codeaction,       diff_opts = { ctxlen = 3 },@@ -445,6 +451,7 @@ M.defaults.global = vim.tbl_deep_extend("force", M.defaults.files, { ---@field worktrees fzf-lua.config.GitWorktrees ---@field tags      fzf-lua.config.GitTags ---@field stash     fzf-lua.config.GitStash+---@field icons     table<string, fzf-lua.git.icons> -- Must construct our opts table in stages -- so we can reference 'M.globals.files' M.defaults.git                   = {@@ -632,6 +639,7 @@ M.defaults.git                   = {     },     _headers      = { "actions", "cwd", "search" },   },+  ---@class fzf-lua.git.icons   icons = {     ["M"] = { icon = "M", color = "yellow" },     ["D"] = { icon = "D", color = "red" },@@ -646,6 +654,7 @@ M.defaults.git                   = { ---@class fzf-lua.config.Grep: fzf-lua.config.Base ---@field cmd? string default: auto detect rg|grep ---@field rg_glob? boolean|integer+---@field rg_glob_fn? fun(query: string, opts: table): string, string ---@field raw_cmd? string ---@field search? string ---@field no_esc? integer|boolean@@ -678,7 +687,7 @@ M.defaults.grep                  = {   _headers       = { "actions", "cwd" }, } ----@diagnostic disable-next-line: assign-type-mismatch+---@diagnostic disable-next-line: param-type-mismatch ---@class fzf-lua.config.GrepCurbuf: fzf-lua.config.Grep,{} ---@field filename? string M.defaults.grep_curbuf           = vim.tbl_deep_extend("force", M.defaults.grep, {@@ -867,7 +876,7 @@ M.defaults.lines                 = {       -- restore the format to something that `path.entry_to_file` can handle       local bufnr0, lnum, text = s:match("%[(%d+)%].-(%d+) (.+)$")       local bufnr = tonumber(bufnr0)-      if not bufnr then return "" end+      if not bufnr then return "" end ---@cast bufnr integer       return string.format("[%s]%s%s:%s:%s",         bufnr, utils.nbsp,         path.tail(vim.api.nvim_buf_get_name(bufnr)),@@ -880,7 +889,7 @@ M.defaults.lines                 = {   _ctx             = { includeBuflist = true }, } ----@diagnostic disable-next-line: assign-type-mismatch+---@diagnostic disable-next-line: param-type-mismatch ---@class fzf-lua.config.Blines: fzf-lua.config.Lines M.defaults.blines                = vim.tbl_deep_extend("force", M.defaults.lines, {   show_bufname    = false,@@ -1030,7 +1039,7 @@ M.defaults.highlights            = { ---@field dbfile string ---@field icons table ---@field packpath fun():string----@field _adm table AsyncDownloadManager+---@field _adm fzf-lua.AsyncDownloadManager ---@field dl_status integer ---@field _apply_awesome_theme function M.defaults.awesome_colorschemes  = {@@ -1280,6 +1289,8 @@ M.defaults.lsp.finder            = { ---@field post_action_cb function ---@field context lsp.CodeActionContext ---@field filter fun(x: lsp.CodeAction|lsp.Command):boolean+---@field _ui_select? { kind: string }+---@field _items any[] M.defaults.lsp.code_actions      = {   async_or_timeout = 5000,   previewer        = "codeaction",@@ -1398,9 +1409,9 @@ M.defaults.tagstack              = { }  ---@class fzf-lua.config.Commands: fzf-lua.config.Base----@field flatten? table<string, boolean>----@field include_builtin? boolean----@field sort_lastused? boolean+---@field flatten table<string, boolean>+---@field include_builtin boolean+---@field sort_lastused boolean M.defaults.commands              = {   actions         = { ["enter"] = actions.ex_run },   flatten         = {},@@ -1543,6 +1554,7 @@ M.defaults.menus             = {  ---@class fzf-lua.config.Tmux ---@field buffers fzf-lua.config.TmuxBuffers+---@field cmd string M.defaults.tmux              = {   ---@class fzf-lua.config.TmuxBuffers: fzf-lua.config.Base   buffers = {@@ -1554,11 +1566,11 @@ M.defaults.tmux              = { }  ---@class fzf-lua.config.DapBase: fzf-lua.config.Base----@field commands fzf-lua.config.DapCommands|{}----@field configurations fzf-lua.config.DapConfigurations|{}----@field variables fzf-lua.config.DapVariables|{}----@field frames fzf-lua.config.DapFrames|{}----@field breakpoints fzf-lua.config.DapBreakpoints|{}+---@field commands fzf-lua.config.DapCommands+---@field configurations fzf-lua.config.DapConfigurations+---@field variables fzf-lua.config.DapVariables+---@field frames fzf-lua.config.DapFrames+---@field breakpoints fzf-lua.config.DapBreakpoints  ---@class fzf-lua.config.Dap M.defaults.dap               = {@@ -1588,7 +1600,7 @@ M.defaults.dap               = { }  ---@class fzf-lua.config.CompletePath: fzf-lua.config.Base----@field cmd? string default: auto detect fd|rg|find+---@field cmd string default: auto detect fd|rg|find ---@field word_pattern? string M.defaults.complete_path     = {   file_icons        = false, ---@type integer|boolean@@ -1602,7 +1614,7 @@ M.defaults.complete_path     = { }  ---@class fzf-lua.config.CompleteFile: fzf-lua.config.Base----@field cmd? string default: auto detect fd|rg|find+---@field cmd string default: auto detect fd|rg|find ---@field word_pattern? string M.defaults.complete_file     = {   multiprocess      = 1, ---@type integer|boolean@@ -1653,6 +1665,7 @@ M.defaults.file_icon_padding = "" M.defaults.dir_icon          = ""  ---@class fzf-lua.config.HLS+---@field fzf fzf-lua.config.fzfHLS M.defaults.__HLS             = {   normal         = "FzfLuaNormal",   border         = "FzfLuaBorder",@@ -1671,7 +1684,7 @@ M.defaults.__HLS             = {   scrollborder_e = "FzfLuaScrollBorderEmpty",   scrollborder_f = "FzfLuaScrollBorderFull",   scrollfloat_e  = "FzfLuaScrollFloatEmpty",-  scrollfloat_f  = "FzfLuaScrollFloatFull",+  scrollfloat_f  = "FzfLuaScrollFloatFull", ---@type string|false   header_bind    = "FzfLuaHeaderBind",   header_text    = "FzfLuaHeaderText",   path_colnr     = "FzfLuaPathColNr",@@ -1692,6 +1705,7 @@ M.defaults.__HLS             = {   cmd_ex         = "FzfLuaCmdEx",   cmd_buf        = "FzfLuaCmdBuf",   cmd_global     = "FzfLuaCmdGlobal",+  ---@class fzf-lua.config.fzfHLS   fzf            = {     normal     = "FzfLuaFzfNormal",     cursorline = "FzfLuaFzfCursorLine",

lua/fzf-lua/devicons.lua

@@ -52,6 +52,7 @@ function NvimWebDevicons:load(do_not_lazy_load)   then     self._package_loaded, self._package = pcall(require, self._package_name)     if self._package_loaded then+      ---@diagnostic disable-next-line: param-type-mismatch       self._package_path = path.parent(path.parent(path.normalize(         debug.getinfo(self._package.setup, "S").source:gsub("^@", ""))))     end@@ -108,7 +109,7 @@ function NvimWebDevicons:load_icons(opts)     -- something is wrong with devicons     utils.error("devicons.get_icons() is nil or empty!")     return-  end+  end ---@cast all_devicons table   local icons = {     by_filename = self._package.get_icons_by_filename(),     by_extension = self._package.get_icons_by_extension(),@@ -186,6 +187,7 @@ function MiniIcons:load(do_not_lazy_load)   then     self._package_loaded, self._package = pcall(require, self._package_name)     if self._package_loaded then+      ---@diagnostic disable-next-line: param-type-mismatch       self._package_path = path.parent(path.parent(path.parent(path.normalize(         debug.getinfo(self._package.setup, "S").source:gsub("^@", "")))))     end

lua/fzf-lua/libuv.lua

@@ -26,7 +26,7 @@ local function coroutine_callback(fn)     if coroutine.status(co) == "suspended" then       coroutine.resume(co, ...)     else-      local pid = unpack({ ... })+      local pid = unpack({ ... }) ---@cast pid integer       M.process_kill(pid)     end   end@@ -71,7 +71,7 @@ if false then M.uv_spawn = uv.spawn end ---@field cmd string|table ---@field env? table ---@field cb_finish fun(code: integer, sig: integer, from: string, pid: integer)----@field cb_write? fun(data: string, cb: fun(err: any): nil): nil+---@field cb_write fun(data: string, cb: fun(err: any): nil): nil ---@field cb_write_lines? fun(lines: string[]) ---@field cb_err fun(data: string) ---@field cb_pid? fun(pid: integer)@@ -162,7 +162,6 @@ M.spawn = function(opts, fn_transform, fn_done)     table.insert(args, tostring(opts.cmd))   end -  ---@diagnostic disable-next-line: missing-fields   handle, pid = M.uv_spawn(shell, {     args = args,     stdio = { nil, output_pipe, error_pipe },@@ -379,7 +378,7 @@ end ---@param b64? boolean ---@return table M.deserialize = function(str, b64)-  local res = loadstring(str)()+  local res = assert(loadstring(str))()   if type(res) == "table" then return res --[[@as table]] end -- ./scripts/headless_fd.sh   res = b64 ~= false and base64.decode(res) or res   -- safe=false enable call function@@ -388,7 +387,7 @@ M.deserialize = function(str, b64)   return obj end ----@param fn_str string+---@param fn_str any ---@return function? M.load_fn = function(fn_str)   if type(fn_str) ~= "string" then return end@@ -794,7 +793,7 @@ M.unescape_fzf = function(s, fzf_version, is_win)   local ret = s:gsub("\\+[^\\]", function(x)     local bslash_num = #x:match([[\+]])     return string.rep([[\]],-      bslash_num == 1 and bslash_num or bslash_num / 2) .. x:sub(-1)+      bslash_num == 1 and bslash_num or math.floor(bslash_num / 2)) .. x:sub(-1)   end)   return ret end

lua/fzf-lua/make_entry.lua

@@ -6,7 +6,7 @@ local path = require "fzf-lua.path" local utils = require "fzf-lua.utils" local libuv = require "fzf-lua.libuv" local devicons = require "fzf-lua.devicons"-local config+local config ---@module 'fzf-lua.config'  -- attempt to load the current config -- should fail if we're running headless@@ -21,7 +21,7 @@ local function load_config()   if not _G._fzf_lua_server then return end   local ok, res = utils.rpcexec(_G._fzf_lua_server, "nvim_exec_lua",     [[return FzfLua.libuv.serialize(FzfLua.config)]], {})-  if not ok then error(res) end+  if not ok then error(res) end ---@cast res string   res = libuv.deserialize(res)   return res end@@ -78,6 +78,7 @@ local opts2 = setmetatable({}, {  if _G._fzf_lua_is_headless then   local _config = load_config() or {} ---@module 'fzf-lua.config'+  ---@diagnostic disable-next-line: missing-fields   _config.globals = { git = {}, files = {}, grep = {} }   _config.globals.git.icons = load_config_section("globals.git.icons", "table") or {}   _config.globals.files.git_status_cmd =@@ -103,20 +104,21 @@ if _G._fzf_lua_is_headless then     devicons = devicons,   } end+assert(config.globals, "missing gloabals in fzf-lua config")  M.get_diff_files = function(opts)   local diff_files = {}-  local cmd = opts.git_status_cmd or config.globals.files.git_status_cmd+  local cmd = opts.git_status_cmd or config.globals.files.git_status_cmd ---@cast cmd string[]   if not cmd then return {} end   local start = uv.hrtime()-  local ok, status, err = pcall(utils.io_systemlist, path.git_cwd(cmd, opts))+  local ok, status, err = pcall(utils.io_systemlist, path.git_cwd(cmd, opts)) ---@cast status string[]   local seconds = (uv.hrtime() - start) / 1e9   if seconds >= 0.5 and opts.silent ~= true then     local exec_str = string.format([[require"fzf-lua".utils.warn(]] ..       [["'git status' took %.2f seconds, consider using `git_icons=false` in this repository or use `silent=true` to supress this message.")]]       , seconds)     if not _G._fzf_lua_is_headless then-      loadstring(exec_str)()+      assert(loadstring(exec_str))()     else       ---@diagnostic disable-next-line: undefined-field       local chan_id = vim.fn.sockconnect("pipe", _G._fzf_lua_server, { rpc = true })@@ -125,8 +127,7 @@ M.get_diff_files = function(opts)     end   end   if ok and err == 0 then-    for i = 1, #status do-      local line = status[i]+    for _, line in ipairs(status) do       local icon = line:match("[MUDARCT?]+")       local file = line:match("[^ ]*$")       if icon and file then@@ -232,8 +233,8 @@ M.lgrep = function(s, opts) end  ---@param opts table----@param search_query string----@param no_esc boolean|number+---@param search_query? string+---@param no_esc? boolean|number ---@return string? M.get_grep_cmd = function(opts, search_query, no_esc)   opts = _G._fzf_lua_is_headless and setmetatable(vim.deepcopy(opts), { __index = opts2 }) or opts@@ -286,6 +287,7 @@ M.get_grep_cmd = function(opts, search_query, no_esc)       return new_cmd     end   elseif opts.rg_glob then+    search_query = search_query or ""     local new_query, glob_args = M.glob_parse(search_query, opts)     if glob_args then       -- since the search string mixes both the query and@@ -319,7 +321,7 @@ M.get_grep_cmd = function(opts, search_query, no_esc)     -- the cwd, this is by design for perf reasons as having to deal with full paths     -- will result in more code rouets taken in `make_entry.file`     for i, p in ipairs(search_paths) do-      search_paths[i] = libuv.shellescape(path.relative_to(path.normalize(p), uv.cwd()))+      search_paths[i] = libuv.shellescape(path.relative_to(path.normalize(p), utils.cwd()))     end     search_path = table.concat(search_paths, " ")     if is_grep then@@ -479,7 +481,7 @@ M.preprocess = function(opts)   opts.cmd = M.fix_windows_cmd(opts.cmd)    if opts.cwd_only and not opts.cwd then-    opts.cwd = uv.cwd()+    opts.cwd = utils.cwd()   end    if opts.file_icons then@@ -498,7 +500,7 @@ M.preprocess = function(opts)     if not opts._fmt.to then       local _to = opts2._fmt._to       if type(_to) == "string" then-        opts._fmt.to = loadstring(_to)()+        opts._fmt.to = assert(loadstring(_to))()       end     end   end@@ -564,6 +566,7 @@ M.file = function(x, opts)       return utils.strip_ansi_coloring(file_part)     end   end)()+  ---@cast stripped_filepath-?   local filepath = stripped_filepath   -- fd v8.3 requires adding '--strip-cwd-prefix' to remove   -- the './' prefix, will not work with '--color=always'@@ -577,16 +580,16 @@ M.file = function(x, opts)   if opts.absolute_path then     -- make path absolute     if not path.is_absolute(filepath) then-      filepath = path.join({ opts.cwd or uv.cwd(), filepath })+      filepath = path.join({ opts.cwd or utils.cwd(), filepath })     end   else     -- make path relative-    filepath = path.relative_to(filepath, opts.cwd or uv.cwd())+    filepath = path.relative_to(filepath, opts.cwd or utils.cwd())   end   if path.is_absolute(filepath) then     -- filter for cwd only     if opts.cwd_only then-      if not path.is_relative_to(filepath, opts.cwd or uv.cwd()) then+      if not path.is_relative_to(filepath, opts.cwd or utils.cwd()) then         return nil       end     end

lua/fzf-lua/path.lua

@@ -270,6 +270,9 @@ function M.HOME_to_tilde(path)   return path end +---@param str string+---@param start_idx integer+---@return integer? local function find_next_separator(str, start_idx)   local SEPARATOR_BYTES = utils._if_win(     { M.fslash_byte, M.bslash_byte }, { M.fslash_byte })@@ -282,6 +285,9 @@ local function find_next_separator(str, start_idx)   end end +---@param s string+---@param i? integer+---@return integer? local function utf8_char_len(s, i)   -- Get byte count of unicode character (RFC 3629)   local c = string_byte(s, i or 1)@@ -298,6 +304,10 @@ local function utf8_char_len(s, i)   end end +---@param s string+---@param from integer+---@param to? integer+---@return string local function utf8_sub(s, from, to)   local ret = ""   -- NOTE: this function is called from shorten right after finding the next@@ -311,7 +321,7 @@ local function utf8_sub(s, from, to)   local byte_i, utf8_i = from, from   -- Concat utf8 chars until "to" or end of string   while byte_i <= #s and (not to or utf8_i <= to) do-    local c_len = utf8_char_len(s, byte_i)+    local c_len = utf8_char_len(s, byte_i) ---@cast c_len-?     local c = string_sub(s, byte_i, byte_i + c_len - 1)     ret = ret .. c     byte_i = byte_i + c_len@@ -335,7 +345,7 @@ function M.shorten(path, max_len, sep)   repeat     local i = find_next_separator(path, start_idx)     local end_idx = i and start_idx + math.min(i - start_idx, max_len) - 1 or nil-    local part = utf8_sub(path, start_idx, end_idx)+    local part = utf8_sub(path, start_idx, end_idx) ---@cast i-?     if end_idx and part == "." and i - start_idx > 1 then       part = utf8_sub(path, start_idx, end_idx + 1)     end@@ -391,7 +401,7 @@ function M.entry_to_location(entry, opts)   local uri, line0, col0 = entry:match("^(.*://.*):(%d+):(%d+):")   local line = utils.tointeger(line0) or 1   local col = utils.tointeger(col0) or 1-  if opts.path_shorten and uri:match("file://") then+  if opts.path_shorten and uri and uri:match("file://") then     uri = "file://" .. M.lengthen(uri:sub(8))   end   return {@@ -447,7 +457,7 @@ function M.entry_to_file(entry, opts, force_uri)     local parts = utils.strsplit(entry, utils.nbsp)     local idx0 = 1     for i = 1, #parts - 1 do-      local s = parts[i]+      local s = parts[i] ---@cast s string       if s:match(".-:%d+:") then         break       end@@ -544,9 +554,8 @@ function M.entry_to_file(entry, opts, force_uri)   } end ----@param cmd string|string[]----@param opts table----@return string|string[]+---@overload fun(cmd: string, opts: table): string+---@overload fun(cmd: string[], opts: table): string[] function M.git_cwd(cmd, opts)   local git_args = {     { "cwd",          "-C" },@@ -599,7 +608,7 @@ function M.git_root(opts, noerr) end  ---@param str string----@param opts fzf-lua.Config+---@param opts fzf-lua.config.Resolved ---@return fzf-lua.path.Entry|fzf-lua.keymap.Entry function M.keymap_to_entry(str, opts)   local valid_modes = {@@ -613,7 +622,7 @@ function M.keymap_to_entry(str, opts)   if not mode or not keymap then return {} end   mode, keymap = vim.trim(mode), vim.trim(keymap)   mode = valid_modes[mode] and mode or "" -- only valid modes-  local out+  local out ---@type string[]   local vmap, cmd = nil, string.format("verbose %smap %s", mode, keymap)   -- Run in the context of the originating buffer or keympas might return   -- "No mapping found"

lua/fzf-lua/previewer/builtin.lua

@@ -14,7 +14,7 @@ local fn = vim.fn ---@field private _winids table<integer, integer> local TSContext = {} ----@param opts? TSContext.UserConfig+---@param opts TSContext.UserConfig ---@return boolean function TSContext.setup(opts)   if TSContext._setup then return true end@@ -154,9 +154,9 @@ local Previewer = {} ---@field title any ---@field title_pos "center"|"left"|"right" ---@field title_fnamemodify fun(title: string, width: integer?): string----@field render_markdown table?----@field snacks_image table?----@field winopts fzf-lua.config.Winopts|{}?+---@field render_markdown table+---@field snacks_image table+---@field winopts fzf-lua.config.PreviewerWinopts ---@field syntax boolean ---@field syntax_delay integer ---@field syntax_limit_b integer@@ -286,7 +286,7 @@ end  function Previewer.base:preview_is_terminal()   if not self.win or not self.win:validate_preview() then return end-  return utils.getwininfo(self.win.preview_winid).terminal == 1+  return (utils.getwininfo(self.win.preview_winid) or {}).terminal == 1 end  ---@diagnostic disable-next-line: unused@@ -490,7 +490,7 @@ function Previewer.base:cmdline(_)     -- convert empty string to nil     if not tonumber(idx) then entry = nil end     -- upvalue incase previewer was detached/re-attached (global picker)-    self = self.win._previewer or self+    self = self.win._previewer or self ---@type fzf-lua.previewer.Builtin     -- on windows, query may not be expanded to a string: #1887     self.opts._last_query = query or ""     self:display_entry(entry)@@ -620,6 +620,7 @@ function Previewer.base:ts_ctx_inc_dec_maxlines(num) end  ---@class fzf-lua.previewer.BufferOrFile : fzf-lua.previewer.Builtin,{}+---@field match_id? integer ---@field super fzf-lua.previewer.Builtin Previewer.buffer_or_file = Previewer.base:extend() @@ -644,22 +645,22 @@ end function Previewer.buffer_or_file:parse_entry(entry_str)   ---@type fzf-lua.buffer_or_file.Entry   local entry = self:entry_to_file(entry_str)-  local loaded = entry.bufnr and api.nvim_buf_is_loaded(entry.bufnr)+  local buf = entry.bufnr+  local loaded = buf and api.nvim_buf_is_loaded(buf)   if loaded then-    entry.tick = vim.b[entry.bufnr].changedtick+    entry.tick = vim.b[buf].changedtick     return entry   end   -- buffer is not loaded, can happen when calling "lines" with `set nohidden`   -- or when starting nvim with an arglist, fix entry.path since it contains   -- filename only-  local valid = entry.bufnr and api.nvim_buf_is_valid(entry.bufnr)-  if valid then-    entry.path = path.relative_to(api.nvim_buf_get_name(entry.bufnr), uv.cwd())+  if buf and api.nvim_buf_is_valid(buf) then+    entry.path = path.relative_to(api.nvim_buf_get_name(buf), utils.cwd())   end   if entry.path then-    if entry.path:find("^fugitive://") then+    if entry.path:find("^fugitive://") and buf and api.nvim_buf_is_valid(buf) then       entry.do_not_cache = true-      api.nvim_buf_call(entry.bufnr,+      api.nvim_buf_call(buf,         function() vim.cmd(("do fugitive BufReadCmd %s"):format(entry.path)) end)       return entry     end@@ -772,7 +773,7 @@ function Previewer.buffer_or_file:populate_terminal_cmd(tmpbuf, cmd, entry)       height     = wincfg.height - 2,       scaler     = self.ueberzug_scaler,       path       = path.is_absolute(entry.path) and entry.path or-          path.join({ self.opts.cwd or uv.cwd(), entry.path }),+          path.join({ self.opts.cwd or utils.cwd(), entry.path }),     }     local json = vim.json.encode(params)     -- both 'fs_open|write|close' and 'fn.system' work.@@ -872,7 +873,7 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str)     self:preview_buf_post(entry)     return   end-  if cached and not cached.invalid then+  if cached and not cached.invalid and cached.bufnr then     self:set_preview_buf(cached.bufnr, cached.min_winopts)     self:preview_buf_post(entry, cached.min_winopts)     return@@ -896,11 +897,12 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str)     -- terminal buffers use minimal window style (2nd arg)     self:set_preview_buf(tmpbuf, entry.terminal)     self:preview_buf_post(entry, entry.terminal)-  elseif entry.uri then+  elseif entry.uri and entry.range then     -- LSP 'jdt://' entries, see issue #195     -- https://github.com/ibhagwan/fzf-lua/issues/195     api.nvim_win_call(self.win.preview_winid, function()-      local ok, res = pcall(utils.jump_to_location, entry, "utf-16", false)+      local loc = { uri = entry.uri, range = entry.range }+      local ok, res = pcall(utils.jump_to_location, loc, "utf-16", false)       if ok then         self.preview_bufnr = api.nvim_get_current_buf()       else@@ -917,11 +919,10 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str)     end)     self:preview_buf_post(entry)   else-    assert(entry.path)     -- not found in cache, attempt to load     local tmpbuf = reuse_buf or self:get_tmp_buffer()     if self.extensions and not utils.tbl_isempty(self.extensions) then-      local ext = path.extension(entry.path)+      local ext = path.extension(assert(entry.path))       local cmd = ext and self.extensions[ext:lower()]       if cmd and self:populate_terminal_cmd(tmpbuf, cmd, entry) then         -- will return 'false' when cmd isn't executable.@@ -944,7 +945,7 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str)         lines = entry.content       else         -- make sure the file is readable (or bad entry.path)-        local fs_stat = entry.fs_stat or uv.fs_stat(entry.path)+        local fs_stat = entry.path and uv.fs_stat(entry.path)         if not fs_stat then           lines = { string.format("Unable to stat file %s", entry.path) }         elseif fs_stat.size > 0 and utils.perl_file_is_binary(entry.path) then@@ -1148,7 +1149,7 @@ local filetype_detect = function(bufnr, filepath)   return vim.bo[bufnr].filetype end ----@param entry? fzf-lua.buffer_or_file.Entry|{}+---@param entry? fzf-lua.buffer_or_file.Entry function Previewer.buffer_or_file:do_syntax(entry)   if not self.preview_bufnr or not entry or not entry.path then return end   local bufnr = self.preview_bufnr@@ -1320,15 +1321,13 @@ function Previewer.buffer_or_file:set_cursor_hl(entry)           regex, reg)       end       if regex_start > 0 then-        ---@diagnostic disable-next-line: assign-type-mismatch-        self.match_id = fn.matchaddpos(hls.search, { { lnum, regex_start, regex_end } }, 11)+        self.match_id = fn.matchaddpos(hls.search, { { lnum, regex_start, regex_end } }, 11) ---@as integer       end     end      -- Fallback to cursor hl, only if column exists     if regex_start <= 0 and hls.cursor and col > 0 then-      ---@diagnostic disable-next-line: assign-type-mismatch-      self.match_id = fn.matchaddpos(hls.cursor, { { lnum, math.max(1, col) } }, 11)+      self.match_id = fn.matchaddpos(hls.cursor, { { lnum, math.max(1, col) } }, 11) ---@as integer     end      utils.zz()@@ -1412,9 +1411,10 @@ end function Previewer.help_tags:parse_entry(entry_str)   local tag = entry_str:match("^[^%s]+")   if not tag then-    return {}+    return { stripped = entry_str }   end   local vimdoc = entry_str:match(string.format("[^%s]+$", utils.nbsp))+  assert(vimdoc and #vimdoc > 0, "help_tags entry missing vimdoc path")   local hregex = (function()     -- lazy.nvim can generate helptags from markdown     -- https://github.com/folke/lazy.nvim/blob/56a34a825b55e0e30cd9df0e055e428a13afd4aa/lua/lazy/help.lua#L35@@ -1445,7 +1445,7 @@ function Previewer.help_tags:gen_winopts() end  ---@class fzf-lua.help_tags.Entry: fzf-lua.buffer_or_file.Entry----@field hregex? string+---@field hregex string  ---@param entry fzf-lua.help_tags.Entry function Previewer.help_tags:set_cursor_hl(entry)@@ -1543,7 +1543,7 @@ function Previewer.marks:parse_entry(entry_str)     else       filepath = res     end-    filepath = path.relative_to(filepath, uv.cwd())+    filepath = path.relative_to(filepath, utils.cwd())   end   return {     bufnr = bufnr,@@ -1564,11 +1564,11 @@ end  function Previewer.jumps:parse_entry(entry_str)   local bufnr = nil-  local _, lnum, col, filepath = entry_str:match("(%d+)%s+(%d+)%s+(%d+)%s+(.*)")+  local _, lnum, col0, filepath = entry_str:match("(%d+)%s+(%d+)%s+(%d+)%s+(.*)")   if filepath then     local ok, res = pcall(libuv.expand, filepath)     if ok then-      filepath = path.relative_to(res, uv.cwd())+      filepath = path.relative_to(res, utils.cwd())     end     if not uv.fs_stat(filepath) then       -- file is not accessible,@@ -1577,11 +1577,12 @@ function Previewer.jumps:parse_entry(entry_str)       filepath = api.nvim_buf_get_name(self.win.src_bufnr)     end   end+  local col = utils.tointeger(col0)   return {     bufnr = bufnr,     path  = filepath,     line  = utils.tointeger(lnum) or 1,-    col   = utils.tointeger(col) + 1 or 1,+    col   = col and col + 1 or 1,   } end @@ -1606,9 +1607,10 @@ function Previewer.tags:set_cursor_hl(entry)     -- didn't reload the buffer (same file)     api.nvim_win_set_cursor(0, { 1, 0 })     fn.clearmatches()-    fn.search(entry.ctag, "W")+    local ctag = assert(entry.ctag)+    fn.search(ctag, "W")     if self.win.hls.search then-      fn.matchadd(self.win.hls.search, entry.ctag)+      fn.matchadd(self.win.hls.search, ctag)     end     self.orig_pos = api.nvim_win_get_cursor(0)     utils.zz()@@ -1708,7 +1710,7 @@ function Previewer.quickfix:populate_preview_buf(entry_str)     return   end -  local qf_list = self.opts._is_loclist+  local qf_list = self.opts.is_loclist       and fn.getloclist(self.win.src_winid, { all = "", nr = tonumber(nr) })       or fn.getqflist({ all = "", nr = tonumber(nr) })   if utils.tbl_isempty(qf_list) or utils.tbl_isempty(qf_list.items) then@@ -1719,7 +1721,7 @@ function Previewer.quickfix:populate_preview_buf(entry_str)   for _, e in ipairs(qf_list.items) do     table.insert(lines, string.format("%s|%d col %d|%s",       path.HOME_to_tilde(path.relative_to(-        api.nvim_buf_get_name(e.bufnr), uv.cwd())),+        api.nvim_buf_get_name(e.bufnr), utils.cwd())),       e.lnum, e.col, e.text))   end   self.tmpbuf = self:get_tmp_buffer()@@ -1739,7 +1741,6 @@ function Previewer.autocmds:new(o, opts)   return self end ----@return fzf-lua.config.Winopts|{}? function Previewer.autocmds:gen_winopts()   if not self._is_vimL_command then     return self.winopts@@ -1761,7 +1762,7 @@ function Previewer.autocmds:populate_preview_buf(entry_str)   if entry.path == "<none>" then     self._is_vimL_command = true     entry.path = entry_str:match("[^:|]+│")-    local viml = entry_str:match("[^│]+$")+    local viml = assert(entry_str:match("[^│]+$"))     local lines = vim.split(viml, "\n")     local tmpbuf = self:get_tmp_buffer()     api.nvim_buf_set_lines(tmpbuf, 0, -1, false, lines)@@ -1794,7 +1795,8 @@ function Previewer.keymaps:populate_preview_buf(entry_str)   if entry.vmap then     -- keymap is vimL, there is no source file info     -- so we display the vimL code instead-    local lines = utils.strsplit(entry.vmap:match("[^%s]+$"), "\n")+    local vmap = assert(entry.vmap:match("[^%s]+$"))+    local lines = utils.strsplit(vmap, "\n")     local tmpbuf = self:get_tmp_buffer()     api.nvim_buf_set_lines(tmpbuf, 0, -1, false, lines)     vim.bo[tmpbuf].filetype = "vim"@@ -1864,7 +1866,7 @@ function Previewer.nvim_options:get_help_text(tag) end  function Previewer.nvim_options:parse_entry(entry_str)-  local parts = vim.split(entry_str, self.opts.separator)+  local parts = vim.split(entry_str, self.opts.separator) ---@cast parts [string, string]   local option = vim.trim(parts[1])   local value = vim.trim(parts[2])   return { name = option, value = value }

lua/fzf-lua/previewer/codeaction.lua

@@ -1,3 +1,4 @@+---@diagnostic disable: param-type-mismatch local utils = require "fzf-lua.utils" local shell = require "fzf-lua.shell" local native = require("fzf-lua.previewer.fzf")@@ -38,6 +39,7 @@ local function diff_text_edits(text_edits, bufnr, offset_encoding, diff_opts)     table.concat(orig_lines, eol) .. eol,     table.concat(new_lines, eol) .. eol,     diff_opts)+  ---@cast diff string   -- Windows: some LSPs use "\n" for EOL (e.g clangd)   -- remove both "\n" and "\r\n" (#1172)   return utils.strsplit(vim.trim(diff), "\r?\n")@@ -122,6 +124,10 @@ local function diff_workspace_edit(workspace_edit, offset_encoding, diff_opts)   return diff end +---@param err { code: integer, message: string }?+---@param tuple [integer, lsp.CodeAction]+---@param diff_opts vim.text.diff.Opts+---@return string[] local function diff_tuple(err, tuple, diff_opts)   if err then     return {@@ -130,7 +136,7 @@ local function diff_tuple(err, tuple, diff_opts)   end   local action = tuple[2]   if action.edit then-    local client = utils.lsp_get_clients({ id = tuple[1] })[1]+    local client = assert(utils.lsp_get_clients({ id = tuple[1] })[1])     return diff_workspace_edit(action.edit, client.offset_encoding, diff_opts)   else     local command = type(action.command) == "table" and action.command or action@@ -145,6 +151,10 @@ local function diff_tuple(err, tuple, diff_opts) end  -- https://github.com/neovim/neovim/blob/v0.9.4/runtime/lua/vim/lsp/buf.lua#L666+---@param self fzf-lua.previewer.CodeActionBuiltin+---@param idx integer+---@param callback? function+---@return string[] local function preview_action_tuple(self, idx, callback)   local tuple = self.opts._items[idx]   -- neovim changed the ui.select params with 0.10.0 (#947)@@ -156,7 +166,7 @@ local function preview_action_tuple(self, idx, callback)   -- the error (we already alerted the user about it in `handle_resolved_response`)   -- and display the default "unsupported" message from the original action   if self._resolved_actions[idx] then-    local resolved = self._resolved_actions[idx]+    local resolved = assert(self._resolved_actions[idx])     return diff_tuple(nil, not resolved.err and resolved.tuple or tuple, self.diff_opts)   end   -- Not found in cache, check if the client supports code action resolving@@ -220,7 +230,9 @@ local function preview_action_tuple(self, idx, callback)   end end -+---@class fzf-lua.previewer.CodeActionBuiltin: fzf-lua.previewer.Builtin,{}+---@field super fzf-lua.previewer.Builtin+---@field diff_opts vim.text.diff.Opts M.builtin = builtin.base:extend() M.builtin.preview_action_tuple = preview_action_tuple @@ -265,19 +277,25 @@ function M.builtin:populate_preview_buf(entry_str)   self.win:update_preview_scrollbar() end +---@class fzf-lua.previewer.CodeActionNative: fzf-lua.previewer.Fzf,{}+---@field super fzf-lua.previewer.Fzf M.native = native.base:extend() M.native.preview_action_tuple = preview_action_tuple -function M.native:new(o, opts, fzf_win)+---@param o fzf-lua.config.CodeActionPreviewer+---@param opts fzf-lua.config.LspCodeActions+---@return fzf-lua.previewer.CodeActionNative+function M.native:new(o, opts)   assert(opts._ui_select and opts._ui_select.kind == "codeaction")-  M.native.super.new(self, o, opts, fzf_win)+  M.native.super.new(self, o, opts)   setmetatable(self, M.native)-  self.pager = opts.preview_pager == nil and o.pager or opts.preview_pager-  if type(self.pager) == "function" then-    self.pager = self.pager()-  end+  local pager = opts.preview_pager == nil and o.pager or opts.preview_pager+  if type(pager) == "function" then pager = assert(pager()) end+  local cmd = pager and pager:match("[^%s]+") or nil+  if cmd and vim.fn.executable(cmd) == 1 then self.pager = pager end   self.diff_opts = o.diff_opts   self._resolved_actions = {}+  ---@diagnostic disable-next-line: undefined-field   for i, _ in ipairs(self.opts._items) do     self._resolved_actions[i] = false   end@@ -287,13 +305,14 @@ end function M.native:cmdline(o)   o = o or {}   local act = shell.stringify_data(function(entries, _, _)-    local idx = tonumber(entries[1]:match("^%s*%d+%."))-    assert(type(idx) == "number")+    if not entries[1] then return shell.nop() end+    local idx = utils.tointeger(entries[1]:match("^%s*%d+%."))+    assert(idx)     local lines = self:preview_action_tuple(idx)     return table.concat(lines, "\r\n")   end, self.opts, "{}")-  if self.pager and #self.pager > 0 and vim.fn.executable(self.pager:match("[^%s]+")) == 1 then-    act = act .. " | " .. utils._if_win_normalize_vars(self.pager)+  if self.pager then+    act = act .. " | " .. self.pager   end   return act end

lua/fzf-lua/previewer/fzf.lua

@@ -28,8 +28,8 @@ function Previewer.base:new(o, opts)   return self end ----@param opts table----@return table+---@param opts fzf-lua.config.Resolved+---@return fzf-lua.config.Resolved function Previewer.base:setup_opts(opts)   -- Set the preview command line   opts.preview = self:cmdline()@@ -111,6 +111,7 @@ end function Previewer.cmd:action(o)   o = o or {}   local act = shell.stringify_data(function(items, _, _)+    if not items[1] then return utils.shell_nop() end     local entry = path.entry_to_file(items[1], self.opts)     return entry.bufname or entry.path   end, self.opts, self.opts.field_index_expr or "{}")@@ -217,8 +218,9 @@ function Previewer.cmd_async:parse_entry_and_verify(entrystr)   end    local entry = path.entry_to_file(entrystr, self.opts)+  if not entry.stripped then return end   -- make relative for bat's header display-  local filepath = path.relative_to(entry.bufname or entry.path or "", uv.cwd())+  local filepath = path.relative_to(entry.bufname or entry.path or "", utils.cwd())   if self.opts._ctag then     -- NOTE: override `entry.ctag` with the unescaped version     entry.ctag = path.entry_to_ctag(entry.stripped, true)@@ -251,6 +253,7 @@ function Previewer.cmd_async:cmdline(o)   local act = shell.stringify_cmd(function(items)     self._last_query = items[2] or ""     local filepath, _, errcmd = self:parse_entry_and_verify(items[1])+    if not filepath then return utils.shell_nop() end     local cmd = errcmd or ("%s %s %s"):format(       self.cmd, self.args, libuv.shellescape(filepath))     return cmd@@ -305,12 +308,13 @@ function Previewer.bat_async:cmdline(o)     self._last_query = items[2] or ""     if items[1] == "" then return utils.shell_nop() end     local filepath, entry, errcmd = self:parse_entry_and_verify(items[1])+    if not filepath or not entry then return utils.shell_nop() end     local line_range = ""-    if entry.ctag then+    if entry.ctag and entry.line then       -- this is a ctag without line numbers, since we can't       -- provide the preview file offset to fzf via the field       -- index expression we use '--line-range' instead-      local start_line = utils.tointeger(math.max(1, entry.line - fzf_lines / 2))+      local start_line = math.floor((math.max(1, entry.line - fzf_lines / 2)))       local end_line = start_line + fzf_lines - 1       line_range = ("--line-range=%d:%d"):format(start_line, end_line)     end@@ -318,7 +322,7 @@ function Previewer.bat_async:cmdline(o)       self.cmd, self.args,       self.theme and string.format([[--theme="%s"]],         type(self.theme) == "function" and tostring(self.theme()) or tostring(self.theme)) or "",-      tonumber(entry.line) and tonumber(entry.line) > 0+      entry.line and entry.line > 0       and string.format("--highlight-line=%d", entry.line) or "",       line_range,       libuv.shellescape(filepath))@@ -331,14 +335,21 @@ end ---@field super fzf-lua.previewer.Fzf,{} Previewer.git_diff = Previewer.base:extend() +---@param o fzf-lua.config.GitDiffPreviewer+---@param opts fzf-lua.config.Resolved+---@return fzf-lua.previewer.GitDiff function Previewer.git_diff:new(o, opts)   Previewer.git_diff.super.new(self, o, opts)   self.cmd_deleted = path.git_cwd(o.cmd_deleted, opts)   self.cmd_modified = path.git_cwd(o.cmd_modified, opts)   self.cmd_untracked = path.git_cwd(o.cmd_untracked, opts)-  self.pager = opts.preview_pager == nil and o.pager or opts.preview_pager-  if type(self.pager) == "function" then-    self.pager = self.pager()+  local pager = opts.preview_pager == nil and o.pager or opts.preview_pager+  if type(pager) == "function" then pager = assert(pager()) end+  local cmd = pager and pager:match("[^%s]+") or nil+  if cmd and vim.fn.executable(cmd) == 1 then+    -- style 2: as we are unable to use %var% within a "cmd /c" without !var! expansion+    -- https://superuser.com/questions/223104/setting-and-using-variable-within-same-command-line-in-windows-cmd-ex+    self.pager = "| " .. utils._if_win_normalize_vars(pager, 2)   end   do     -- populate the icon mappings@@ -360,6 +371,7 @@ function Previewer.git_diff:cmdline(o)       utils.warn("shell error while running preview action.")       return utils.shell_nop()     end+    if not items[1] then return utils.shell_nop() end     local is_deleted = items[1]:match(self.git_icons["D"] .. utils.nbsp) ~= nil     local is_modified = items[1]:match("[" ..       self.git_icons["M"] ..@@ -374,7 +386,7 @@ function Previewer.git_diff:cmdline(o)     local s = items[1]     if s:match("%s%->%s") then       -- for renames, we take only the last part (#864)-      s = s:match("%s%->%s(.*)$")+      s = s:match("%s%->%s(.*)$") or s     end     local entry = path.entry_to_file(s, self.opts)     local cmd = nil@@ -393,13 +405,6 @@ function Previewer.git_diff:cmdline(o)     end     if not cmd then return "" end     if type(cmd) == "table" then return table.concat(cmd, " ") end-    local pager = ""-    if self.pager and #self.pager > 0 and-        vim.fn.executable(self.pager:match("[^%s]+")) == 1 then-      -- style 2: as we are unable to use %var% within a "cmd /c" without !var! expansion-      -- https://superuser.com/questions/223104/setting-and-using-variable-within-same-command-line-in-windows-cmd-ex-      pager = "| " .. utils._if_win_normalize_vars(self.pager, 2)-    end     -- with default commands we add the filepath at the end.     -- If the user configured a more complex command, e.g.:     -- git_diff = {@@ -407,6 +412,7 @@ function Previewer.git_diff:cmdline(o)     -- }     -- we use ':format' directly on the user's command, see     -- issue #392 for more info (limiting diff output width)+    if not entry.path then return "" end     local fname_escaped = libuv.shellescape(entry.path)     if cmd:match("[<{]file[}>]") then       cmd = cmd:gsub("[<{]file[}>]", fname_escaped)@@ -425,7 +431,7 @@ function Previewer.git_diff:cmdline(o)     -- env vars in `stringify:libuv.spawn`     -- local setenv = utils.shell_setenv_str(env)     -- cmd = string.format("%s %s %s", table.concat(setenv, " "), cmd, pager)-    cmd = string.format("%s %s", cmd, pager)+    cmd = string.format("%s %s", cmd, self.pager or "")     return { cmd = cmd, env = env }   end, self.opts, "{}")   return act@@ -446,6 +452,7 @@ end function Previewer.man_pages:cmdline(o)   o = o or {}   local act = shell.stringify_cmd(function(items)+    if not items[1] then return utils.shell_nop() end     local manpage = require("fzf-lua.providers.manpages").manpage_sh_arg(items[1])     local cmd = self.cmd:format(manpage)     return cmd@@ -472,7 +479,9 @@ end function Previewer.help_tags:cmdline(o)   o = o or {}   local act = shell.stringify_cmd(function(items)+    if not items[1] then return utils.shell_nop() end     local vimdoc = items[1]:match(string.format("[^%s]+$", utils.nbsp))+    assert(vimdoc, "help_tags previewer: unable to parse help file name")     local tag = items[1]:match("^[^%s]+")     local ext = path.extension(vimdoc)     local cmd = self.cmd:format(libuv.shellescape(vimdoc))

lua/fzf-lua/previewer/init.lua

@@ -39,17 +39,14 @@ Previewer.swiper.default = function() return require "fzf-lua.previewer.swiper". ---@field cmd? string ---@field args? string ---@field preview_offset? string----@field cmd_deleted? string----@field cmd_modified? string----@field cmd_untracked? string ---@field theme? string ---@field pager? string|function----@field _fn_git_icons? table[]|fun():table+---@field _fn_git_icons? table[]|fun():table? ---builtin ---@field title_fnamemodify? function  ---Instantiate previewer from spec----@param spec table+---@param spec? fzf-lua.config.Previewer|string ---@param opts table ---@return fzf-lua.previewer.Fzf|fzf-lua.previewer.Builtin? Previewer.new = function(spec, opts)

lua/fzf-lua/previewer/swiper.lua

@@ -6,9 +6,20 @@ local shell = require "fzf-lua.shell"  local M = {} ----@class fzf-lua.previewer.SwiperBase: fzf-lua.Object,{}+---@class fzf-lua.previewer.SwiperBase: fzf-lua.Object, {}+---@field opts table+---@field ctx_winid integer+---@field ctx_bufnr integer+---@field ctx_winopts table+---@field ns integer+---@field picker string+---@field win fzf-lua.Win M.base = Object:extend() +---@diagnostic disable: param-type-not-match+---@param o fzf-lua.config.Previewer+---@param opts fzf-lua.config.Resolved+---@return fzf-lua.previewer.SwiperBase? function M.base:new(o, opts)   o = o or {}   self.opts = opts;@@ -79,7 +90,7 @@ function M.base:parse_lnum_col(line, is_entry)   elseif self.picker == "treesitter" or self.picker == "lsp_document_symbols" then     prefix = line:gsub("%s+$", ""):match("(.*%s+).+$")     lnum, col = line:match("^.-(%d+):(%d+)%s")-    off = col and (1 - assert(tonumber(col)) - 1)+    off = col and (1 - assert(utils.tointeger(col)) - 1) or nil   end   if lnum then     -- use `vin.fn.strwidth` for proper adjustment of fzf's marker/pointer if unicode@@ -92,7 +103,7 @@ function M.base:preview_cmd()   return shell.stringify_data(function(items, _, _)     ---@type string?, string?, string?     local entry, _, idx = unpack(items, 1, 3)-    if not tonumber(idx) then return end+    if not entry or not tonumber(idx) then return end     local lnum, col = self:parse_lnum_col(entry, true)     if not lnum or lnum < 1 then return end     vim.api.nvim_win_set_cursor(self.ctx_winid, { lnum, col or 0 })@@ -129,8 +140,9 @@ function M.base:highlight_matches()     local hldef = vim.api.nvim_get_hl(0, { link = false, name = hlgroup })     return hldef and hldef.fg   end)()-  local fzf_win = utils.fzf_winobj().fzf_winid-  local fzf_buf = utils.fzf_winobj().fzf_bufnr+  local win = assert(utils.fzf_winobj())+  local fzf_win = win.fzf_winid+  local fzf_buf = win.fzf_bufnr   if not vim.api.nvim_win_is_valid(fzf_win) or not vim.api.nvim_buf_is_valid(fzf_buf) then     return   end@@ -144,7 +156,9 @@ function M.base:highlight_matches()   for r = l_s, l_e do     (function()       local buf_lnum = r - l_s + 2-      local lnum, _, col_valid_idx, col_off = self:parse_lnum_col(buf_lines[buf_lnum])+      local lnum, _, col_valid_idx, col_off = self:parse_lnum_col(assert(buf_lines[buf_lnum]))+      assert(col_valid_idx)+      assert(col_off)       if not lnum or lnum < 1 then return end       local state = { bytelen = 0 }       for c = 1, max_columns do@@ -178,8 +192,10 @@ function M.base:close()   -- on hide + change picker ctx will be nil   local ctx = utils.__CTX()   if not ctx then return end+  assert(ctx.winopts)   vim.wo[ctx.winid].winhl = ctx.winopts.winhl   vim.wo[ctx.winid].cursorline = ctx.winopts.cursorline+  ---@diagnostic disable-next-line: param-type-not-match   vim.api.nvim_win_set_cursor(ctx.winid, ctx.cursor)   utils.zz() end

lua/fzf-lua/profiles/hide.lua

@@ -23,6 +23,8 @@ return {         return opts       end       opts.actions = opts.actions or {}+      assert(opts.keymap)+      assert(opts.keymap.builtin)       if fzf.utils.has(opts, "sk") then         -- `execute-silent` actions are bugged with skim         -- Set esc to hide since we aren't using the custom callback@@ -94,6 +96,7 @@ return {       FzfLua.win.on_SIGWINCH(opts, "win.unhide", function()         if type(opts._contents) == "string"             and (opts._resume_reload == true+              ---@diagnostic disable-next-line: need-check-nil               or type(opts._resume_reload) == "function" and opts._resume_reload(opts))         then           return string.format("reload:%s", opts._contents)

lua/fzf-lua/providers/buffers.lua

@@ -1,5 +1,3 @@----@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local core = require "fzf-lua.core" local path = require "fzf-lua.path" local utils = require "fzf-lua.utils"@@ -62,7 +60,7 @@ local filter_buffers = function(opts, unfiltered)           excluded[b] = true         elseif opts.no_term_buffers and utils.is_term_buffer(b) then           excluded[b] = true-        elseif opts.cwd_only and not path.is_relative_to(vim.api.nvim_buf_get_name(b), uv.cwd()) then+        elseif opts.cwd_only and not path.is_relative_to(vim.api.nvim_buf_get_name(b), utils.cwd()) then           excluded[b] = true         elseif opts.cwd and not path.is_relative_to(vim.api.nvim_buf_get_name(b), opts.cwd) then           excluded[b] = true@@ -73,7 +71,7 @@ local filter_buffers = function(opts, unfiltered)         if buf_valid and vim.api.nvim_get_option_value("ft", { buf = b }) == "qf" then           excluded[b] = not opts.show_quickfix and true or nil         end-        if not excluded[b] and b > max_bufnr then ---@diagnostic disable-next-line: assign-type-mismatch+        if not excluded[b] and b > max_bufnr then           max_bufnr = b         end         return not excluded[b]@@ -164,7 +162,7 @@ local function gen_buffer_entry(opts, buf, max_bufnr, cwd, prefix)     else       bname = make_entry.lcol({ filename = bname, lnum = buf.info.lnum }, opts):gsub(":$", "")       return make_entry.file(bname,-        vim.tbl_extend("force", opts, { cwd = cwd or opts.cwd or uv.cwd() }))+        vim.tbl_extend("force", opts, { cwd = cwd or opts.cwd or utils.cwd() }))     end   end)()   if buf.flag == "%" then@@ -198,7 +196,8 @@ M.buffers = function(opts)   if not opts then return end    local contents = function(cb)-    local filtered, _, max_bufnr = filter_buffers(opts, utils.CTX().buflist)+    local buflist = assert(utils.CTX().buflist)+    local filtered, _, max_bufnr = filter_buffers(opts, buflist)      if next(filtered) then       local buffers = populate_buffer_entries(opts, filtered)@@ -260,7 +259,7 @@ M.buffer_lines = function(opts)       local co = coroutine.running()        local buffers = filter_buffers(opts,-        opts.current_buffer_only and { utils.CTX().bufnr } or utils.CTX().buflist)+        opts.current_buffer_only and { utils.CTX().bufnr } or utils.CTX().buflist or {})        if opts.sort_lastused and utils.tbl_count(buffers) > 1 then         table.sort(buffers, function(a, b)@@ -331,7 +330,6 @@ M.buffer_lines = function(opts)           end         end -        assert(opts.hls)         for i = 1, lines do           local lnum = i + offset           if lnum > lines then@@ -419,7 +417,6 @@ M.tabs = function(opts)       return ret     end)() -    assert(opts.hls)     for tabnr, tabh in ipairs(vim.api.nvim_list_tabpages()) do       (function()         if opts.current_tab_only and tabh ~= utils.CTX().tabh then return end@@ -429,7 +426,7 @@ M.tabs = function(opts)         local title, fn_title_hl = opt_hl(tabnr, "tab_title",           function(s)             return string.format("%s%s#%d%s", s, utils.nbsp, tabnr,-              (uv.cwd() == tab_cwd and "" or string.format(": %s", tab_cwd_tilde)))+              (utils.cwd() == tab_cwd and "" or string.format(": %s", tab_cwd_tilde)))           end,           utils.ansi_codes[opts.hls.tab_title]) @@ -582,7 +579,7 @@ M.treesitter = function(opts)               local lnum, col, _, _ = ts.get_node_range(node.node)               local node_text = ts.get_node_text(node.node, bufnr0)               local node_kind = node.kind and utils.ansi_from_hl(kind2hl(node.kind), node.kind)-              local hls = assert(opts.hls)+              local hls = opts.hls               local entry = string.format("[%s]%s%s:%s:%s\t\t[%s] %s",                 utils.ansi_codes[hls.buf_nr](tostring(bufnr0)),                 utils.nbsp,@@ -620,7 +617,7 @@ M.spellcheck = function(opts)   end    -- Default to current buffer-  local bufnr0 = tonumber(opts.bufnr) or vim.api.nvim_get_current_buf()+  local bufnr0 = utils.tointeger(opts.bufnr) or vim.api.nvim_get_current_buf()   local bufname0 = path.basename(vim.api.nvim_buf_get_name(bufnr0))   if not bufname0 or #bufname0 == 0 then     bufname0 = assert(utils.nvim_buf_get_name(bufnr0))@@ -695,13 +692,13 @@ M.spellcheck = function(opts)                 local _, lead = word:find("^" .. word_separator .. "+")                 local spell = vim.spell.check(trim(word))[1]                 if spell then-                  local hls = assert(opts.hls)+                  local hls = opts.hls                   cb(string.format("[%s]%s%s:%s:%-26s\t\t%s",                     utils.ansi_codes[hls.buf_nr](tostring(bufnr0)),                     utils.nbsp,                     utils.ansi_codes[hls.buf_name](bufname0),                     utils.ansi_codes[hls.buf_linenr](tostring(lnum)),-                    utils.ansi_codes[hls.path_colnr](tostring(from + (lead or 0))),+                    utils.ansi_codes[hls.path_colnr](tostring(assert(from) + (lead or 0))),                     trim(word)                   ), function(err)                     -- coroutine.resume(co)@@ -711,7 +708,7 @@ M.spellcheck = function(opts)                   -- coroutine.yield()                 end               end-              if from then from = to + 1 end+              if from then from = assert(to) + 1 end             until not from           end           cb(nil)

lua/fzf-lua/providers/colorschemes.lua

@@ -69,7 +69,6 @@ M.colorschemes = function(opts)         live = sel[1]         vim.cmd("colorscheme " .. sel[1])       end-      ---@diagnostic disable-next-line: param-type-mismatch     end, opts, "{}")   end @@ -155,8 +154,20 @@ M.highlights = function(opts) end  +---@class fzf-lua.AsyncDownloadManager.Job+---@field plugin string+---@field args table++---@class fzf-lua.AsyncDownloadManager+---@field path string Path to the download directory+---@field dl_status number Download status code+---@field max_threads number Maximum number of concurrent threads+---@field job_ids table<integer, fzf-lua.AsyncDownloadManager.Job>+---@field job_stack fzf-lua.AsyncDownloadManager.Job[] Stack of jobs local AsyncDownloadManager = Object:extend() +---@param opts table+---@return fzf-lua.AsyncDownloadManager|nil function AsyncDownloadManager:new(opts)   self.path = opts.path   self.dl_status = tonumber(opts.dl_status)@@ -182,14 +193,15 @@ end  function AsyncDownloadManager:destruct()   for id, _ in pairs(self.job_ids) do-    vim.fn.jobstop(tonumber(id))+    vim.fn.jobstop(id)   end end +---@param co thread? function AsyncDownloadManager:jobwait_all(co)   local jobs = {}   for id, _ in pairs(self.job_ids) do-    table.insert(jobs, tonumber(id))+    table.insert(jobs, id)   end   if #jobs > 0 then     vim.fn.jobwait(jobs)@@ -197,6 +209,8 @@ function AsyncDownloadManager:jobwait_all(co)   end end +---@param db table<string, table>+---@return boolean function AsyncDownloadManager:load_db(db)   -- store db ref and update package params   self.db = db@@ -244,6 +258,8 @@ function AsyncDownloadManager:load_db(db)   return true end +---@param plugin string+---@return boolean? function AsyncDownloadManager:downloaded(plugin)   local info = plugin and self.db[plugin]   if not info then return end@@ -251,15 +267,21 @@ function AsyncDownloadManager:downloaded(plugin)   return stat and stat.type == "directory" end +---@param plugin string+---@return integer|boolean? function AsyncDownloadManager:downloading(plugin)   local info = plugin and self.db[plugin]   return info and info.job_id end +---@param plugin string+---@return table function AsyncDownloadManager:get(plugin)   return plugin and self.db[plugin] or nil end +---@param plugin string+---@param fn fun(...) function AsyncDownloadManager:set_once_on_exit(plugin, fn)   if not plugin or not self.db[plugin] then return end   self.db[plugin].on_exit = function(...)@@ -268,12 +290,14 @@ function AsyncDownloadManager:set_once_on_exit(plugin, fn)   end end +---@param plugin string function AsyncDownloadManager:jobwait(plugin)   local info = plugin and self.db[plugin]   if not info or not info.job_id then return end   vim.fn.jobwait({ info.job_id }) end +---@param plugin string? function AsyncDownloadManager:delete(plugin)   if not plugin or not self.db[plugin] then return end   if self:downloaded(plugin) then@@ -281,6 +305,8 @@ function AsyncDownloadManager:delete(plugin)   end end +---@param plugin string+---@param job_args table function AsyncDownloadManager:queue(plugin, job_args)   if utils.tbl_count(self.job_ids) < self.max_threads then     self:jobstart(plugin, job_args)@@ -298,12 +324,14 @@ function AsyncDownloadManager:dequeue()   end end +---@param plugin string+---@param job_args table function AsyncDownloadManager:jobstart(plugin, job_args)   if not plugin then return end   local info = plugin and self.db[plugin]   local msg = string.format("%s %s (%s)",     job_args[1][2] == "clone" and "Cloning" or "Updating", info.disp_name, info.dir)-  local job_id+  local job_id ---@type integer   job_args[2] = vim.tbl_extend("keep", job_args[2] or {},     {       on_exit = function(_, rc, _)@@ -312,7 +340,7 @@ function AsyncDownloadManager:jobstart(plugin, job_args)           -- this calls `coroutine.resume` and resumes fzf's reload input stream           info.on_exit(_, rc, _)         end-        self.job_ids[tostring(job_id)] = nil+        self.job_ids[job_id] = nil         self.db[plugin].job_id = nil         -- dequeue the next job         self:dequeue()@@ -326,11 +354,13 @@ function AsyncDownloadManager:jobstart(plugin, job_args)   else     -- job started successfully     utils.info("%s [path:%s] [job_id:%d]...", msg, path.HOME_to_tilde(assert(info.path)), job_id)-    self.job_ids[tostring(job_id)] = { plugin = plugin, args = job_args }+    self.job_ids[job_id] = { plugin = plugin, args = job_args }     self.db[plugin].job_id = job_id   end end +---@param plugin string+---@return nil function AsyncDownloadManager:update(plugin)   local info = plugin and self.db[plugin]   if not info then return end@@ -365,7 +395,7 @@ M.apply_awesome_theme = function(dbkey, idx, opts)   end   if cs.vim then     ok, out = pcall(vim.api.nvim_exec2, cs.vim, { output = true })-  elseif cs.lua then+  elseif cs.lua then ---@diagnostic disable-next-line: need-check-nil     ok, out = pcall(function() loadstring(cs.lua)() end)   else     ok, out = pcall(function() vim.cmd("colorscheme " .. cs.name) end)@@ -400,7 +430,7 @@ M.awesome_colorschemes = function(opts)   if not ok then     utils.error(string.format("Json decode failed: %s", json_db))     return-  end+  end ---@cast json_db table    -- save a ref for action   opts._apply_awesome_theme = M.apply_awesome_theme@@ -476,7 +506,7 @@ M.awesome_colorschemes = function(opts)     opts.fzf_opts["--preview-window"] = "nohidden:right:0"     opts.preview = shell.stringify_data(function(sel)       if opts.live_preview and sel and sel[1] then-        local dbkey, idx = sel[1]:match("^(.-):(%d+):")+        local dbkey, idx = assert(sel[1]:match("^(.-):(%d+):"))         if opts._adm:downloaded(dbkey) then           -- some colorschemes choose a different theme based on dark|light bg           -- restore to the original background when interface was opened

lua/fzf-lua/providers/dap.lua

@@ -1,6 +1,3 @@----@diagnostic disable: undefined-field----@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local core = require "fzf-lua.core" local utils = require "fzf-lua.utils" local config = require "fzf-lua.config"@@ -102,7 +99,7 @@ M.breakpoints = function(opts)   end    -- display relative paths by default-  if opts.cwd == nil then opts.cwd = uv.cwd() end+  if opts.cwd == nil then opts.cwd = utils.cwd() end    local contents = function(cb)     coroutine.wrap(function()@@ -144,6 +141,10 @@ M.variables = function(opts)     utils.info("No active DAP session.")     return   end+  if not session.current_frame then+    utils.info("No current frame.")+    return+  end    local entries = {}   for _, s in pairs(session.current_frame.scopes or {}) do@@ -206,11 +207,11 @@ M.frames = function(opts)           return {}         end         if f.source.path then-          local path = f.source.path-          local fs_stat = vim.uv.fs_stat(path)+          local path0 = f.source.path+          local fs_stat = vim.uv.fs_stat(path0)           if fs_stat and fs_stat.type == "file" then             return {-              path = path,+              path = path0,               line = utils.tointeger(f.line),               -- col = f.column,             }

lua/fzf-lua/providers/diagnostic.lua

@@ -1,5 +1,4 @@----@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop+---@diagnostic disable: need-check-nil, param-type-mismatch local core = require "fzf-lua.core" local utils = require "fzf-lua.utils" local config = require "fzf-lua.config"@@ -41,7 +40,7 @@ M.diagnostics = function(opts)    -- required for relative paths presentation   if not opts.cwd or #opts.cwd == 0 then-    opts.cwd = uv.cwd()+    opts.cwd = utils.cwd()   else     opts.cwd_only = true   end@@ -81,7 +80,6 @@ M.diagnostics = function(opts)       if type(sign_confs) ~= "table" or utils.tbl_isempty(sign_confs) then sign_confs = nil end       signs0[v.severity].text =           (not opts.diag_icons or not sign_confs or not sign_confs.text or not sign_confs.text[level])-          ---@diagnostic disable-next-line: need-check-nil           and v.default or vim.trim(sign_confs.text[level])       signs0[v.severity].texthl = v.name     else

lua/fzf-lua/providers/files.lua

@@ -24,7 +24,7 @@ M.get_files_cmd = function(opts)     -- will result in more code routes taken in `make_entry.file`     if type(paths) == "table" then       for i, p in ipairs(paths) do-        paths[i] = libuv.shellescape(path.relative_to(path.normalize(p), uv.cwd()))+        paths[i] = libuv.shellescape(path.relative_to(path.normalize(p), utils.cwd()))       end       return table.concat(paths, " ")     end@@ -80,7 +80,7 @@ M.files = function(opts)   if opts.ignore_current_file then     local curbuf = vim.api.nvim_buf_get_name(0)     if #curbuf > 0 then-      curbuf = path.relative_to(curbuf, opts.cwd or uv.cwd())+      curbuf = path.relative_to(curbuf, opts.cwd or utils.cwd())       opts.file_ignore_patterns = opts.file_ignore_patterns or {}       table.insert(opts.file_ignore_patterns,         "^" .. utils.lua_regex_escape(curbuf) .. "$")@@ -91,7 +91,7 @@ M.files = function(opts)     -- `dir` command returns absolute paths with ^M for EOL     -- `make_entry.file` will strip the ^M     -- set `opts.cwd` for relative path display-    opts.cwd = uv.cwd()+    opts.cwd = utils.cwd()   end   opts = core.set_title_flags(opts, { "cmd" })   return core.fzf_exec(opts.cmd, opts)

lua/fzf-lua/providers/git.lua

@@ -98,9 +98,8 @@ M.diff = function(opts)     utils.warn("Invalid git ref %s", opts.ref)     return   end-  for _, k in ipairs({ "cmd", "preview" }) do-    opts[k] = opts[k]:gsub("[<{]ref[}>]", opts.ref)-  end+  opts.cmd = opts.cmd:gsub("[<{]ref[}>]", opts.ref)+  opts.preview = opts.preview:gsub("[<{]ref[}>]", opts.ref)   opts = set_git_cwd_args(opts)   if not opts.cwd then return end   opts.preview = git_preview(opts, "{-1}")@@ -205,7 +204,8 @@ M.branches = function(opts)       -- * branch       --   remotes/origin/branch       --   (HEAD detached at origin/branch)-      local branch = items[1]:match("^[%*+]*[%s]*[(]?([^%s)]+)")+      if not items[1] then return utils.shell_nop() end+      local branch = assert(items[1]:match("^[%*+]*[%s]*[(]?([^%s)]+)"))       return (preview:gsub("{.*}", branch))     end, opts, "{}")   end@@ -221,6 +221,7 @@ M.worktrees = function(opts)   if opts.preview then     local preview_cmd = opts.preview     opts.preview = shell.stringify_cmd(function(items)+      if not items[1] then return utils.shell_nop() end       local cwd = items[1]:match("^[^%s]+")       local cmd = path.git_cwd(preview_cmd, { cwd = cwd })       return cmd

lua/fzf-lua/providers/grep.lua

@@ -1,3 +1,4 @@+---@diagnostic disable: param-type-mismatch ---@diagnostic disable-next-line: deprecated local uv = vim.uv or vim.loop local path = require "fzf-lua.path"@@ -135,6 +136,7 @@ end ---@param opts fzf-lua.config.Grep|{}? ---@return thread?, string?, table? M.live_grep = function(opts)+  ---@type fzf-lua.config.Grep   opts = normalize_live_grep_opts(opts)   if not opts then return end @@ -245,7 +247,7 @@ end ---@param opts fzf-lua.config.Grep|{}? ---@return thread?, string?, table? M.grep_cword = function(opts)-  if not opts then opts = {} end+  opts = opts or {}   opts.no_esc = true   -- match whole words only (#968)   opts.search = [[\b]] .. utils.rg_escape(vim.fn.expand("<cword>")) .. [[\b]]@@ -263,7 +265,7 @@ end ---@param opts fzf-lua.config.Grep|{}? ---@return thread?, string?, table? M.grep_visual = function(opts)-  if not opts then opts = {} end+  opts = opts or {}   opts.search = utils.get_visual_selection()   return M.grep(opts) end@@ -271,8 +273,8 @@ end ---@param opts fzf-lua.config.Grep|{}? ---@return thread?, string?, table? M.grep_project = function(opts)-  if not opts then opts = {} end-  if not opts.search then opts.search = "" end+  opts = opts or {}+  opts.search = opts.search or ""   -- by default, do not include filename in search   opts.fzf_opts = opts.fzf_opts or {}   if opts.fzf_opts["--delimiter"] == nil then@@ -300,7 +302,7 @@ M.grep_curbuf = function(opts, lgrep)     utils.info("Rg current buffer requires file on disk")     return   else-    opts.filename = path.relative_to(opts.filename, uv.cwd())+    opts.filename = path.relative_to(opts.filename, utils.cwd())   end    -- Persist call options so we don't revert to global grep on `grep_lgrep`

lua/fzf-lua/providers/lsp.lua

@@ -1,5 +1,3 @@----@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local core = require "fzf-lua.core" local path = require "fzf-lua.path" local utils = require "fzf-lua.utils"@@ -90,7 +88,7 @@ local regex_filter_fn = function(regex_filter) end  local function location_handler(opts, cb, _, result, ctx, _)-  local encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding+  local encoding = assert(vim.lsp.get_client_by_id(ctx.client_id)).offset_encoding   result = utils.tbl_islist(result) and result or { result }   -- HACK: make sure target URI is valid for buggy LSPs (#1317)   for i, x in ipairs(result) do@@ -115,7 +113,7 @@ local function location_handler(opts, cb, _, result, ctx, _)   end   if opts.ignore_current_line then     local uri = vim.uri_from_bufnr(utils.CTX().bufnr)-    local cursor_line = utils.CTX().cursor[1] - 1+    local cursor_line = assert(utils.CTX().cursor[1]) - 1     result = vim.tbl_filter(function(l)       if (l.uri             and l.uri == uri@@ -160,7 +158,7 @@ local function location_handler(opts, cb, _, result, ctx, _) end  local function call_hierarchy_handler(opts, cb, _, result, ctx, _)-  local encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding+  local encoding = assert(vim.lsp.get_client_by_id(ctx.client_id)).offset_encoding   for _, call_hierarchy_call in pairs(result) do     --- "from" for incoming calls and "to" for outgoing calls     local call_hierarchy_item = call_hierarchy_call.from or call_hierarchy_call.to@@ -233,7 +231,7 @@ local function symbol_handler(opts, cb, _, result, ctx, _)     items = symbols_to_items(opts, result, utils.CTX().bufnr,       opts.child_prefix == true and string.rep(" ", 2) or opts.child_prefix)   else-    local encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding+    local encoding = assert(vim.lsp.get_client_by_id(ctx.client_id)).offset_encoding     items = vim.lsp.util.symbols_to_items(result, utils.CTX().bufnr, encoding)   end   if opts.regex_filter and opts._regex_filter_fn == nil then@@ -434,6 +432,7 @@ local function gen_lsp_contents(opts)         if x and jump1 == nil then jump1 = { result = x.result, encoding = x.encoding } end         table.insert(results, text)       end+      ---@diagnostic disable-next-line: param-type-mismatch       for client_id, response in pairs(lsp_results) do         if response.result then           local context = { client_id = client_id }@@ -591,6 +590,7 @@ local function gen_lsp_contents_hierarchy(opts)   if err then     utils.error(("Error executing '%s': %s"):format(opts.lsp_handler.prep, err))   else+    ---@diagnostic disable-next-line: param-type-mismatch     local _, response = next(res)     if not response or not response.result or not response.result[1] then       if not opts.silent then@@ -618,7 +618,7 @@ local normalize_lsp_opts = function(opts, cfg, __resume_key)    -- required for relative paths presentation   if not opts.cwd or #opts.cwd == 0 then-    opts.cwd = uv.cwd()+    opts.cwd = utils.cwd()   elseif opts.cwd_only == nil then     opts.cwd_only = true   end

lua/fzf-lua/providers/meta.lua

@@ -42,7 +42,7 @@ local function ls(dir, fn)     -- HACK: type is not always returned due to a bug in luv,     -- so fecth it with fs_stat instead when needed.     -- see https://github.com/folke/lazy.nvim/issues/306-    fn(fname, name, t or uv.fs_stat(fname).type)+    fn(fname, name, t or (uv.fs_stat(fname) or {}).type)   end end @@ -96,10 +96,10 @@ end M.combine = function(t)   t = t or {} -  local pickers = type(t.pickers) == "table" and t.pickers-      or type(t.pickers) == "string" and utils.strsplit(t.pickers, "[,;]")-      or nil+  local pickers = (type(t.pickers) == "table" and t.pickers+    or type(t.pickers) == "string" and utils.strsplit(t.pickers, "[,;]")) +  assert(pickers)   local opts = t   t.pickers = nil @@ -149,6 +149,7 @@ end ---@param opts fzf-lua.config.Global|{}? ---@return thread?, string?, table? M.global = function(opts)+  -- -@type fzf-lua.config.GlobalStrict   ---@type fzf-lua.config.Global   opts = config.normalize_opts(opts, "global")   if not opts then return end@@ -259,6 +260,7 @@ M.global = function(opts)         cur_sub = new_sub         cur_picker = new_picker       end+      if not q or not cur_sub then return end       return reload .. string.format("search(%s)", q:sub(cur_sub))     end, opts, "{q}")   end

lua/fzf-lua/providers/nvim.lua

@@ -76,7 +76,6 @@ M.commands = function(opts)   end    opts.flatten = opts.flatten or {}-  assert(opts.hls)   for k, _ in pairs(global_commands) do     table.insert(entries, utils.ansi_codes[opts.hls.cmd_global](k))     add_subcommand(k, utils.ansi_codes[opts.hls.cmd_global])@@ -182,7 +181,8 @@ M.changes_or_jumps = function(opts)    local entries = {}   for i = #jumps - 1, 3, -1 do-    local jump, line, col, text = jumps[i]:match("(%d+)%s+(%d+)%s+(%d+)%s+(.*)")+    local entry = jumps[i] ---@cast entry -?+    local jump, line, col, text = entry:match("(%d+)%s+(%d+)%s+(%d+)%s+(.*)")     table.insert(entries, string.format(" %16s %15s %15s %s",       utils.ansi_codes.yellow(jump),       utils.ansi_codes.blue(line),@@ -203,6 +203,17 @@ M.changes_or_jumps = function(opts)   return core.fzf_exec(entries, opts) end ++---@class fzf-lua.TagStackItem+---@field bufnr integer+---@field from [integer, integer, integer] # {line, col, ...}+---@field matchnr integer+---@field tagname string+---@field filename? string+---@field lnum? integer+---@field col? integer+---@field text? string+ ---@param opts fzf-lua.config.Tagstack|{}? ---@return thread?, string?, table? M.tagstack = function(opts)@@ -210,6 +221,7 @@ M.tagstack = function(opts)   opts = config.normalize_opts(opts, "tagstack")   if not opts then return end +  ---@type fzf-lua.TagStackItem[]   local tagstack = vim.fn.gettagstack().items    local tags = {}@@ -233,7 +245,7 @@ M.tagstack = function(opts)    local entries = {}   for i, tag in ipairs(tags) do-    local bufname = path.HOME_to_tilde(path.relative_to(tag.filename, uv.cwd()))+    local bufname = path.HOME_to_tilde(path.relative_to(tag.filename, utils.cwd()))     local buficon, hl     if opts.file_icons then       buficon, hl = devicons.get_devicon(bufname)@@ -267,7 +279,6 @@ M.marks = function(opts)   opts = config.normalize_opts(opts, "marks")   if not opts then return end -  assert(opts.hls)   local contents = function(cb)     local buf = utils.CTX().bufnr     local entries = {}@@ -290,7 +301,7 @@ M.marks = function(opts)     -- global marks     for _, m in ipairs(vim.fn.getmarklist()) do       local mark, bufnr, lnum, col, file = m.mark:sub(2, 2), m.pos[1], m.pos[2], m.pos[3], m.file-      file = path.relative_to(file, uv.cwd())+      file = path.relative_to(file, utils.cwd())       if path.is_absolute(file) then         file = path.HOME_to_tilde(file)       end@@ -587,7 +598,7 @@ M.spell_suggest = function(opts)   local match = opts.word_pattern or "[^%s\"'%(%)%.%%%+%-%*%?%[%]%^%$:#,]*"   local line = vim.api.nvim_get_current_line()   local col = vim.api.nvim_win_get_cursor(0)[2] + 1-  local before = col > 1 and line:sub(1, col - 1):reverse():match(match):reverse() or ""+  local before = col > 1 and assert(line:sub(1, col - 1):reverse():match(match)):reverse() or ""   local after = line:sub(col):match(match) or ""   -- special case when the cursor is on the left surrounding char   if #before == 0 and #after == 0 and #line > col then@@ -781,7 +792,7 @@ M.serverlist = function(opts)       -- Don't list servers twice       if not vim.list_contains(listed, socket) then         local ok, chan = pcall(vim.fn.sockconnect, "pipe", socket, { rpc = true })-        if ok and chan then+        if ok and chan then ---@cast chan integer           -- Check that the server is responding           if vim.fn.rpcrequest(chan, "nvim_get_chan_info", 0).id then             table.insert(found, socket)@@ -804,7 +815,7 @@ M.serverlist = function(opts)           end         )         :map(function(p)-          ----@type boolean, string?+          ---@type boolean, string?           local ok, cwd = utils.rpcexec(p, "nvim_exec_lua", "return vim.uv.cwd()", {})           if not ok or not cwd then return end           cwd = FzfLua.path.normalize(cwd)

lua/fzf-lua/providers/oldfiles.lua

@@ -36,7 +36,7 @@ M.oldfiles = function(opts)    if opts.include_current_session then     for _, buffer in ipairs(vim.split(vim.fn.execute(":buffers! t"), "\n")) do-      local bufnr = tonumber(buffer:match("%s*(%d+)"))+      local bufnr = utils.tointeger(buffer:match("%s*(%d+)"))       if bufnr then         local file = vim.api.nvim_buf_get_name(bufnr)         local fs_stat = stat_fn(file)@@ -86,7 +86,7 @@ M.oldfiles = function(opts)   end    -- for 'file_ignore_patterns' to work on relative paths-  opts.cwd = opts.cwd or uv.cwd()+  opts.cwd = opts.cwd or utils.cwd()   return core.fzf_exec(contents, opts) end 

lua/fzf-lua/providers/quickfix.lua

@@ -1,5 +1,4 @@ ---@diagnostic disable-next-line: deprecated-local uv = vim.uv or vim.loop local core = require "fzf-lua.core" local utils = require "fzf-lua.utils" local config = require "fzf-lua.config"@@ -11,7 +10,7 @@ local quickfix_run = function(opts, cfg)   opts = config.normalize_opts(opts, cfg)   if not opts then return end -  if not opts.cwd then opts.cwd = uv.cwd() end+  opts.cwd = opts.cwd or utils.cwd()    local function getlist()     if opts.__locations then return nil end

lua/fzf-lua/providers/tags.lua

@@ -26,7 +26,7 @@ local function get_tags_cmd(opts)     -- tags use relative paths, by now we should     -- have the correct cwd from `get_ctags_cwd`     query = libuv.shellescape(-      utils.rg_escape(path.relative_to(opts.filename, opts.cwd or uv.cwd())))+      utils.rg_escape(path.relative_to(opts.filename, opts.cwd or utils.cwd())))   elseif opts.search and #opts.search > 0 then     filter = ([[%s -v "^!"]]):format(bin)     query = libuv.shellescape(opts.no_esc and opts.search or@@ -84,7 +84,7 @@ local function tags(opts)   -- tags file should always resolve to an absolute path, already "expanded" by   -- `get_ctags_file` we take care of the case where `opts.ctags_file = "tags"`   if not path.is_absolute(opts._ctags_file) then-    opts._ctags_file = path.join({ opts.cwd or uv.cwd(), opts.ctags_file })+    opts._ctags_file = path.join({ opts.cwd or utils.cwd(), opts.ctags_file })   end    if not opts.ctags_autogen and not uv.fs_stat(opts._ctags_file) then

lua/fzf-lua/providers/tmux.lua

@@ -10,14 +10,13 @@ local M = {} M.buffers = function(opts)   ---@type fzf-lua.config.TmuxBuffers   opts = config.normalize_opts(opts, "tmux.buffers")-  if not opts then return end-   opts.fn_transform = function(x)     local buf, data = x:match([[^(.-):%s+%d+%s+bytes: "(.*)"$]])     return string.format("[%s] %s", utils.ansi_codes.yellow(buf), data)   end    opts.fzf_opts["--preview"] = shell.stringify_cmd(function(items)+    if not items[1] then return utils.shell_nop() end     local buf = items[1]:match("^%[(.-)%]")     return string.format("tmux show-buffer -b %s", buf)   end, opts, "{}")

lua/fzf-lua/providers/ui_select.lua

@@ -181,6 +181,7 @@ M.ui_select = function(items, ui_opts, on_choice)     -- multiple keybinds trigger, sending `--expect` to fzf     local previewer = _OPTS_ONCE.previewer     _OPTS_ONCE.previewer = nil -- can't copy the previewer object+    ---@diagnostic disable-next-line: param-type-mismatch     opts = vim.tbl_deep_extend(opts_merge_strategy, _OPTS_ONCE, opts)     opts.actions = vim.tbl_deep_extend("force", opts.actions or {},       { ["enter"] = opts.actions.enter })

lua/fzf-lua/rpc.lua

@@ -16,7 +16,7 @@ end  local function new_pipe()   local tmp = _is_win and windows_pipename() or vim.fn.tempname()-  local socket = uv.new_pipe(false)+  local socket = assert(uv.new_pipe(false))   uv.pipe_bind(socket, tmp)   return socket, tmp end

lua/fzf-lua/shell.lua

@@ -122,13 +122,13 @@ end  ---@param fn function ---@param fzf_field_index string----@param debug boolean|integer+---@param debug? boolean|integer|"v"|"verbose" ---@return string, integer function M.pipe_wrap_fn(fn, fzf_field_index, debug)   fzf_field_index = fzf_field_index or "{+}"    local receiving_function = function(pipe_path, ...)-    local pipe = uv.new_pipe(false)+    local pipe = assert(uv.new_pipe(false))     local args = { ... }     -- unescape double backslashes on windows     if utils.__IS_WINDOWS and type(args[1]) == "table" then@@ -176,8 +176,8 @@ M.check_upvalue = function(v, varname)     require("fzf-lua.lib.base64").encode(string.dump(v, true)))   -- Test the function once with nil value (imprefect?)   -- to see if there's an issue with upvalue refs-  local f = loadstring(str)()-  local ok, err = pcall(f)+  local f = assert(loadstring(str))()+  local ok, err = pcall(f) ---@cast err string   assert(     ok or (not err:match("attempt to index upvalue") and not err:match("attempt to call upvalue")),     string.format("multiprocess '%s' cannot have upvalue referecnces", varname))@@ -524,9 +524,10 @@ M.wrap_spawn_stdio = function(opts)   local nvim_bin = os.getenv("FZF_LUA_NVIM_BIN") or vim.v.progpath   -- TODO: should we check "cmd"?   for _, k in ipairs({ "contents", "fn_transform", "fn_preprocess", "fn_postprocess" }) do-    if type(opts[k]) == "function" then+    local v = opts[k]+    if type(v) == "function" then ---@cast v function       -- opts[k] = M.check_upvalue(opts[k], "opts." .. k)-      M.check_upvalue(opts[k], "opts." .. k)+      M.check_upvalue(v, "opts." .. k)     end   end   local cmd_str = ("%s -u NONE -l %s %s"):format(

lua/fzf-lua/spawn.lua

@@ -34,7 +34,7 @@ end -- global var indicating a headless instance _G._fzf_lua_is_headless = true ---@type fzf-lua.SpawnStdioOpts-local opts = require("fzf-lua.libuv").deserialize(_G.arg[1])+local opts = require("fzf-lua.libuv").deserialize(assert(_G.arg[1])) local _, pid = require("fzf-lua.libuv").spawn_stdio(opts) -- while vim.uv.run() do end -- os.exit in spawn_stdio while uv.os_getpriority(pid) do

lua/fzf-lua/test/previewer.lua

@@ -1,3 +1,4 @@+---@diagnostic disable: param-type-mismatch local fzf = require("fzf-lua") local builtin = require("fzf-lua.previewer.builtin") local M = {}

lua/fzf-lua/types.lua

@@ -3,40 +3,29 @@ error("Cannot require a meta file")  _G.FzfLua = require("fzf-lua") ----@class fzf-lua.previewer.SwiperBase----@field new function----@field setup_opts function----@field zero_cmd function?----@field result_cmd function?----@field preview_cmd function?----@field highlight_matches function?----@field win fzf-lua.Win-----@class fzf-lua.previewer.BufferOrFile----@field match_id? integer  ---@class fzf-lua.path.Entry ---@field stripped? string+---@field path? string ---@field bufnr? integer ---@field line? integer ---@field col? integer ---@field bufname? string ---@field terminal? boolean----@field path? string ---@field ctag? string ---@field uri? string ---@field range? lsp.Range ---@field debug? string debug information ----@class fzf-lua.buffer_or_file.Entry : fzf-lua.path.Entry, {}----@field do_not_cache boolean?----@field no_scrollbar boolean?----@field tick integer?----@field fs_stat uv.fs_stat.result?----@field no_syntax boolean?----@field cached fzf-lua.buffer_or_file.Bcache?----@field content string[]?----@field filetype string?+---@class fzf-lua.buffer_or_file.Entry : fzf-lua.path.Entry,{}+---@field do_not_cache? boolean+---@field no_scrollbar? boolean+---@field tick? integer+---@field fs_stat? uv.fs_stat.result+---@field no_syntax? boolean+---@field cached? fzf-lua.buffer_or_file.Bcache+---@field content? string[]+---@field filetype? string  ---@class fzf-lua.keymap.Entry ---@field vmap string?@@ -155,7 +144,7 @@ _G.FzfLua = require("fzf-lua") ---@field scrollbar? string ---@field scrolloff? integer ---@field delay? integer----@field winopts? fzf-lua.config.PreviewerWinopts+---@field winopts fzf-lua.config.PreviewerWinopts  ---@class fzf-lua.config.PreviewerWinopts ---@field number? boolean@@ -220,15 +209,15 @@ _G.FzfLua = require("fzf-lua") ---@class fzf-lua.config.Base ---@field cwd_prompt? boolean ---@field dir_icon? string----@field enrich? fun(opts: fzf-lua.config.Resolved):fzf-lua.config.Resolved|{}+---@field enrich? fun(opts: fzf-lua.config.Resolved|{}):fzf-lua.config.Resolved|{} ---@field fzf_bin? string ---@field fzf_colors? { [1]?: boolean, [string]: string? } ---@field fzf_opts? table<string, any>----@field fzf_tmux_opts? table<string, any>----@field hls? fzf-lua.config.HLS----@field winopts? fzf-lua.config.Winopts|(fun(opts: fzf-lua.Config):fzf-lua.config.Winopts)----@field keymap? fzf-lua.config.Keymap|(fun(opts: fzf-lua.Config):fzf-lua.config.Keymap)----@field actions? fzf-lua.config.Actions|(fun(opts: fzf-lua.Config):fzf-lua.config.Actions)+---@field fzf_tmux_opts table<string, any>+---@field hls fzf-lua.config.HLS+---@field winopts? fzf-lua.config.Winopts|(fun(opts: fzf-lua.config.Resolved):fzf-lua.config.Winopts)+---@field keymap? fzf-lua.config.Keymap|(fun(opts: fzf-lua.config.Resolved):fzf-lua.config.Keymap)+---@field actions? fzf-lua.config.Actions|(fun(opts: fzf-lua.config.Resolved):fzf-lua.config.Actions) ---@field no_header? boolean ---@field no_header_i? boolean ---@field prompt? string@@ -241,7 +230,7 @@ _G.FzfLua = require("fzf-lua") ---@field color_icons? boolean ---@field git_icons? boolean ---@field silent? boolean|integer----@field previewer? fun(...)|table|string+---@field previewer? fzf-lua.config.Previewer|string ---@field preview? string|function|table ---@field complete? (fun(s: string[], _o: fzf-lua.config.Resolved, l: string, c: integer):string?, integer?)|boolean ---@field header string@@ -260,14 +249,14 @@ _G.FzfLua = require("fzf-lua") ---@field cb_co fun(co: thread) ---@field cwd_only boolean ---@field cmd? string----@field debug? boolean|'v'|'verbose'+---@field debug? boolean|integer|'v'|'verbose' ---@field preview_offset? string ---@field _fzf_cli_args? string[]----@field __INFO? fzf-lua.Info----@field __CTX? fzf-lua.Ctx|{}+---@field __INFO fzf-lua.Info+---@field __CTX fzf-lua.Ctx ---@field _normalized? boolean----@field __call_fn? function----@field __call_opts? table+---@field __call_fn function+---@field __call_opts table ---@field is_live? boolean is "live" picker ---@field contents? fzf-lua.content|fzf-lua.shell.data2 ---@field _actions? fun():fzf-lua.config.Actions?@@ -281,6 +270,7 @@ _G.FzfLua = require("fzf-lua") ---@field field_index_expr? string ---@field _ctag? string ---@field preview_pager? string+---@field toggle_flag? string  ---@class fzf-lua.config.Resolved: fzf-lua.config.Base ---@field PidObject? table@@ -305,11 +295,15 @@ _G.FzfLua = require("fzf-lua") ---@field __sigwinches? string[] ---@field __sigwinch_on_scope table<string, function> ---@field __sigwinch_on_any function[]---- ---@field process1? boolean ---@field profiler? boolean ---@field use_queue? boolean ---@field throttle? boolean ---@field env? boolean----@field winopts? fzf-lua.config.Winopts+---@field winopts fzf-lua.config.WinoptsResolved+---@field actions fzf-lua.config.Actions+---@field keymap fzf-lua.config.Keymap+---@field fzf_opts table<string, any> ---@field _resume_reload? boolean+---@field _fzf_cli_args string[]+---@field _uri? boolean

lua/fzf-lua/utils.lua

@@ -604,6 +604,11 @@ function M.tointeger(x)   end end +---@return string+function M.cwd()+  return (assert(uv.cwd()))+end+ local function hex2rgb(hexcol)   local r, g, b = hexcol:match("#(%x%x)(%x%x)(%x%x)")   if not r or not g or not b then return end@@ -891,12 +896,13 @@ function M.fzf_exit()   require("fzf-lua").win.win_leave() end +---@return fzf-lua.Win? function M.fzf_winobj()   return require("fzf-lua").win.__SELF() end  ---@param opts? { includeBuflist?: boolean, buf?: integer|string, bufnr?: integer|string }----@return fzf-lua.Ctx|{}+---@return fzf-lua.Ctx function M.CTX(opts)   return require("fzf-lua.ctx").refresh(opts) end@@ -936,7 +942,7 @@ end  ---@param fname string ---@param name string|nil----@param silent boolean|integer+---@param silent? boolean|integer ---@return table? function M.load_profile_fname(fname, name, silent)   local profile = name or vim.fn.fnamemodify(fname, ":t:r") or "<unknown>"@@ -1015,7 +1021,7 @@ function M.is_term_buffer(bufnr)   bufnr = bufnr == 0 and vim.api.nvim_get_current_buf() or bufnr   local winid = vim.fn.bufwinid(bufnr)   if tonumber(winid) > 0 and vim.api.nvim_win_is_valid(winid) then-    return M.getwininfo(winid).terminal == 1+    return M.getwininfo(winid) --[[@cast -?]].terminal == 1   end   local bufname = vim.api.nvim_buf_is_valid(bufnr) and vim.api.nvim_buf_get_name(bufnr)   return M.is_term_bufname(bufname)@@ -1041,8 +1047,10 @@ function M.buffer_is_dirty(bufnr, warn, only_if_last_buffer)   return false end +---@param bufnr integer+---@return boolean function M.save_dialog(bufnr)-  bufnr = tonumber(bufnr) or vim.api.nvim_get_current_buf()+  bufnr = bufnr or vim.api.nvim_get_current_buf()   local info = bufnr and M.getbufinfo(bufnr)   if not info.name or #info.name == 0 then     -- unnamed buffers can't be saved@@ -1085,7 +1093,7 @@ function M.buf_is_qf(bufnr, bufinfo)   if bufinfo and bufinfo.variables and       bufinfo.variables.current_syntax == "qf" and       not M.tbl_isempty(bufinfo.windows) then-    local window = bufinfo.windows[1]+    local window = bufinfo.windows --[[@cast -?]][1]     ---@cast window integer     return M.win_is_qf(window)   end@@ -1143,6 +1151,9 @@ function M.nvim_buf_get_name(bufnr, bufinfo) end  -- correctly handle virtual text, conceal lines+---@param win integer+---@param buf integer+---@return integer function M.line_count(win, buf)   if vim.api.nvim_win_text_height then     return vim.api.nvim_win_text_height(win, {}).all

lua/fzf-lua/win.lua

@@ -120,6 +120,7 @@ end ---@field width integer ---@field row integer ---@field col integer+---@field zindex integer ---@field __winhls { main: [string, string][], prev: [string, string][] }  ---@class fzf-lua.config.Winopts: vim.api.keyset.win_config@@ -127,7 +128,7 @@ end ---@field width? number ---@field row? number ---@field col? number----@field preview? fzf-lua.config.PreviewOpts+---@field preview fzf-lua.config.PreviewOpts ---@field split? string|function|false ---@field backdrop? number|boolean ---@field fullscreen? boolean@@ -141,20 +142,21 @@ end ---@field __winhls? { main: [string, string?][], prev: [string, string?][] }  ---@class fzf-lua.Win----@field winopts fzf-lua.config.Winopts+---@field winopts fzf-lua.config.WinoptsResolved ---@field actions fzf-lua.config.Actions|{} ---@field layout fzf-lua.WinLayout+---@field fzf_bufnr integer+---@field fzf_winid integer ---@field preview_hidden? boolean ---@field preview_wrap? boolean ---@field km_winid? integer ---@field km_bufnr? integer ---@field fullscreen? boolean----@field hls? fzf-lua.config.HLS+---@field hls fzf-lua.config.HLS ---@field previewer? fun(...)|table|string----@field fzf_bufnr? integer ---@field _hidden_fzf_bufnr? integer ---@field toggle_behavior? "extend"|"default"----@field _previewer? fzf-lua.previewer.Builtin|fzf-lua.previewer.Fzf?+---@field _previewer? fzf-lua.previewer.Builtin|fzf-lua.previewer.Fzf ---@field _preview_pos_force? fzf-lua.win.previewPos ---@field _last_view? [integer, integer, integer]? ---@field _o fzf-lua.config.Resolved@@ -357,12 +359,14 @@ function FzfWin:generate_layout()       height = wininfo.height,       width = wininfo.width,       split = winopts.split,+      row = 0,+      col = 0,     }   end    local pwopts   local row, col = winopts.row, winopts.col-  local height, width = winopts.height, winopts.width ---@type integer, integer+  local height, width = winopts.height, winopts.width   local preview_pos, preview_size = layout.pos, layout.size   local pborder, ph, pw = self:normalize_border(self._o.winopts.preview.border,     { type = "nvim", name = "prev", layout = preview and layout.pos, nwin = nwin, opts = self._o })@@ -479,7 +483,7 @@ function FzfWin:tmux_columns()   -- fzf's defaults to "--tmux" is "center,50%" or "50%" for splits   if is_popup or is_hsplit then     local percent = type(opt_val) == "string" and tonumber(opt_val:match("(%d+)%%")) or 50-    cols = math.floor(cols * percent / 100)+    cols = math.floor(assert(cols) * percent / 100)   end   return cols end@@ -507,7 +511,7 @@ end ---@field name? 'fzf'|'prev' ---@field nwin? integer ---@field layout? fzf-lua.win.previewPos----@field opts? fzf-lua.config.Resolved+---@field opts? fzf-lua.config.Resolved|{}  ---@alias fzf-lua.winborder string[]|"none"|"single"|"double"|"rounded"|"solid"|"shadow" @@ -657,7 +661,7 @@ function FzfWin:normalize_winopts()     -- convert cursor relative to absolute ('editor'),     -- this solves the preview positioning seamlessly     -- use the calling window context for correct pos-    local winid = assert(utils.CTX().winid)+    local winid = utils.CTX().winid     local pos = api.nvim_win_get_cursor(winid)     local screenpos = fn.screenpos(winid, pos[1], pos[2])     winopts.row = math.floor((winopts.row or 0) + screenpos.row - 1)@@ -682,12 +686,14 @@ function FzfWin:reset_win_highlights(win)   -- derive the highlights from the window type   local key = "main"   local hl-  if win == self.preview_winid then+  if self._previewer+      and self._previewer.gen_winopts+      and win == self.preview_winid then     key = "prev"     hl = self._previewer:gen_winopts().winhl   end   if not hl then-    for _, h in ipairs(assert(self.winopts.__winhls)[key]) do+    for _, h in ipairs(self.winopts.__winhls[key]) do       if h[2] then         hl = string.format("%s%s:%s", hl and hl .. "," or "", h[1], h[2])       end@@ -836,9 +842,7 @@ function FzfWin.new(o)   self.winopts = self:normalize_winopts()   -- Backward compat since removal of "border" scrollbar   if self.winopts.preview.scrollbar == "border" then-    ---@diagnostic disable-next-line: assign-type-mismatch     self.hls.scrollfloat_f = false-    ---@diagnostic disable-next-line: undefined-field     -- Reverse "FzfLuaScrollBorderFull" color     local scrollborder_f = self.hls.scrollborder_f     if type(scrollborder_f) == "string" then@@ -915,8 +919,7 @@ end  function FzfWin:validate_preview()   return not self.closing-      and tonumber(self.preview_winid)-      and self.preview_winid > 0+      and self.preview_winid       and api.nvim_win_is_valid(self.preview_winid) end @@ -924,6 +927,7 @@ function FzfWin:redraw_preview()   if not self.previewer_is_builtin or self.preview_hidden then     return   end+  local previewer = self._previewer ---@cast previewer fzf-lua.previewer.Builtin    -- Close the exisiting scrollbar   self:close_preview_scrollbar()@@ -935,11 +939,11 @@ function FzfWin:redraw_preview()   if self:validate_preview() then     -- since `nvim_win_set_config` removes all styling, save backup     -- of the current options and restore after the call (#813)-    local style = self:get_winopts(self.preview_winid, self._previewer:gen_winopts())+    local style = self:get_winopts(self.preview_winid, previewer:gen_winopts())     api.nvim_win_set_config(self.preview_winid, self.layout.preview)     self:set_winopts(self.preview_winid, style)   else-    local tmp_buf = self._previewer:get_tmp_buffer()+    local tmp_buf = previewer:get_tmp_buffer()     -- No autocmds, can only be sent with 'nvim_open_win'     self.preview_winid = api.nvim_open_win(tmp_buf, false,       vim.tbl_extend("force", self.layout.preview, { noautocmd = true }))@@ -947,8 +951,8 @@ function FzfWin:redraw_preview()     api.nvim_win_set_var(self.preview_winid, "fzf_lua_preview", true)   end   self:reset_win_highlights(self.preview_winid)-  self._previewer:display_last_entry()-  self._previewer:update_ts_context()+  previewer:display_last_entry()+  previewer:update_ts_context() end  function FzfWin:validate()@@ -987,7 +991,8 @@ function FzfWin:redraw_main()   if self:validate() then     if self._previewer         and self._previewer.clear_on_redraw-        and self._previewer.clear_preview_buf then+        and self._previewer.clear_preview_buf+        and self._previewer.clear_cached_buffers then       self._previewer:clear_preview_buf(true)       self._previewer:clear_cached_buffers()     end@@ -1447,7 +1452,7 @@ function FzfWin:was_hidden() end  ---SIGWINCH/on_SIGWINCH is nop if fzf < v0.46----@param opts fzf-lua.config.Resolved+---@param opts fzf-lua.config.Resolved|{} ---@param scope string? nil means on any sigwinch ---@param cb function ---@return boolean?@@ -1568,8 +1573,9 @@ function FzfWin:update_preview_scrollbar()   end    local scrolloff = self.winopts.preview.scrollbar == "border"+      and self.layout.preview       and self.layout.preview.border ~= "none" and 0-      or tonumber(self.winopts.preview.scrolloff) or -1+      or self.winopts.preview.scrolloff or -1    local empty = {     style = "minimal",@@ -1669,9 +1675,11 @@ function FzfWin:update_main_title(title) end  function FzfWin:update_preview_title(title)-  if type(title) ~= "string" and type(title) ~= "table" or not self.layout.preview then+  if type(title) ~= "string" and type(title) ~= "table" or not self.layout.preview+      or not self._previewer then     return   end+  assert(self._previewer.gen_winopts)   -- since `nvim_win_set_config` removes all styling, save backup   -- of the current options and restore after the call (#813)   local style = self:get_winopts(self.preview_winid, self._previewer:gen_winopts())

plugin/fzf-lua.lua

@@ -7,6 +7,7 @@ if vim.fn.has("nvim-0.9") ~= 1 then end  vim.api.nvim_create_user_command("FzfLua", function(opts)+  ---@diagnostic disable-next-line: param-type-mismatch   require("fzf-lua.cmd").run_command(unpack(opts.fargs)) end, {   nargs = "*",

scripts/cli.lua

@@ -39,7 +39,6 @@ for _, config_path in ipairs(config_paths) do end  _G.fzf_jobstart = function(cmd, opts)-  ---@diagnostic disable-next-line: missing-fields, missing-parameter   FzfLua.libuv.uv_spawn(cmd[1], {       cwd = opts.cwd,       args = vim.list_slice(cmd, 2),

scripts/minimal_init.lua

@@ -1,3 +1,4 @@+---@diagnostic disable: param-type-mismatch -- Add current directory to 'runtimepath' to be able to use 'lua' files vim.opt.runtimepath:append(vim.uv.cwd()) 

tests/devicons_spec.lua

@@ -7,6 +7,7 @@ local eq = helpers.expect.equality local new_set = MiniTest.new_set local exec_lua = child.lua +---@diagnostic disable-next-line: param-type-mismatch local _devicons_path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "nvim-web-devicons") if not vim.uv.fs_stat(_devicons_path) then   _devicons_path = vim.fs.joinpath("deps", "nvim-web-devicons")

tests/files_spec.lua

@@ -61,6 +61,7 @@ T["files"]["previewer"] = new_set({ parametrize = { { false }, { true } } }) T["files"]["previewer"]["builtin"] = new_set({ parametrize = { { "ci" }, { "builtin" } } }, {   function(icons, previewer)     if icons then+      ---@diagnostic disable-next-line: param-type-mismatch       local path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "mini.nvim")       if not vim.uv.fs_stat(path) then         path = vim.fs.joinpath("deps", "mini.nvim")@@ -102,6 +103,7 @@ T["files"]["icons"]["defaults"] = new_set({ parametrize = { { "+attrs" }, { "-at     attrs = attrs == "+attrs" and true or false     if attrs then helpers.SKIP_IF_WIN() end     local plugin = icons == "mini" and "mini.nvim" or "nvim-web-devicons"+    ---@diagnostic disable-next-line: param-type-mismatch     local path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", plugin)     if not vim.uv.fs_stat(path) then       path = vim.fs.joinpath("deps", plugin)

tests/grep_spec.lua

@@ -20,7 +20,7 @@ T["grep"]["search"]["regex"] = new_set({ parametrize = { { false }, { true }, {       ignore_text = helpers.IS_WIN() and { 4, 6, 9, 10, 12, 18, 28 } or { 28 },       normalize_paths = helpers.IS_WIN()     }-    local path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "nvim-web-devicons")+    local path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "nvim-web-devicons") ---@diagnostic disable-line: param-type-mismatch     if not vim.uv.fs_stat(path) then       path = vim.fs.joinpath("deps", "nvim-web-devicons")     end

tests/headless_spec.lua

@@ -6,11 +6,13 @@ local eq = helpers.expect.equality local new_set = MiniTest.new_set local exec_lua = child.lua +---@diagnostic disable-next-line: param-type-mismatch local _mini_path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "mini.nvim") if not vim.uv.fs_stat(_mini_path) then   _mini_path = vim.fs.joinpath("deps", "mini.nvim") end +---@diagnostic disable-next-line: param-type-mismatch local _devicons_path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "nvim-web-devicons") if not vim.uv.fs_stat(_devicons_path) then   _devicons_path = vim.fs.joinpath("deps", "nvim-web-devicons")

tests/minicons_spec.lua

@@ -8,6 +8,7 @@ local new_set = MiniTest.new_set local exec_lua = child.lua  -- Setup mini.icons locally+---@diagnostic disable-next-line: param-type-mismatch local _mini_path = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy", "mini.nvim") if not vim.uv.fs_stat(_mini_path) then   _mini_path = vim.fs.joinpath("deps", "mini.nvim")

tests/shell_spec.lua

@@ -10,6 +10,7 @@ describe("Testing shell module", function()   it("check_upvalue", function()     ok(shell.check_upvalue, function() end, "no upvalue") +    ---@diagnostic disable: need-check-nil     err(shell.check_upvalue, (function()       local upvalue       ---@diagnostic disable-next-line: undefined-field@@ -20,5 +21,6 @@ describe("Testing shell module", function()       local upvalue       return function() return upvalue() end     end)(), "call upvalue")+    ---@diagnostic enable: need-check-nil   end) end)

tests/win_spec.lua

@@ -111,7 +111,7 @@ T["win"]["hide"]["can resume after close CTX win (#1936)"] = function()   -- can :wqa when there're hide job #1817   pcall(child.cmd, [[wqa]])   -- child.is_running() didn't work as expected-  eq(vim.fn.jobwait({ child.job.id }, 1000)[1], 0)+  eq(vim.fn.jobwait({ assert(child.job).id }, 1000)[1], 0) end  T["win"]["hide"]["actions on multi-select but zero-match #1961"] = function()@@ -133,7 +133,7 @@ end T["win"]["keymap"] = new_set({ n_retry = not helpers.IS_LINUX() and 5 or nil })  T["win"]["keymap"]["no error"] = new_set({-  parametrize = vim.iter(assert(require("fzf-lua.defaults").defaults.keymap).builtin)+  parametrize = vim.iter(require("fzf-lua.defaults").defaults.keymap.builtin)       :map(function(key, action) return { key, action } end)       :totable() }, {