feat: actions for sending oil entries to quickfix (#249)

* Implement actions for sending oil entries to quickfix/location-list

* Use vim.notify instead of vim.notify_once in util quickfix function

* Remove redundant files/directories options for sending to qf

always send just files

* set qflist/loclist with a single call

* Add type annotations and default values for send_to_quickfix

* In visual mode, send only selected items to qf
This commit is contained in:
Luka Potočnik 2023-12-08 06:01:13 +01:00 committed by GitHub
parent b3c24f4b3b
commit 3ffb8309e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 11 deletions

View file

@ -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()

View file

@ -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)

View file

@ -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