GnikDroy / projections.nvim

A map to your filesystem
GNU General Public License v3.0
236 stars 8 forks source link

[feat] Search in path direct child's #38

Closed TheSnakeWitcher closed 1 year ago

TheSnakeWitcher commented 1 year ago

Is your feature request related to a problem? Please describe. I need to search projects in all direct child's directories of a path instead that in the path itself. I DON'T want this search to be recursive for performance reasons.

Describe the solution you'd like I would like an additional field child's in the workspaces table from config that control the above-mentioned behavior. Something like this:

require("projections").setup({
     -- ...
     workspaces = {
           { workspace , {patterns} , childs = true }
    }
     -- ...
})

If appropriate, have you considered any alternatives? I have considered adding manually the inner paths or run a script to save these paths in the workspaces.json file, but I consider this solution unappropriated because every time that, a new inner folder is created, is needed to repeat the same process.

Additional context My request is to be able to search my work projects easily. My work projects are organized like this:

─── Work ├── job_1 │ └── job_1_project / .git ├── job_2 │ └── job_2_project / .git ├── job_N

NOTE: I don't find a way to write these file structure more pretty like in the projections README, my bad.

GnikDroy commented 1 year ago

I think a more general approach is something like a depth= parameter where depth=2 is equivalent to childs=true. After all, someone else might come along who wants a grandchilds parameter.

I have thought about this, but searching can be pretty performance intensive at higher depth values.

The discussion from #33 is relevant here.

I like the approach by @airtonix there:

workspaces = functionThatBuildsListOfWorkSpaces("~/Projects/**/*")

You will have to writefunctionThatBuildsListOfWorkSpaces yourself. But this way I don't have to package something like ripgrep in projections. It also gives you a lot of control on how you want to build your list of workspaces.

GnikDroy commented 1 year ago

So, in your case something like:

function get_child_directories(path)
    local dirs = {}
    local dir = vim.loop.fs_scandir(path)
    if dir == nil then return dirs end
    while true do
        local file, type = vim.loop.fs_scandir_next(dir)
        if file == nil then return dirs end
        if type == "directory" then table.insert(dirs, file) end
    end
end

function build_workspaces()
    local workspaces = {
        -- add normal workspaces here
       { "~/Documents/dev" , {}}
    }

    local child_workspaces = {
        -- add workspaces that need to search child directories here
        { path = "~/Documents", patterns = { ".git", ".hg" }}
    }

    table.insert(workspaces, vim.tbl_map(
        function(ws)
            return vim.tbl_map(function(dir)
                    return { dir, ws.patterns }
                end,
                get_child_directories(vim.fs.normalize(ws.path))
            )
        end,
        child_workspaces)
    )
    return workspaces
end

Finally, you can do

require("projections").setup({
     workspaces = build_workspaces()
     ...
})
TheSnakeWitcher commented 1 year ago

Thanks, I think that should work, and congrats, I find your approach very clear and precise.