diff --git a/README.md b/README.md index fcb96126..f0a9752e 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ use { "nvim-telescope/telescope-file-browser.nvim" } Plug "nvim-telescope/telescope-file-browser.nvim" ``` +### Optional Dependencies + +`telescope-file-browser` optionally levers [fd](https://github.com/sharkdp/fd) if installed primarily for more async but also generally faster file and folder browsing, which is most noticeable in larger repositories. + # Setup and Configuration You configure the `telescope-file-browser` like any other `telescope.nvim` picker. See `:h telescope-file-browser.picker` for the full set of options dedicated to the picker. In addition, you of course can map `theme` and `mappings` as you are accustomed to from `telescope.nvim`. diff --git a/doc/telescope-file-browser.txt b/doc/telescope-file-browser.txt index 9542f893..17442bd6 100644 --- a/doc/telescope-file-browser.txt +++ b/doc/telescope-file-browser.txt @@ -89,9 +89,9 @@ fb_picker.file_browser({opts}) *fb_picker.file_browser()* (default: ) {hidden} (boolean) determines whether to show hidden files or not (default: false) - {respect_gitignore} (boolean) whether to respect_gitignore; induces - slow-down w/ plenary finder (default: - false) + {respect_gitignore} (boolean) induces slow-down w/ plenary finder + (default: false, true if `fd` + available) @@ -245,3 +245,67 @@ fb_actions.select_all({prompt_bufnr}) *fb_actions.select_all()* +================================================================================ + *telescope-file-browser.finders* + +The file browser finders power the picker with both a file and folder browser. + +fb_finders.browse_files({opts}) *fb_finders.browse_files()* + Returns a finder that is populated with files and folders in `path`. + - Notes: + - Uses `fd` if available for more async-ish browsing and speed-ups + + + Parameters: ~ + {opts} (table) options to pass to the finder + + Fields: ~ + {path} (string) root dir to browse from + {depth} (number) file tree depth to display, `false` for unlimited + (default: 1) + {hidden} (boolean) determines whether to show hidden files or not + (default: false) + + +fb_finders.browse_folders({opts}) *fb_finders.browse_folders()* + Returns a finder that is populated with (sub-)folders of `cwd`. + - Notes: + - Uses `fd` if available for more async-ish browsing and speed-ups + + + Parameters: ~ + {opts} (table) options to pass to the finder + + Fields: ~ + {cwd} (string) root dir to browse from + {depth} (number) file tree depth to display (default: 1) + {hidden} (boolean) determines whether to show hidden files or not + (default: false) + + +fb_finders.finder({opts}) *fb_finders.finder()* + Returns a finder that combines |fb_finders.browse_files| and + |fb_finders.browse_folders| into a unified finder. + + + Parameters: ~ + {opts} (table) options to pass to the picker + + Fields: ~ + {path} (string) root dir to file_browse from (default: + vim.loop.cwd()) + {cwd} (string) root dir (default: vim.loop.cwd()) + {files} (boolean) start in file (true) or folder (false) + browser (default: true) + {depth} (number) file tree depth to display (default: 1) + {dir_icon} (string) change the icon for a directory. + (default: ) + {hidden} (boolean) determines whether to show hidden files + or not (default: false) + {respect_gitignore} (boolean) induces slow-down w/ plenary finder + (default: false, true if `fd` + available) + + + + vim:tw=78:ts=8:ft=help:norl: diff --git a/lua/telescope/_extensions/file_browser/finders.lua b/lua/telescope/_extensions/file_browser/finders.lua index 95f09b8f..6b25eedf 100644 --- a/lua/telescope/_extensions/file_browser/finders.lua +++ b/lua/telescope/_extensions/file_browser/finders.lua @@ -8,6 +8,7 @@ local fb_make_entry = require "telescope._extensions.file_browser.make_entry" +local async_oneshot_finder = require "telescope.finders.async_oneshot_finder" local finders = require "telescope.finders" local scan = require "plenary.scandir" @@ -15,54 +16,87 @@ local Path = require "plenary.path" local os_sep = Path.path.sep local fb_finders = {} +local has_fd = vim.fn.executable "fd" == 1 --- Returns a finder that is populated with files and folders in `path`. +--- - Notes: +--- - Uses `fd` if available for more async-ish browsing and speed-ups ---@param opts table: options to pass to the finder ---@field path string: root dir to browse from ----@field depth number: file tree depth to display (default: 1) +---@field depth number: file tree depth to display, `false` for unlimited (default: 1) ---@field hidden boolean: determines whether to show hidden files or not (default: false) fb_finders.browse_files = function(opts) opts = opts or {} - local data = scan.scan_dir(opts.path, { - add_dirs = opts.add_dirs, - depth = opts.depth, - hidden = opts.hidden, - respect_gitignore = opts.respect_gitignore, - }) - if opts.path ~= os_sep then - table.insert(data, 1, Path:new(opts.path):parent():absolute()) - end -- returns copy with properly set cwd for entry maker - return finders.new_table { results = data, entry_maker = opts.entry_maker { cwd = opts.path } } + local entry_maker = opts.entry_maker { cwd = opts.path } + if has_fd then + local args = { "-a" } + if opts.hidden then + table.insert(args, "-H") + end + if opts.respect_gitignore == false then + table.insert(args, "--no-ignore-vcs") + end + if type(opts.depth) == "number" then + table.insert(args, "--maxdepth") + table.insert(args, opts.depth) + end + return async_oneshot_finder { + fn_command = function() + return { command = "fd", args = args } + end, + entry_maker = entry_maker, + results = { entry_maker(Path:new(opts.path):parent():absolute()) }, + cwd = opts.path, + } + else + local data = scan.scan_dir(opts.path, { + add_dirs = opts.add_dirs, + depth = opts.depth, + hidden = opts.hidden, + }) + if opts.path ~= os_sep then + table.insert(data, 1, Path:new(opts.path):parent():absolute()) + end + return finders.new_table { results = data, entry_maker = entry_maker } + end end --- Returns a finder that is populated with (sub-)folders of `cwd`. +--- - Notes: +--- - Uses `fd` if available for more async-ish browsing and speed-ups ---@param opts table: options to pass to the finder ---@field cwd string: root dir to browse from ---@field depth number: file tree depth to display (default: 1) ---@field hidden boolean: determines whether to show hidden files or not (default: false) fb_finders.browse_folders = function(opts) - -- TODO(fdschmidt93): how to add current folder in `fd` - -- if vim.fn.executable "fd" == 1 then - -- local cmd = { "fd", "-t", "d", "-a" } - -- if opts.hidden then - -- table.insert(cmd, "-H") - -- end - -- if not opts.respect_gitignore then - -- table.insert(cmd, "-I") - -- end - -- return finders.new_oneshot_job( - -- cmd, - -- { entry_maker = opts.entry_maker { cwd = opts.cwd, fd_finder = true }, cwd = opts.cwd } - -- ) - -- else - local data = scan.scan_dir(opts.cwd, { - hidden = opts.hidden, - only_dirs = true, - respect_gitignore = opts.respect_gitignore, - }) - table.insert(data, 1, opts.cwd) - return finders.new_table { results = data, entry_maker = opts.entry_maker { cwd = opts.cwd } } + -- returns copy with properly set cwd for entry maker + local entry_maker = opts.entry_maker { cwd = opts.cwd } + if has_fd then + local args = { "-t", "d", "-a" } + if opts.hidden then + table.insert(args, "-H") + end + if opts.respect_gitignore == false then + table.insert(args, "--no-ignore-vcs") + end + return async_oneshot_finder { + fn_command = function() + return { command = "fd", args = args } + end, + entry_maker = entry_maker, + results = { entry_maker(opts.cwd) }, + cwd = opts.cwd, + } + else + local data = scan.scan_dir(opts.cwd, { + hidden = opts.hidden, + only_dirs = true, + respect_gitignore = opts.respect_gitignore, + }) + table.insert(data, 1, opts.cwd) + return finders.new_table { results = data, entry_maker = entry_maker } + end end --- Returns a finder that combines |fb_finders.browse_files| and |fb_finders.browse_folders| into a unified finder. @@ -73,6 +107,7 @@ end ---@field depth number: file tree depth to display (default: 1) ---@field dir_icon string: change the icon for a directory. (default: ) ---@field hidden boolean: determines whether to show hidden files or not (default: false) +---@field respect_gitignore boolean: induces slow-down w/ plenary finder (default: false, true if `fd` available) fb_finders.finder = function(opts) opts = opts or {} -- cache entries such that multi selections are maintained across {file, folder}_browsers @@ -85,7 +120,7 @@ fb_finders.finder = function(opts) add_dirs = vim.F.if_nil(opts.add_dirs, true), hidden = vim.F.if_nil(opts.hidden, false), depth = vim.F.if_nil(opts.depth, 1), -- depth for file browser - respect_gitignore = vim.F.if_nil(opts.respect_gitignore, false), -- opt-in + respect_gitignore = vim.F.if_nil(opts.respect_gitignore, has_fd), files = vim.F.if_nil(opts.files, true), -- file or folders mode -- ensure we forward make_entry opts adequately entry_maker = vim.F.if_nil(opts.entry_maker, function(local_opts) diff --git a/lua/telescope/_extensions/file_browser/picker.lua b/lua/telescope/_extensions/file_browser/picker.lua index c1c6e4ff..0911472d 100644 --- a/lua/telescope/_extensions/file_browser/picker.lua +++ b/lua/telescope/_extensions/file_browser/picker.lua @@ -47,7 +47,7 @@ local fb_picker = {} ---@field depth number: file tree depth to display, false for unlimited depth (default: 1) ---@field dir_icon string: change the icon for a directory. (default: ) ---@field hidden boolean: determines whether to show hidden files or not (default: false) ----@field respect_gitignore boolean: whether to respect_gitignore; induces slow-down w/ plenary finder (default: false) +---@field respect_gitignore boolean: induces slow-down w/ plenary finder (default: false, true if `fd` available) fb_picker.file_browser = function(opts) opts = opts or {} diff --git a/scripts/gendocs.lua b/scripts/gendocs.lua index ac114d6c..a542601e 100644 --- a/scripts/gendocs.lua +++ b/scripts/gendocs.lua @@ -7,7 +7,7 @@ docs.test = function() "./lua/telescope/_extensions/file_browser.lua", "./lua/telescope/_extensions/file_browser/picker.lua", "./lua/telescope/_extensions/file_browser/actions.lua", - "./lua/telescope/_extensions/file_browser/finder.lua", + "./lua/telescope/_extensions/file_browser/finders.lua", } local output_file = "./doc/telescope-file-browser.txt"