feat(entry_maker): add 'filename_first' option for path_display (#3010)

* Initial commit

* Fixes issue with find_files where devicons where disabled

* Fixes issue with vimgrep where devicons where disabled

* Fixes trailing space for path with only a file name

* Adds test for reverse path_display

* Refactors reverse to filename_first

* Adds tests

* Fixes highlighting

* Fixes linting issues

* Uses trim function

* Fixes issue with highlighting

* Moves local function to utils

* Removes redundant code

* Adds highlighting for gen_from_buffer

* fix formatting

---------

Co-authored-by: alycklama <>
Co-authored-by: James Trew <j.trew10@gmail.com>
This commit is contained in:
Anton
2024-04-20 06:21:35 +02:00
committed by GitHub
parent 10d57f38f5
commit a4432dfb9b
5 changed files with 155 additions and 40 deletions

View File

@@ -270,18 +270,19 @@ telescope.setup({opts}) *telescope.setup()*
Determines how file paths are displayed. Determines how file paths are displayed.
path_display can be set to an array with a combination of: path_display can be set to an array with a combination of:
- "hidden" hide file names - "hidden" hide file names
- "tail" only display the file name, and not the path - "tail" only display the file name, and not the path
- "absolute" display absolute paths - "absolute" display absolute paths
- "smart" remove as much from the path as possible to only show - "smart" remove as much from the path as possible to only show
the difference between the displayed paths. the difference between the displayed paths.
Warning: The nature of the algorithm might have a negative Warning: The nature of the algorithm might have a negative
performance impact! performance impact!
- "shorten" only display the first character of each directory in - "shorten" only display the first character of each directory in
the path the path
- "truncate" truncates the start of the path when the whole path will - "truncate" truncates the start of the path when the whole path will
not fit. To increase the gap between the path and the edge, not fit. To increase the gap between the path and the edge,
set truncate to number `truncate = 3` 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 You can also specify the number of characters of each directory name
to keep by setting `path_display.shorten = num`. to keep by setting `path_display.shorten = num`.
@@ -306,6 +307,21 @@ telescope.setup({opts}) *telescope.setup()*
will give a path like: will give a path like:
`al/beta/gamma/de` `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 'hidden' string to hide file names
path_display can also be set to a function for custom formatting of path_display can also be set to a function for custom formatting of

View File

@@ -304,18 +304,19 @@ append(
Determines how file paths are displayed. Determines how file paths are displayed.
path_display can be set to an array with a combination of: path_display can be set to an array with a combination of:
- "hidden" hide file names - "hidden" hide file names
- "tail" only display the file name, and not the path - "tail" only display the file name, and not the path
- "absolute" display absolute paths - "absolute" display absolute paths
- "smart" remove as much from the path as possible to only show - "smart" remove as much from the path as possible to only show
the difference between the displayed paths. the difference between the displayed paths.
Warning: The nature of the algorithm might have a negative Warning: The nature of the algorithm might have a negative
performance impact! performance impact!
- "shorten" only display the first character of each directory in - "shorten" only display the first character of each directory in
the path the path
- "truncate" truncates the start of the path when the whole path will - "truncate" truncates the start of the path when the whole path will
not fit. To increase the gap between the path and the edge, not fit. To increase the gap between the path and the edge,
set truncate to number `truncate = 3` 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 You can also specify the number of characters of each directory name
to keep by setting `path_display.shorten = num`. to keep by setting `path_display.shorten = num`.
@@ -340,6 +341,21 @@ append(
will give a path like: will give a path like:
`al/beta/gamma/de` `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 'hidden' string to hide file names
path_display can also be set to a function for custom formatting of path_display can also be set to a function for custom formatting of

View File

@@ -158,14 +158,16 @@ do
mt_file_entry.cwd = cwd mt_file_entry.cwd = cwd
mt_file_entry.display = function(entry) mt_file_entry.display = function(entry)
local hl_group, icon 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) display, hl_group, icon = utils.transform_devicons(entry.value, display, disable_devicons)
if hl_group then 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 else
return display return display, path_style
end end
end end
@@ -313,7 +315,7 @@ do
cwd = utils.path_expand(opts.cwd or vim.loop.cwd()), cwd = utils.path_expand(opts.cwd or vim.loop.cwd()),
display = function(entry) 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 = ":" local coordinates = ":"
if not disable_coordinates then if not disable_coordinates then
@@ -333,9 +335,11 @@ do
) )
if hl_group then 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 else
return display return display, path_style
end end
end, end,
@@ -454,7 +458,7 @@ function make_entry.gen_from_quickfix(opts)
local hidden = utils.is_path_hidden(opts) local hidden = utils.is_path_hidden(opts)
local make_display = function(entry) 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) local display_string = string.format("%s:%d:%d", display_filename, entry.lnum, entry.col)
if hidden then if hidden then
display_string = string.format("%4d:%2d", entry.lnum, entry.col) 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 display_string = display_string .. ":" .. text
end end
return display_string return display_string, path_style
end end
local get_filename = get_filename_fn() local get_filename = get_filename_fn()
@@ -597,14 +601,19 @@ function make_entry.gen_from_buffer(opts)
local make_display = function(entry) local make_display = function(entry)
-- bufnr_width + modes + icon + 3 spaces + : + lnum -- bufnr_width + modes + icon + 3 spaces + : + lnum
opts.__prefix = opts.bufnr_width + 4 + icon_width + 3 + 1 + #tostring(entry.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) local icon, hl_group = utils.get_devicons(entry.filename, disable_devicons)
return displayer { return displayer {
{ entry.bufnr, "TelescopeResultsNumber" }, { entry.bufnr, "TelescopeResultsNumber" },
{ entry.indicator, "TelescopeResultsComment" }, { entry.indicator, "TelescopeResultsComment" },
{ icon, hl_group }, { icon, hl_group },
display_bufname .. ":" .. entry.lnum, {
display_bufname .. ":" .. entry.lnum,
function()
return path_style
end,
},
} }
end end

View File

@@ -270,23 +270,24 @@ end
--- not be addressed by us --- not be addressed by us
---@param opts table: The opts the users passed into the picker. Might contains a path_display key ---@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 ---@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) utils.transform_path = function(opts, path)
if path == nil then if path == nil then
return "" return "", {}
end end
if utils.is_uri(path) then if utils.is_uri(path) then
return path return path, {}
end end
local path_display = vim.F.if_nil(opts.path_display, require("telescope.config").values.path_display) local path_display = vim.F.if_nil(opts.path_display, require("telescope.config").values.path_display)
local transformed_path = path local transformed_path = path
local path_style = {}
if type(path_display) == "function" then if type(path_display) == "function" then
return path_display(opts, transformed_path) return path_display(opts, transformed_path)
elseif utils.is_path_hidden(nil, path_display) then elseif utils.is_path_hidden(nil, path_display) then
return "" return "", path_style
elseif type(path_display) == "table" then elseif type(path_display) == "table" then
if vim.tbl_contains(path_display, "tail") or path_display.tail then if vim.tbl_contains(path_display, "tail") or path_display.tail then
transformed_path = utils.path_tail(transformed_path) 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) transformed_path = Path:new(transformed_path):make_relative(cwd)
end 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 vim.tbl_contains(path_display, "shorten") or path_display["shorten"] ~= nil then
if type(path_display["shorten"]) == "table" then if type(path_display["shorten"]) == "table" then
local shorten = path_display["shorten"] local shorten = path_display["shorten"]
@@ -315,6 +347,7 @@ utils.transform_path = function(opts, path)
transformed_path = Path:new(transformed_path):shorten(length) transformed_path = Path:new(transformed_path):shorten(length)
end end
end end
if vim.tbl_contains(path_display, "truncate") or path_display.truncate then if vim.tbl_contains(path_display, "truncate") or path_display.truncate then
if opts.__length == nil then if opts.__length == nil then
opts.__length = calc_result_length(path_display.truncate) opts.__length = calc_result_length(path_display.truncate)
@@ -326,10 +359,10 @@ utils.transform_path = function(opts, path)
end end
end end
return transformed_path return transformed_path, path_style
else else
log.warn("`path_display` must be either a function or a table.", "See `:help telescope.defaults.path_display.") 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
end end
@@ -661,4 +694,25 @@ utils.__separate_file_path_location = function(path)
return path, nil, nil return path, nil, nil
end 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 return utils

View File

@@ -277,4 +277,24 @@ describe("transform_path", function()
it("handles default 'truncate' path_display", function() it("handles default 'truncate' path_display", function()
assert_path({ "truncate" }, new_relpath "lua/telescope/init.lua", new_relpath "…scope/init.lua") assert_path({ "truncate" }, new_relpath "lua/telescope/init.lua", new_relpath "…scope/init.lua")
end) 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) end)