From b1a567ae2fa968a0f3b5a61a5308b677287d745e Mon Sep 17 00:00:00 2001 From: Oscar Wallberg Date: Thu, 30 Apr 2026 11:51:38 +0200 Subject: [PATCH] feat(fzf-lua): replace oldfiles with unified MRU recent_files --- plugins/fzf-lua.lua | 86 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/plugins/fzf-lua.lua b/plugins/fzf-lua.lua index 73beeed..6b25a5a 100644 --- a/plugins/fzf-lua.lua +++ b/plugins/fzf-lua.lua @@ -3,13 +3,88 @@ local fzf = require("fzf-lua") local wide = { width = 160, height = 30, - preview = { horizontal = "right:50%" }, + preview = { + horizontal = "right:50%", + }, } +local function valid_file(file) + local stat = vim.uv.fs_stat(file) + return stat ~= nil + and not fzf.utils.path_is_directory(file, stat) + -- FIFO blocks `fs_open` indefinitely (#908) + and not fzf.utils.file_is_fifo(file, stat) + and fzf.utils.file_is_readable(file) +end + +local function recent_files() + local cwd = vim.fn.getcwd() + local current = vim.api.nvim_buf_get_name(0) + local has_current = current ~= "" + local oldfiles_count = #vim.v.oldfiles + local scores = {} + + local function under_cwd(path) + local rel = vim.fs.relpath(cwd, path) + return rel ~= nil and not vim.startswith(rel, "..") + end + + local function is_uri(path) + return path:match("^%w[%w+%-%.]*://") ~= nil + end + + for i, f in ipairs(vim.v.oldfiles) do + if f ~= current and not is_uri(f) and under_cwd(f) then + scores[f] = oldfiles_count - i + 1 + end + end + + for _, b in ipairs(vim.api.nvim_list_bufs()) do + if vim.bo[b].buftype == "" then + local name = vim.api.nvim_buf_get_name(b) + if + name ~= "" + and not is_uri(name) + and name ~= current + and under_cwd(name) + and (scores[name] or valid_file(name)) + then + local info = vim.fn.getbufinfo(b)[1] + ---@cast info -nil + scores[name] = math.max(info.lastused, scores[name] or 0) + end + end + end + + local list = {} + for f in pairs(scores) do + table.insert(list, f) + end + table.sort(list, function(a, b) + return scores[a] > scores[b] + end) + for i, f in ipairs(list) do + list[i] = vim.fs.relpath(cwd, f) or f + end + if has_current then + table.insert(list, 1, vim.fs.relpath(cwd, current) or current) + end + + fzf.fzf_exec(list, { + prompt = "> ", + previewer = false, + winopts = { title = " Recent " }, + fzf_opts = has_current and { ["--header-lines"] = 1 } or nil, + actions = require("fzf-lua.config").globals.actions.files, + }) +end + fzf.setup({ defaults = { lopen = "lopen", copen = "copen", + git_icons = false, + file_icons = false, }, winopts = { width = 80, @@ -17,6 +92,7 @@ fzf.setup({ row = 0.5, col = 0.5, backdrop = 100, + treesitter = false, }, keymap = { builtin = { @@ -79,10 +155,16 @@ fzf.setup({ winopts = wide, multiline = 1, }, + manpages = { + winopts = wide, + }, + helptags = { + winopts = wide, + }, }) vim.keymap.set("n", "ff", fzf.files) -vim.keymap.set("n", "fr", fzf.oldfiles) +vim.keymap.set("n", "fr", recent_files) vim.keymap.set("n", "fg", fzf.live_grep) vim.keymap.set("n", "fG", function() fzf.live_grep({ cwd = vim.fn.expand("%:p:h") })