diff --git a/doc/telescope.txt b/doc/telescope.txt index 2388431..b241b27 100644 --- a/doc/telescope.txt +++ b/doc/telescope.txt @@ -270,18 +270,19 @@ telescope.setup({opts}) *telescope.setup()* Determines how file paths are displayed. path_display can be set to an array with a combination of: - - "hidden" hide file names - - "tail" only display the file name, and not the path - - "absolute" display absolute paths - - "smart" remove as much from the path as possible to only show - the difference between the displayed paths. - Warning: The nature of the algorithm might have a negative - performance impact! - - "shorten" only display the first character of each directory in - the path - - "truncate" truncates the start of the path when the whole path will - not fit. To increase the gap between the path and the edge, - set truncate to number `truncate = 3` + - "hidden" hide file names + - "tail" only display the file name, and not the path + - "absolute" display absolute paths + - "smart" remove as much from the path as possible to only show + the difference between the displayed paths. + Warning: The nature of the algorithm might have a negative + performance impact! + - "shorten" only display the first character of each directory in + the path + - "truncate" truncates the start of the path when the whole path will + not fit. To increase the gap between the path and the edge, + set truncate to number `truncate = 3` + - "filename_first" shows filenames first and then the directories You can also specify the number of characters of each directory name to keep by setting `path_display.shorten = num`. @@ -306,6 +307,21 @@ telescope.setup({opts}) *telescope.setup()* will give a path like: `al/beta/gamma/de` + path_display can also be set to 'filename_first' to put the filename + in front. + + path_display = { + "filename_first" + }, + + The directory structure can be reversed as follows: + + path_display = { + filename_first = { + reverse_directories = true + } + }, + path_display can also be set to 'hidden' string to hide file names path_display can also be set to a function for custom formatting of diff --git a/lua/telescope/config.lua b/lua/telescope/config.lua index 38267a6..11404ea 100644 --- a/lua/telescope/config.lua +++ b/lua/telescope/config.lua @@ -304,18 +304,19 @@ append( Determines how file paths are displayed. path_display can be set to an array with a combination of: - - "hidden" hide file names - - "tail" only display the file name, and not the path - - "absolute" display absolute paths - - "smart" remove as much from the path as possible to only show - the difference between the displayed paths. - Warning: The nature of the algorithm might have a negative - performance impact! - - "shorten" only display the first character of each directory in - the path - - "truncate" truncates the start of the path when the whole path will - not fit. To increase the gap between the path and the edge, - set truncate to number `truncate = 3` + - "hidden" hide file names + - "tail" only display the file name, and not the path + - "absolute" display absolute paths + - "smart" remove as much from the path as possible to only show + the difference between the displayed paths. + Warning: The nature of the algorithm might have a negative + performance impact! + - "shorten" only display the first character of each directory in + the path + - "truncate" truncates the start of the path when the whole path will + not fit. To increase the gap between the path and the edge, + set truncate to number `truncate = 3` + - "filename_first" shows filenames first and then the directories You can also specify the number of characters of each directory name to keep by setting `path_display.shorten = num`. @@ -340,6 +341,21 @@ append( will give a path like: `al/beta/gamma/de` + path_display can also be set to 'filename_first' to put the filename + in front. + + path_display = { + "filename_first" + }, + + The directory structure can be reversed as follows: + + path_display = { + filename_first = { + reverse_directories = true + } + }, + path_display can also be set to 'hidden' string to hide file names path_display can also be set to a function for custom formatting of diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index 2217fd8..009b36a 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -158,14 +158,16 @@ do mt_file_entry.cwd = cwd mt_file_entry.display = function(entry) local hl_group, icon - local display = utils.transform_path(opts, entry.value) + local display, path_style = utils.transform_path(opts, entry.value) display, hl_group, icon = utils.transform_devicons(entry.value, display, disable_devicons) if hl_group then - return display, { { { 0, #icon }, hl_group } } + local style = { { { 0, #icon + 1 }, hl_group } } + style = utils.merge_styles(style, path_style, #icon + 1) + return display, style else - return display + return display, path_style end end @@ -313,7 +315,7 @@ do cwd = utils.path_expand(opts.cwd or vim.loop.cwd()), display = function(entry) - local display_filename = utils.transform_path(opts, entry.filename) + local display_filename, path_style = utils.transform_path(opts, entry.filename) local coordinates = ":" if not disable_coordinates then @@ -333,9 +335,11 @@ do ) if hl_group then - return display, { { { 0, #icon }, hl_group } } + local style = { { { 0, #icon }, hl_group } } + style = utils.merge_styles(style, path_style, #icon + 1) + return display, style else - return display + return display, path_style end end, @@ -454,7 +458,7 @@ function make_entry.gen_from_quickfix(opts) local hidden = utils.is_path_hidden(opts) local make_display = function(entry) - local display_filename = utils.transform_path(opts, entry.filename) + local display_filename, path_style = utils.transform_path(opts, entry.filename) local display_string = string.format("%s:%d:%d", display_filename, entry.lnum, entry.col) if hidden then display_string = string.format("%4d:%2d", entry.lnum, entry.col) @@ -469,7 +473,7 @@ function make_entry.gen_from_quickfix(opts) display_string = display_string .. ":" .. text end - return display_string + return display_string, path_style end local get_filename = get_filename_fn() @@ -597,14 +601,19 @@ function make_entry.gen_from_buffer(opts) local make_display = function(entry) -- bufnr_width + modes + icon + 3 spaces + : + lnum opts.__prefix = opts.bufnr_width + 4 + icon_width + 3 + 1 + #tostring(entry.lnum) - local display_bufname = utils.transform_path(opts, entry.filename) + local display_bufname, path_style = utils.transform_path(opts, entry.filename) local icon, hl_group = utils.get_devicons(entry.filename, disable_devicons) return displayer { { entry.bufnr, "TelescopeResultsNumber" }, { entry.indicator, "TelescopeResultsComment" }, { icon, hl_group }, - display_bufname .. ":" .. entry.lnum, + { + display_bufname .. ":" .. entry.lnum, + function() + return path_style + end, + }, } end diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua index e515142..89af6b4 100644 --- a/lua/telescope/utils.lua +++ b/lua/telescope/utils.lua @@ -270,23 +270,24 @@ end --- not be addressed by us ---@param opts table: The opts the users passed into the picker. Might contains a path_display key ---@param path string|nil: The path that should be formatted ----@return string: The transformed path ready to be displayed +---@return string, table: The transformed path ready to be displayed with the styling (or nil) utils.transform_path = function(opts, path) if path == nil then - return "" + return "", {} end if utils.is_uri(path) then - return path + return path, {} end local path_display = vim.F.if_nil(opts.path_display, require("telescope.config").values.path_display) local transformed_path = path + local path_style = {} if type(path_display) == "function" then return path_display(opts, transformed_path) elseif utils.is_path_hidden(nil, path_display) then - return "" + return "", path_style elseif type(path_display) == "table" then if vim.tbl_contains(path_display, "tail") or path_display.tail then transformed_path = utils.path_tail(transformed_path) @@ -306,6 +307,37 @@ utils.transform_path = function(opts, path) transformed_path = Path:new(transformed_path):make_relative(cwd) end + if vim.tbl_contains(path_display, "filename_first") or path_display["filename_first"] ~= nil then + local reverse_directories = false + + if type(path_display["filename_first"]) == "table" then + local filename_first_opts = path_display["filename_first"] + + if filename_first_opts.reverse_directories == nil or filename_first_opts.reverse_directories == false then + reverse_directories = false + else + reverse_directories = filename_first_opts.reverse_directories + end + end + + local dirs = vim.split(transformed_path, utils.get_separator()) + local filename + + if reverse_directories then + dirs = utils.reverse_table(dirs) + filename = table.remove(dirs, 1) + else + filename = table.remove(dirs, #dirs) + end + + local tail = table.concat(dirs, utils.get_separator()) + + -- Prevents a toplevel filename to have a trailing whitespace + transformed_path = vim.trim(filename .. " " .. tail) + + path_style = { { { #filename, #transformed_path }, "TelescopeResultsComment" } } + end + if vim.tbl_contains(path_display, "shorten") or path_display["shorten"] ~= nil then if type(path_display["shorten"]) == "table" then local shorten = path_display["shorten"] @@ -315,6 +347,7 @@ utils.transform_path = function(opts, path) transformed_path = Path:new(transformed_path):shorten(length) end end + if vim.tbl_contains(path_display, "truncate") or path_display.truncate then if opts.__length == nil then opts.__length = calc_result_length(path_display.truncate) @@ -326,10 +359,10 @@ utils.transform_path = function(opts, path) end end - return transformed_path + return transformed_path, path_style else log.warn("`path_display` must be either a function or a table.", "See `:help telescope.defaults.path_display.") - return transformed_path + return transformed_path, path_style end end @@ -661,4 +694,25 @@ utils.__separate_file_path_location = function(path) return path, nil, nil end +utils.merge_styles = function(style1, style2, offset) + local function addOffset(i, obj) + return { obj[1] + i, obj[2] + i } + end + + for _, item in ipairs(style2) do + item[1] = addOffset(offset, item[1]) + table.insert(style1, item) + end + + return style1 +end + +utils.reverse_table = function(input_table) + local temp_table = {} + for index = 0, #input_table do + temp_table[#input_table - index] = input_table[index + 1] -- Reverses the order + end + return temp_table +end + return utils diff --git a/lua/tests/automated/utils_spec.lua b/lua/tests/automated/utils_spec.lua index f1cbb68..e91420b 100644 --- a/lua/tests/automated/utils_spec.lua +++ b/lua/tests/automated/utils_spec.lua @@ -277,4 +277,24 @@ describe("transform_path", function() it("handles default 'truncate' path_display", function() assert_path({ "truncate" }, new_relpath "lua/telescope/init.lua", new_relpath "…scope/init.lua") end) + + it("handles 'filename_first' path_display", function() + assert_path("filename_first", new_relpath "init.lua", new_relpath "init.lua") + assert_path("filename_first", new_relpath "lua/telescope/init.lua", new_relpath "init.lua lua/telescope") + end) + + it("handles 'filename_first' path_display with the option to reverse directories", function() + assert_path({ filename_first = { reverse_directories = true } }, new_relpath "init.lua", new_relpath "init.lua") + assert_path( + { filename_first = { reverse_directories = true } }, + new_relpath "lua/telescope/init.lua", + new_relpath "init.lua telescope/lua" + ) + assert_path({ filename_first = { reverse_directories = false } }, new_relpath "init.lua", new_relpath "init.lua") + assert_path( + { filename_first = { reverse_directories = false } }, + new_relpath "lua/telescope/init.lua", + new_relpath "init.lua lua/telescope" + ) + end) end)