stevearc / oil.nvim

Neovim file explorer: edit your filesystem like a buffer
MIT License
4.12k stars 122 forks source link

feature request: send a subset of files to the quickfixlist #522

Open Janshagen opened 4 days ago

Janshagen commented 4 days ago

Did you check existing requests?

Describe the feature

The ability to send all files in a directory to the quickfixlist was recently added (https://github.com/stevearc/oil.nvim/issues/223). An obvious extension would be to only send some of the selected files, either only the visually selected files, or something more clever

Provide background

Example: You would like to do some quickfix-edit to some files in a directory, but there are also a lot of files that you do not want to edit. I want a good way to add only some of the files

What is the significance of this feature?

nice to have

Additional details

I have adapted the code mentioned above to work for visually selected lines (without breaking the prior behavior):

local function selected_oil_files_to_quickfix()
    if vim.bo.filetype ~= "oil" then
        return
    end

    local start_line = 1
    local end_line = vim.fn.line("$")

    local mode = vim.fn.mode()
    if mode == "v" or mode == "V" or mode == "\22" then
        start_line = vim.fn.line("v")
        end_line = vim.fn.line(".")

        if start_line > end_line then
            start_line, end_line = end_line, start_line
        end
    end

    local oil = require("oil")
    local dir = oil.get_current_dir()

    local entries = {}
    for line_number = start_line, end_line do
        local entry = oil.get_entry_on_line(0, line_number)
        if entry and entry.type == "file" then
            table.insert(entries, { filename = dir .. entry.name })
        end
    end

    if #entries == 0 then
        return
    end

    vim.fn.setqflist(entries)
    return vim.cmd.copen()
end
Janshagen commented 4 days ago

Here is another version (that breaks the prior behavior) which adds the files that match the latest search pattern:

local function searched_oil_files_to_quickfix()
    if vim.bo.filetype ~= "oil" then
        return
    end

    local pattern = vim.fn.getreg("/")
    if pattern == "" then
        return
    end

    local oil = require("oil")
    local dir = oil.get_current_dir()

    local entries = {}
    for line_number = 1, vim.fn.line("$") do
        local entry = oil.get_entry_on_line(0, line_number)
        if entry and entry.name:find(pattern) and entry.type == "file" then
            table.insert(entries, { filename = dir .. entry.name })
        end
    end

    if #entries == 0 then
        return
    end

    vim.fn.setqflist(entries)
    return vim.cmd.copen()
end
Janshagen commented 4 days ago

Sorry for spamming. But I figured out a way to keep the original behavior and combining my two suggestions.

The following code adds all files that are 1. matched if highlighting of matched items is active else all files and 2. are visually selected if you are in any visual mode else all files in directory

local function selected_oil_files_to_quickfix()
    if vim.bo.filetype ~= "oil" then
        return
    end

    local oil = require("oil")
    local dir = oil.get_current_dir()

    local start_line = 1
    local end_line = vim.fn.line("$")

    local mode = vim.fn.mode()
    if mode == "v" or mode == "V" or mode == "\22" then
        start_line = vim.fn.line("v")
        end_line = vim.fn.line(".")

        if start_line > end_line then
            start_line, end_line = end_line, start_line
        end
    end

    local pattern = vim.fn.getreg("/")
    local entries = {}
    for line_number = start_line, end_line do
        local entry = oil.get_entry_on_line(0, line_number)
        if
            entry
            and entry.type == "file"
            and (vim.v.hlsearch == 0 or (vim.v.hlsearch == 1 and entry.name:find(pattern)))
        then
            table.insert(entries, { filename = dir .. entry.name })
        end
    end

    if #entries == 0 then
        return
    end

    vim.fn.setqflist(entries)
    return vim.cmd.copen()
end