make_entry.file: optimized performance and logic

main
bhagwan 2 years ago
parent 4707adc1ec
commit 7a0b7fac66

@ -298,50 +298,59 @@ M.lcol = function(entry, opts)
(opts and opts.trim_entry and vim.trim(entry.text)) or entry.text) (opts and opts.trim_entry and vim.trim(entry.text)) or entry.text)
end end
local COLON_BYTE = string.byte(":")
M.file = function(x, opts) M.file = function(x, opts)
opts = opts or {} opts = opts or {}
local ret = {} local ret = {}
local icon, hl local icon, hl
local file = utils.strip_ansi_coloring(string.match(x, '[^:]*')) local colon_idx = utils.find_next_char(x, COLON_BYTE) or 0
if opts.cwd_only and path.starts_with_separator(file) then local file_part = colon_idx>1 and x:sub(1, colon_idx-1) or x
local cwd = opts.cwd or vim.loop.cwd() local rest_of_line = colon_idx>1 and x:sub(colon_idx) or nil
if not path.is_relative(file, cwd) then -- strip ansi coloring from path so we can use filters
return nil -- otherwise the ANSI escape sequnce will get in the way
end -- TODO: we only support path modfication without ANSI
end -- escape sequences, it becomes too expensive to modify
-- and restore the path with escape sequences
local filepath, file_is_ansi = utils.strip_ansi_coloring(file_part)
-- fd v8.3 requires adding '--strip-cwd-prefix' to remove -- fd v8.3 requires adding '--strip-cwd-prefix' to remove
-- the './' prefix, will not work with '--color=always' -- the './' prefix, will not work with '--color=always'
-- https://github.com/sharkdp/fd/blob/master/CHANGELOG.md -- https://github.com/sharkdp/fd/blob/master/CHANGELOG.md
if not (opts.strip_cwd_prefix == false) and path.starts_with_cwd(x) then if not (opts.strip_cwd_prefix == false) and path.starts_with_cwd(filepath) then
x = path.strip_cwd_prefix(x) filepath = path.strip_cwd_prefix(filepath)
-- this is required to fix git icons not showing
-- since `git status -s` does not prepend './'
-- we can assume no ANSI coloring is present
-- since 'path.starts_with_cwd == true'
file = x
end end
if opts.cwd and #opts.cwd > 0 then -- make path relative
-- TODO: does this work if there are ANSI escape codes in x? if opts.cwd and #opts.cwd>0 then
x = path.relative(x, opts.cwd) filepath = path.relative(filepath, opts.cwd)
end end
-- replace $HOME with ~ if path.starts_with_separator(filepath) then
if path.starts_with_separator(x) then -- filter for cwd only
x = path.HOME_to_tilde(x) if opts.cwd_only then
local cwd = opts.cwd or vim.loop.cwd()
if not path.is_relative(filepath, cwd) then
return nil
end
end
-- replace $HOME with ~
filepath = path.HOME_to_tilde(filepath)
end end
-- only check for ignored patterns after './' was -- only check for ignored patterns after './' was
-- stripped and path was transformed to relative -- stripped and path was transformed to relative
if opts.file_ignore_patterns then if opts.file_ignore_patterns then
for _, pattern in ipairs(opts.file_ignore_patterns) do for _, pattern in ipairs(opts.file_ignore_patterns) do
if #pattern>0 and x:match(pattern) then if #pattern>0 and filepath:match(pattern) then
return nil return nil
end end
end end
end end
-- only shorten after we're done with all the filtering
-- save a copy for git indicator and icon lookups
local origpath = filepath
if opts.path_shorten then if opts.path_shorten then
x = path.shorten(x, tonumber(opts.path_shorten)) filepath = path.shorten(filepath, tonumber(opts.path_shorten))
end end
if opts.git_icons then if opts.git_icons then
local indicators = opts.diff_files and opts.diff_files[file] or utils.nbsp local indicators = opts.diff_files and opts.diff_files[origpath] or utils.nbsp
for i=1,#indicators do for i=1,#indicators do
icon = indicators:sub(i,i) icon = indicators:sub(i,i)
local git_icon = config.globals.git.icons[icon] local git_icon = config.globals.git.icons[icon]
@ -356,7 +365,7 @@ M.file = function(x, opts)
ret[#ret+1] = utils.nbsp ret[#ret+1] = utils.nbsp
end end
if opts.file_icons then if opts.file_icons then
local filename = path.tail(file) local filename = path.tail(origpath)
local ext = path.extension(filename) local ext = path.extension(filename)
icon, hl = M.get_devicon(filename, ext) icon, hl = M.get_devicon(filename, ext)
if opts.color_icons then if opts.color_icons then
@ -368,7 +377,8 @@ M.file = function(x, opts)
ret[#ret+1] = icon ret[#ret+1] = icon
ret[#ret+1] = utils.nbsp ret[#ret+1] = utils.nbsp
end end
ret[#ret+1] = x ret[#ret+1] = file_is_ansi>0 and file_part or filepath
ret[#ret+1] = rest_of_line
return table.concat(ret) return table.concat(ret)
end end

@ -60,6 +60,24 @@ M.strsplit = function(inputstr, sep)
return t return t
end end
local string_byte = string.byte
M.find_last_char = function(str, c)
for i=#str,1,-1 do
if string_byte(str, i) == c then
return i
end
end
end
M.find_next_char = function(str, c, start_idx)
for i=start_idx or 1,#str do
if string_byte(str, i) == c then
return i
end
end
end
function M.round(num, limit) function M.round(num, limit)
if not num then return nil end if not num then return nil end
if not limit then limit = 0.5 end if not limit then limit = 0.5 end

Loading…
Cancel
Save