diff --git a/doc/telescope.txt b/doc/telescope.txt index 832e4a5..06815c8 100644 --- a/doc/telescope.txt +++ b/doc/telescope.txt @@ -373,8 +373,9 @@ builtin.file_browser({opts}) *builtin.file_browser()* {opts} (table) options to pass to the picker Fields: ~ - {cwd} (string) directory path to browse (default is cwd) - {depth} (number) file tree depth to display (default is 1) + {cwd} (string) directory path to browse (default is cwd) + {depth} (number) file tree depth to display (default is 1) + {dir_icon} (string) change the icon for a directory. default:  builtin.treesitter() *builtin.treesitter()* diff --git a/lua/telescope/actions/set.lua b/lua/telescope/actions/set.lua index e790e34..855400f 100644 --- a/lua/telescope/actions/set.lua +++ b/lua/telescope/actions/set.lua @@ -13,7 +13,7 @@ local a = vim.api local log = require('telescope.log') -local path = require('telescope.path') +local Path = require('plenary.path') local state = require('telescope.state') local action_state = require('telescope.actions.state') @@ -130,7 +130,7 @@ action_set.edit = function(prompt_bufnr, command) -- check if we didn't pick a different buffer -- prevents restarting lsp server if vim.api.nvim_buf_get_name(0) ~= filename or command ~= "edit" then - filename = path.normalize(vim.fn.fnameescape(filename), vim.loop.cwd()) + filename = Path:new(vim.fn.fnameescape(filename)):normalize(vim.loop.cwd()) vim.cmd(string.format("%s %s", command, filename)) end end diff --git a/lua/telescope/algos/fzy.lua b/lua/telescope/algos/fzy.lua index 93206a9..f6622d0 100644 --- a/lua/telescope/algos/fzy.lua +++ b/lua/telescope/algos/fzy.lua @@ -7,10 +7,12 @@ -- > matches on consecutive letters and starts of words. This allows matching -- > using acronyms or different parts of the path." - J Hawthorn -local has_path, path = pcall(require, 'telescope.path') +local has_path, Path = pcall(require, 'plenary.path') if not has_path then - path = { - separator = '/' + Path = { + path = { + separator = '/' + } } end @@ -56,10 +58,10 @@ end local function precompute_bonus(haystack) local match_bonus = {} - local last_char = path.separator + local last_char = Path.path.sep for i = 1, string.len(haystack) do local this_char = haystack:sub(i, i) - if last_char == path.separator then + if last_char == Path.path.sep then match_bonus[i] = SCORE_MATCH_SLASH elseif last_char == "-" or last_char == "_" or last_char == " " then match_bonus[i] = SCORE_MATCH_WORD diff --git a/lua/telescope/builtin/files.lua b/lua/telescope/builtin/files.lua index 9aee76a..d1e80f7 100644 --- a/lua/telescope/builtin/files.lua +++ b/lua/telescope/builtin/files.lua @@ -47,10 +47,9 @@ files.live_grep = function(opts) end, vim.api.nvim_list_bufs()) if not next(bufnrs) then return end - local tele_path = require'telescope.path' for _, bufnr in ipairs(bufnrs) do local file = vim.api.nvim_buf_get_name(bufnr) - table.insert(filelist, tele_path.make_relative(file, opts.cwd)) + table.insert(filelist, Path:new(file):make_relative(opts.cwd)) end elseif search_dirs then for i, path in ipairs(search_dirs) do @@ -242,6 +241,10 @@ end files.file_browser = function(opts) opts = opts or {} + local is_dir = function(value) + return value:sub(-1, -1) == os_sep + end + opts.depth = opts.depth or 1 opts.cwd = opts.cwd and vim.fn.expand(opts.cwd) or vim.loop.cwd() opts.new_finder = opts.new_finder or function(path) @@ -258,18 +261,53 @@ files.file_browser = function(opts) }) table.insert(data, 1, '..' .. os_sep) - return finders.new_table { - results = data, - entry_maker = (function() - local tele_path = require'telescope.path' - local gen = make_entry.gen_from_file(opts) - return function(entry) - local tmp = gen(entry) - tmp.ordinal = tele_path.make_relative(entry, opts.cwd) - return tmp + local maker = function() + local mt = {} + mt.cwd = opts.cwd + mt.display = function(entry) + local hl_group + local display = utils.transform_path(opts, entry.value) + if is_dir(entry.value) then + display = display .. os_sep + if not opts.disable_devicons then + display = (opts.dir_icon or "") .. " " .. display + hl_group = "Default" + end + else + display, hl_group = utils.transform_devicons(entry.value, display, opts.disable_devicons) end - end)() - } + + if hl_group then + return display, { { {1, 3}, hl_group } } + else + return display + end + end + + mt.__index = function(t, k) + local raw = rawget(mt, k) + if raw then return raw end + + if k == "path" then + local retpath = Path:new({t.cwd, t.value}):absolute() + if not vim.loop.fs_access(retpath, "R", nil) then + retpath = t.value + end + if is_dir(t.value) then retpath = retpath .. os_sep end + return retpath + end + + return rawget(t, rawget({ value = 1 }, k)) + end + + return function(line) + local tbl = {line} + tbl.ordinal = Path:new(line):make_relative(opts.cwd) + return setmetatable(tbl, mt) + end + end + + return finders.new_table { results = data, entry_maker = maker() } end pickers.new(opts, { @@ -279,7 +317,7 @@ files.file_browser = function(opts) sorter = conf.file_sorter(opts), attach_mappings = function(prompt_bufnr, map) action_set.select:replace_if(function() - return action_state.get_selected_entry().path:sub(-1) == os_sep + return is_dir(action_state.get_selected_entry().path) end, function() local new_cwd = vim.fn.expand(action_state.get_selected_entry().path:sub(1, -2)) local current_picker = action_state.get_current_picker(prompt_bufnr) @@ -299,7 +337,7 @@ files.file_browser = function(opts) end local fpath = current_picker.cwd .. os_sep .. file - if string.sub(fpath, -1) ~= os_sep then + if not is_dir(fpath) then actions.close(prompt_bufnr) Path:new(fpath):touch({ parents = true }) vim.cmd(string.format(':e %s', fpath)) diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua index 7cce3d9..8e7f5ec 100644 --- a/lua/telescope/builtin/init.lua +++ b/lua/telescope/builtin/init.lua @@ -101,6 +101,7 @@ builtin.fd = builtin.find_files ---@param opts table: options to pass to the picker ---@field cwd string: directory path to browse (default is cwd) ---@field depth number: file tree depth to display (default is 1) +---@field dir_icon string: change the icon for a directory. default:  builtin.file_browser = require('telescope.builtin.files').file_browser --- Lists function names, variables, and other symbols from treesitter queries diff --git a/lua/telescope/builtin/internal.lua b/lua/telescope/builtin/internal.lua index ef34ca9..b157ee2 100644 --- a/lua/telescope/builtin/internal.lua +++ b/lua/telescope/builtin/internal.lua @@ -3,7 +3,7 @@ local action_set = require('telescope.actions.set') local action_state = require('telescope.actions.state') local finders = require('telescope.finders') local make_entry = require('telescope.make_entry') -local path = require('telescope.path') +local Path = require('plenary.path') local pickers = require('telescope.pickers') local previewers = require('telescope.previewers') local sorters = require('telescope.sorters') @@ -135,7 +135,7 @@ internal.symbols = function(opts) local results = {} for _, source in ipairs(sources) do - local data = vim.fn.json_decode(path.read_file(source)) + local data = vim.fn.json_decode(Path:new(source):read()) for _, entry in ipairs(data) do table.insert(results, entry) end @@ -346,8 +346,9 @@ end internal.vim_options = function(opts) -- Load vim options. - local vim_opts = loadfile(utils.data_directory() .. path.separator .. 'options' .. - path.separator .. 'options.lua')().options + local vim_opts = loadfile( + Path:new({utils.data_directory(), 'options', 'options.lua'}):absolute() + )().options pickers.new(opts, { prompt = 'options', @@ -449,7 +450,7 @@ internal.help_tags = function(opts) local delimiter = string.char(9) for _, lang in ipairs(langs) do for _, file in ipairs(tag_files[lang] or {}) do - local lines = vim.split(path.read_file(file), '\n', true) + local lines = vim.split(Path:new(file):read(), '\n', true) for _, line in ipairs(lines) do -- TODO: also ignore tagComment starting with ';' if not line:match'^!_TAG_' then diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index e0b58c6..12da181 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -1,8 +1,6 @@ local entry_display = require('telescope.pickers.entry_display') -local path = require('telescope.path') local utils = require('telescope.utils') local strings = require('plenary.strings') - local Path = require('plenary.path') local treesitter_type_highlight = { @@ -88,7 +86,7 @@ do if raw then return raw end if k == "path" then - local retpath = t.cwd .. path.separator .. t.value + local retpath = Path:new({t.cwd, t.value}):absolute() if not vim.loop.fs_access(retpath, "R", nil) then retpath = t.value end @@ -146,7 +144,7 @@ do if Path:new(t.filename):is_absolute() then return t.filename, false else - return t.cwd .. path.separator .. t.filename, false + return Path:new({t.cwd, t.filename}):absolute(), false end end, @@ -446,7 +444,7 @@ function make_entry.gen_from_buffer(opts) return function(entry) local bufname = entry.info.name ~= "" and entry.info.name or '[No Name]' -- if bufname is inside the cwd, trim that part of the string - bufname = path.normalize(bufname, cwd) + bufname = Path:new(bufname):normalize(cwd) local hidden = entry.info.hidden == 1 and 'h' or 'a' local readonly = vim.api.nvim_buf_get_option(entry.bufnr, 'readonly') and '=' or ' ' @@ -815,7 +813,7 @@ function make_entry.gen_from_ctags(opts) opts = opts or {} local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd()) - local current_file = path.normalize(vim.fn.expand('%'), cwd) + local current_file = Path:new(vim.fn.expand('%')):normalize(cwd) local display_items = { { remaining = true }, @@ -1106,10 +1104,9 @@ function make_entry.gen_from_git_status(opts) status = mod, ordinal = entry, display = make_display, - path = opts.cwd .. path.separator .. file + path = Path:new({opts.cwd, file}):absolute() } end end - return make_entry diff --git a/lua/telescope/path.lua b/lua/telescope/path.lua index 0d17c1a..f69fca6 100644 --- a/lua/telescope/path.lua +++ b/lua/telescope/path.lua @@ -1,6 +1,7 @@ +local log = require('telescope.log') + local path = {} --- TODO: Can we use vim.loop for this? path.separator = package.config:sub(1, 1) path.home = vim.fn.expand("~") @@ -86,4 +87,9 @@ path.read_file_async = function(filepath, callback) end) end -return path +return setmetatable({}, { + __index = function(_, k) + log.error("telescope.path is deprecated. please use plenary.path instead") + return path[k] + end +}) diff --git a/lua/telescope/previewers/buffer_previewer.lua b/lua/telescope/previewers/buffer_previewer.lua index f2f49b9..1e884d0 100644 --- a/lua/telescope/previewers/buffer_previewer.lua +++ b/lua/telescope/previewers/buffer_previewer.lua @@ -1,5 +1,5 @@ local from_entry = require('telescope.from_entry') -local path = require('telescope.path') +local Path = require('plenary.path') local utils = require('telescope.utils') local putils = require('telescope.previewers.utils') local Previewer = require('telescope.previewers.previewer') @@ -39,7 +39,7 @@ color_hash[6] = function(line) end local colorize_ls = function(bufnr, data, sections) - local windows_add = path.separator == '\\' and 2 or 0 + local windows_add = Path.path.sep == '\\' and 2 or 0 for lnum, line in ipairs(data) do local section = sections[lnum] for i = 1, section[1].end_index - 1 do -- Highlight permissions @@ -97,7 +97,7 @@ previewers.file_maker = function(filepath, bufnr, opts) if opts.callback then opts.callback(bufnr) end end)}) else - path.read_file_async(filepath, vim.schedule_wrap(function(data) + Path:new(filepath):_read_async(vim.schedule_wrap(function(data) if not vim.api.nvim_buf_is_valid(bufnr) then return end local ok = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, vim.split(data, '[\r]?\n')) if not ok then return end @@ -273,7 +273,7 @@ previewers.cat = defaulter(function(opts) return previewers.new_buffer_previewer { title = "File Preview", dyn_title = function(_, entry) - return path.normalize(from_entry.path(entry, true), cwd) + return Path:new(from_entry.path(entry, true)):normalize(cwd) end, get_buffer_by_name = function(_, entry) @@ -307,7 +307,7 @@ previewers.vimgrep = defaulter(function(opts) return previewers.new_buffer_previewer { title = "Grep Preview", dyn_title = function(_, entry) - return path.normalize(from_entry.path(entry, true), cwd) + return Path:new(from_entry.path(entry, true)):normalize(cwd) end, setup = function() @@ -614,7 +614,7 @@ previewers.git_commit_diff_as_was = defaulter(function(opts) define_preview = function(self, entry, status) local cmd = { 'git', '--no-pager', 'show' } - local cf = opts.current_file and path.make_relative(opts.current_file, opts.cwd) + local cf = opts.current_file and Path:new(opts.current_file):make_relative(opts.cwd) local value = cf and (entry.value .. ':' .. cf) or (entry.value) local ft = cf and pfiletype.detect(value) or 'diff' table.insert(cmd, value) diff --git a/lua/telescope/previewers/term_previewer.lua b/lua/telescope/previewers/term_previewer.lua index 299b52e..a7a0f72 100644 --- a/lua/telescope/previewers/term_previewer.lua +++ b/lua/telescope/previewers/term_previewer.lua @@ -1,6 +1,6 @@ local conf = require('telescope.config').values local utils = require('telescope.utils') -local path = require('telescope.path') +local Path = require('plenary.path') local putils = require('telescope.previewers.utils') local from_entry = require('telescope.from_entry') local Previewer = require('telescope.previewers.previewer') @@ -239,7 +239,7 @@ previewers.cat = defaulter(function(opts) return previewers.new_termopen_previewer { title = "File Preview", dyn_title = function(_, entry) - return path.normalize(from_entry.path(entry, true), cwd) + return Path:new(from_entry.path(entry, true)):normalize(cwd) end, get_command = function(entry) @@ -260,7 +260,7 @@ previewers.vimgrep = defaulter(function(opts) return previewers.new_termopen_previewer { title = "Grep Preview", dyn_title = function(_, entry) - return path.normalize(from_entry.path(entry, true), cwd) + return Path:new(from_entry.path(entry, true)):normalize(cwd) end, get_command = function(entry, status) @@ -293,7 +293,7 @@ previewers.qflist = defaulter(function(opts) return previewers.new_termopen_previewer { title = "Grep Preview", dyn_title = function(_, entry) - return path.normalize(from_entry.path(entry, true), cwd) + return Path:new(from_entry.path(entry, true)):normalize(cwd) end, get_command = function(entry, status) diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua index b8d2b6b..bb48c2c 100644 --- a/lua/telescope/utils.lua +++ b/lua/telescope/utils.lua @@ -1,12 +1,12 @@ local has_devicons, devicons = pcall(require, 'nvim-web-devicons') -local pathlib = require('telescope.path') +local Path = require('plenary.path') local Job = require('plenary.job') local utils = {} utils.get_separator = function() - return pathlib.separator + return Path.path.sep end utils.if_nil = function(x, was_nil, was_not_nil) @@ -251,21 +251,6 @@ utils.diagnostics_to_tbl = function(opts) return items end --- TODO: Figure out how to do this... could include in plenary :) --- NOTE: Don't use this yet. It will segfault sometimes. --- --- opts.shorten_path and function(value) --- local result = { --- valid = true, --- display = utils.path_shorten(value), --- ordinal = value, --- value = value --- } - --- return result --- end or nil) -utils.path_shorten = pathlib.shorten - utils.path_tail = (function() local os_sep = utils.get_separator() local match_string = '[^' .. os_sep .. ']*$' @@ -304,11 +289,11 @@ utils.transform_path = function(opts, path) else cwd = vim.loop.cwd(); end - transformed_path = pathlib.make_relative(transformed_path, cwd) + transformed_path = Path:new(transformed_path):make_relative(cwd) end if vim.tbl_contains(path_display, "shorten") then - transformed_path = pathlib.shorten(transformed_path) + transformed_path = Path:new(transformed_path):shorten() end end @@ -397,7 +382,7 @@ function utils.data_directory() local sourced_file = require('plenary.debug_utils').sourced_filepath() local base_directory = vim.fn.fnamemodify(sourced_file, ":h:h:h") - return base_directory .. pathlib.separator .. 'data' .. pathlib.separator + return Path:new({base_directory, 'data'}):absolute() .. Path.path.sep end function utils.display_termcodes(str)