diff --git a/lua/oil/actions.lua b/lua/oil/actions.lua index 8064f9b..ffab753 100644 --- a/lua/oil/actions.lua +++ b/lua/oil/actions.lua @@ -337,6 +337,46 @@ M.toggle_trash = { end, } +M.send_to_qflist = { + desc = "Sends files in the current oil directory to the quickfix list, replacing the previous entries.", + callback = function() + util.send_to_quickfix({ + target = "qflist", + mode = "r", + }) + end, +} + +M.add_to_qflist = { + desc = "Adds files in the current oil directory to the quickfix list, keeping the previous entries.", + callback = function() + util.send_to_quickfix({ + target = "qflist", + mode = "a", + }) + end, +} + +M.send_to_loclist = { + desc = "Sends files in the current oil directory to the location list, replacing the previous entries.", + callback = function() + util.send_to_quickfix({ + target = "loclist", + mode = "r", + }) + end, +} + +M.add_to_loclist = { + desc = "Adds files in the current oil directory to the location list, keeping the previous entries.", + callback = function() + util.send_to_quickfix({ + target = "loclist", + mode = "a", + }) + end, +} + ---List actions for documentation generation ---@private M._get_actions = function() diff --git a/lua/oil/init.lua b/lua/oil/init.lua index 888c812..96df42e 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -456,20 +456,12 @@ M.select = function(opts, callback) return finish("Could not find adapter for current buffer") end - local mode = vim.api.nvim_get_mode().mode - local is_visual = mode:match("^[vV]") + local visual_range = util.get_visual_range() ---@type oil.Entry[] local entries = {} - if is_visual then - -- This is the best way to get the visual selection at the moment - -- https://github.com/neovim/neovim/pull/13896 - local _, start_lnum, _, _ = unpack(vim.fn.getpos("v")) - local _, end_lnum, _, _, _ = unpack(vim.fn.getcurpos()) - if start_lnum > end_lnum then - start_lnum, end_lnum = end_lnum, start_lnum - end - for i = start_lnum, end_lnum do + if visual_range then + for i = visual_range.start_lnum, visual_range.end_lnum do local entry = M.get_entry_on_line(0, i) if entry then table.insert(entries, entry) diff --git a/lua/oil/util.lua b/lua/oil/util.lua index 027b5db..81de100 100644 --- a/lua/oil/util.lua +++ b/lua/oil/util.lua @@ -697,4 +697,66 @@ M.adapter_list_all = function(adapter, url, opts, callback) end) end +---Send files from the current oil directory to quickfix +---based on the provided options. +---@param opts {target?: "qflist"|"loclist", mode?: "r"|"a"} +M.send_to_quickfix = function(opts) + if type(opts) ~= "table" then + opts = {} + end + local oil = require("oil") + local dir = oil.get_current_dir() + if type(dir) ~= "string" then + return + end + local range = M.get_visual_range() + if not range then + range = { start_lnum = 1, end_lnum = vim.fn.line("$") } + end + local qf_entries = {} + for i = range.start_lnum, range.end_lnum do + local entry = oil.get_entry_on_line(0, i) + if entry and entry.type == "file" then + local qf_entry = { + filename = dir .. entry.name, + lnum = 1, + col = 1, + text = entry.name, + } + table.insert(qf_entries, qf_entry) + end + end + if #qf_entries == 0 then + vim.notify("[oil] No entries found to send to quickfix", vim.log.levels.WARN) + return + end + vim.api.nvim_exec_autocmds("QuickFixCmdPre", {}) + local qf_title = "oil files" + local mode = opts.mode == "a" and "a" or "r" + if opts.target == "loclist" then + vim.fn.setloclist(0, {}, mode, { title = qf_title, items = qf_entries }) + else + vim.fn.setqflist({}, mode, { title = qf_title, items = qf_entries }) + end + vim.api.nvim_exec_autocmds("QuickFixCmdPost", {}) +end + +---Get the current visual selection range. If not in visual mode, return nil. +---@return {start_lnum: integer, end_lnum: integer}? +M.get_visual_range = function() + local mode = vim.api.nvim_get_mode().mode + local is_visual = mode:match("^[vV]") + if not is_visual then + return + end + -- This is the best way to get the visual selection at the moment + -- https://github.com/neovim/neovim/pull/13896 + local _, start_lnum, _, _ = unpack(vim.fn.getpos("v")) + local _, end_lnum, _, _, _ = unpack(vim.fn.getcurpos()) + if start_lnum > end_lnum then + start_lnum, end_lnum = end_lnum, start_lnum + end + return { start_lnum = start_lnum, end_lnum = end_lnum } +end + return M