| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- -- recentf.lua
- -- Track and access recently opened files (like Emacs recentf-mode)
- -- ============================================================================
- local recentf = {}
- -- Configuration
- recentf.config = {
- enabled = true,
- max_saved = 20, -- Maximum number of recent files to track
- exclude_patterns = { -- Patterns to exclude from recent files
- "^/tmp/",
- "%.git/",
- "COMMIT_EDITMSG$",
- },
- }
- -- Recent files list (most recent first)
- recentf.list = {}
- -- Check if a file should be excluded
- local function should_exclude(filepath)
- if not filepath or filepath == "" then
- return true
- end
- -- Exclude *scratch* and other special buffers
- if filepath:match("^%*") then
- return true
- end
- for _, pattern in ipairs(recentf.config.exclude_patterns) do
- if filepath:match(pattern) then
- return true
- end
- end
- return false
- end
- -- Add a file to the recent list
- function recentf.add(filepath)
- if should_exclude(filepath) then
- return
- end
- -- Remove if already in list (to move to front)
- for i, f in ipairs(recentf.list) do
- if f == filepath then
- table.remove(recentf.list, i)
- break
- end
- end
- -- Add to front
- table.insert(recentf.list, 1, filepath)
- -- Trim to max size
- while #recentf.list > recentf.config.max_saved do
- table.remove(recentf.list)
- end
- end
- -- Get the recent files list
- function recentf.get_list()
- return recentf.list
- end
- -- Clear the recent files list
- function recentf.clear()
- recentf.list = {}
- end
- -- Open a recent file by index (1-based)
- function recentf.open(index)
- local idx = tonumber(index)
- if not idx or idx < 1 or idx > #recentf.list then
- return {success = false, message = "Invalid index: " .. tostring(index)}
- end
- local filepath = recentf.list[idx]
- return editor:execute_command("find-file", {filepath})
- end
- -- Format the recent files list for display
- function recentf.format_list()
- local lines = {}
- for i, filepath in ipairs(recentf.list) do
- -- Shorten home directory
- local display = filepath:gsub("^" .. os.getenv("HOME"), "~")
- table.insert(lines, string.format("%2d: %s", i, display))
- end
- return lines
- end
- -- Setup function
- function recentf.setup(opts)
- opts = opts or {}
- for k, v in pairs(opts) do
- recentf.config[k] = v
- end
- if not recentf.config.enabled then
- return
- end
- -- Register commands
- editor:register_command("recentf-open", "Open a recent file by number", function(args)
- if #args == 0 then
- -- List recent files
- local list = recentf.format_list()
- if #list == 0 then
- return {success = true, message = "No recent files"}
- end
- -- Show in echo area (up to 5 files)
- local preview = {}
- for i = 1, math.min(5, #list) do
- table.insert(preview, list[i])
- end
- local msg = table.concat(preview, " | ")
- if #list > 5 then
- msg = msg .. " ..."
- end
- return {success = true, message = msg}
- end
- return recentf.open(args[1])
- end, {}, true, "n")
- editor:register_command("recentf-list", "List all recent files", function(args)
- local list = recentf.format_list()
- if #list == 0 then
- return {success = true, message = "No recent files"}
- end
- -- Use echo area for multi-line display
- editor:set_echo_area(list)
- return {success = true, message = ""}
- end)
- editor:register_command("recentf-clear", "Clear the recent files list", function(args)
- recentf.clear()
- return {success = true, message = "Recent files list cleared"}
- end)
- -- Key binding (similar to Emacs)
- editor:bind_key("C-x C-r", "recentf-open", "Open recent file")
- -- Hook into find-file to track opens
- -- We'll expose a global function that the C++ can call
- lumacs.recentf_track = function(filepath)
- recentf.add(filepath)
- end
- print("[Lua] recentf package loaded")
- end
- -- Auto-setup with defaults
- recentf.setup()
- return recentf
|