nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.
MIT License
15.77k stars 833 forks source link

find_files hijack netrw #2806

Open pbnj-dragon opened 10 months ago

pbnj-dragon commented 10 months ago

Is your feature request related to a problem? Please describe.

telescope-file-browser.nvim supports hijacking netrw such that when users run nvim ., the file browser extension will display results instead of netrw.

This functionality would be useful in the builtin file fuzzy finder instead of a full-fledged file browser extension that can search, copy, move, and delete files.

Describe the solution you'd like

find_files picker can support hijack_netrw = true configuration option:

      telescope.setup({
        pickers = {
          find_files = {
            hijack_netrw = true,
          },
        },
      })

Once this is configured, running nvim . should open neovim with "Find Files" picker.

Describe alternatives you've considered

telescope-file-browser.nvim, but this has drawbacks:

  1. Does not fuzzy search through nested directories; only fuzzy searches on the current directory.
  2. Requires an additional plugin
jamestrew commented 10 months ago

I don't think hijack_netrw is an adequate option for find_files. Mix of technical and "philosophical".

If all you want is to have find_files open every time you launch neovim, aliasing nvim with nvim +"Telescope find_files" should work.

MarcoBuess commented 10 months ago

I guess what @pbnj-dragon desires, probably much like me, is that when opening a folder e.g. through e: or when starting nvim with a folder, find_files can hook into that. I'm too using the telescope-file-browser extension to get that specific behavior, but it is not exactly working like find_files, which is imo what is more desireable. Who want's to manually browse the folder structure am I right?

PS: It might be worth noting that I'm using this autocmd to achive the startup behavior:

local find_files_on_startup = vim.api.nvim_create_augroup("find_files_on_startup", { clear = true })
vim.api.nvim_create_autocmd("VimEnter", {
    group = find_files_on_startup,
    pattern = "*",
    callback = function()
        if vim.fn.isdirectory(vim.fn.expand("%:p")) ~= 0 then
            local current_dir = vim.fn.expand("%:p:h")
            require("telescope.builtin").find_files({ cwd = current_dir })
        end
    end,
})

Thinking about this e: might also be solvable that way but I'm not sure which event to trigger on.

MarcoBuess commented 10 months ago

So I borrowed a bunch of code from telescope-file-browser's hijack_netrw() function and came up with the following autocmd:

local find_files_on_edit = vim.api.nvim_create_augroup("find_files_on_edit", { clear = true })
-- clear FileExplorer appropriately to prevent netrw from launching on folders
-- netrw may or may not be loaded before telescope-find-files
-- conceptual credits to nvim-tree and telescope-file-browser
vim.api.nvim_create_autocmd("VimEnter", {
    pattern = "*",
    once = true,
    callback = function()
        pcall(vim.api.nvim_clear_autocmds, { group = "FileExplorer" })
    end,
})
vim.api.nvim_create_autocmd("BufEnter", {
    group = find_files_on_edit,
    pattern = "*",
    callback = function()
        local netrw_bufname

        vim.schedule(function()
            -- Don't launch if current buffer is netrw
            if vim.bo[0].filetype == "netrw" then
                return
            end

            local bufname = vim.api.nvim_buf_get_name(0)
            if vim.fn.isdirectory(bufname) == 0 then
                _, netrw_bufname = pcall(vim.fn.expand, "#:p:h")
                return
            end

            -- prevents reopening of find_files if exiting without selecting a file
            if netrw_bufname == bufname then
                netrw_bufname = nil
                return
            else
                netrw_bufname = bufname
            end

            -- ensure no buffers remain with the directory name
            vim.api.nvim_buf_set_option(0, "bufhidden", "wipe")

            require("telescope.builtin").find_files({
                cwd = vim.fn.expand("%:p:h"),
            })
        end)
    end,
})

this seems to achieve the desired behavior but might be flawed. I'm no lua dev, so please use at your own risk. I'd rather see the functionality implemented in the plugin by someone who knows what hes doing 😉 .

Cheers

EDIT: Looks like this even allowed me to get rid of my startup autocmd as this is now covered as well.

MarcoBuess commented 9 months ago

Was able to condense the code further. This should suffice:

local find_files_hijack_netrw = vim.api.nvim_create_augroup("find_files_hijack_netrw", { clear = true })
-- clear FileExplorer appropriately to prevent netrw from launching on folders
-- netrw may or may not be loaded before telescope-find-files
-- conceptual credits to nvim-tree and telescope-file-browser
vim.api.nvim_create_autocmd("VimEnter", {
    pattern = "*",
    once = true,
    callback = function()
        pcall(vim.api.nvim_clear_autocmds, { group = "FileExplorer" })
    end,
})
vim.api.nvim_create_autocmd("BufEnter", {
    group = find_files_hijack_netrw,
    pattern = "*",
    callback = function()
        vim.schedule(function()
            -- Early return if netrw or not a directory
            if vim.bo[0].filetype == "netrw" or vim.fn.isdirectory(vim.fn.expand("%:p")) == 0 then
                return
            end

            vim.api.nvim_buf_set_option(0, "bufhidden", "wipe")

            require("telescope.builtin").find_files({
                cwd = vim.fn.expand("%:p:h"),
            })
        end)
    end,
})