File icons: use colors from nvim-web-devicons if available

This improves the colors for file icons if nvim-web-devicons is
available. If it is, fzf-lua now uses those colors for the icons.

This should also improve the performance of make_entry_file by
optimizing string creation and when various regexes are matched.
main
John Drouhard 3 years ago committed by ibhagwan
parent fa70aa52f8
commit 02ad885d30

@ -452,8 +452,24 @@ M.globals.nvim = {
},
},
}
M.globals.file_icon_padding = ''
M.globals.file_icon_colors = {
if M._has_devicons then
M.globals.file_icon_colors = {}
local function hex(hex)
local r,g,b = hex:match('.(..)(..)(..)')
r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
return r, g, b
end
for ext, info in pairs(M._devicons.get_icons()) do
local r, g, b = hex(info.color)
utils.add_ansi_code('DevIcon' .. info.name, string.format('[38;2;%s;%s;%sm', r, g, b))
end
else
M.globals.file_icon_colors = {
["lua"] = "blue",
["rockspec"] = "magenta",
["vim"] = "green",
@ -502,7 +518,8 @@ M.globals.file_icon_colors = {
["svg"] = "green",
["otf"] = "green",
["ttf"] = "green",
}
}
end
function M.normalize_opts(opts, defaults)
if not opts then opts = {} end

@ -38,13 +38,20 @@ M.fzf = function(opts, contents, previewer)
end
M.get_devicon = function(file, ext)
local icon = ''
if not file or #file == 0 then return icon end
local icon, hl
if config._has_devicons and config._devicons then
local devicon = config._devicons.get_icon(file, ext)
if devicon then icon = devicon end
icon, hl = config._devicons.get_icon(file, ext, {default = true})
else
icon, hl = '', 'dark_grey'
end
-- allow user override of the color
local override = config.globals.file_icon_colors[ext]
if override then
hl = override
end
return icon..config.globals.file_icon_padding:gsub(" ", utils.nbsp)
return icon..config.globals.file_icon_padding:gsub(" ", utils.nbsp), hl
end
M.preview_window = function(opts)
@ -124,8 +131,6 @@ local get_untracked_files = function(opts)
end
local get_git_indicator = function(file, diff_files, untracked_files)
-- remove colors from `rg` output
file = utils.strip_ansi_coloring(file)
if diff_files and diff_files[file] then
return diff_files[file]
end
@ -148,41 +153,44 @@ M.make_entry_lcol = function(_, entry)
end
M.make_entry_file = function(opts, x)
local icon
local prefix = ''
if opts.cwd_only and path.starts_with_separator(x) then
local icon, hl
local ret = {}
local file = utils.strip_ansi_coloring(string.match(x, '[^:]*'))
if opts.cwd_only and path.starts_with_separator(file) then
local cwd = opts.cwd or vim.loop.cwd()
if not path.is_relative(x, cwd) then
if not path.is_relative(file, cwd) then
return nil
end
end
if opts.cwd and #opts.cwd > 0 then
-- TODO: does this work if there are ANSI escape codes in x?
x = path.relative(x, opts.cwd)
end
if opts.file_icons then
local ext = path.extension(x)
icon = M.get_devicon(x, ext)
local filename = path.tail(file)
local ext = path.extension(filename)
icon, hl = M.get_devicon(filename, ext)
if opts.color_icons then
icon = utils.ansi_codes[config.globals.file_icon_colors[ext] or "dark_grey"](icon)
icon = utils.ansi_codes[hl](icon)
end
prefix = prefix .. icon
ret[#ret+1] = icon
ret[#ret+1] = utils.nbsp
end
if opts.git_icons then
local filepath = x:match("^[^:]+")
local indicator = get_git_indicator(filepath, opts.diff_files, opts.untracked_files)
local indicator = get_git_indicator(file, opts.diff_files, opts.untracked_files)
icon = indicator
if config.globals.git.icons[indicator] then
icon = config.globals.git.icons[indicator].icon
local git_icon = config.globals.git.icons[indicator]
if git_icon then
icon = git_icon.icon
if opts.color_icons then
icon = utils.ansi_codes[config.globals.git.icons[indicator].color or "dark_grey"](icon)
icon = utils.ansi_codes[git_icon.color or "dark_grey"](icon)
end
end
prefix = prefix .. utils._if(#prefix>0, utils.nbsp, '') .. icon
end
if #prefix > 0 then
x = prefix .. utils.nbsp .. x
ret[#ret+1] = icon
ret[#ret+1] = utils.nbsp
end
return x
ret[#ret+1] = x
return table.concat(ret)
end
M.set_fzf_line_args = function(opts)

@ -10,14 +10,16 @@ M.starts_with_separator = function(path)
return path:find(M.separator()) == 1
end
M.tail = (function()
function M.tail(path)
local os_sep = M.separator()
local match_string = '[^' .. os_sep .. ']*$'
return function(path)
return string.match(path, match_string)
end
end)()
return string.match(path, match_string)
end
function M.extension(path)
return string.match(path, '[%w_+$]*$')
end
function M.to_matching_str(path)
return path:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)'):gsub('(%_)', '(%%_)')
@ -43,15 +45,6 @@ function M.basename(path)
return path:sub(i + 1, #path)
end
function M.extension(path)
-- path = M.basename(path)
-- return path:match(".+%.(.*)")
-- 1. match anything before the first ':'
-- 2. greedy match anything after the last dot
-- 3. remove coloring escape sequence
return utils.strip_ansi_coloring(path:match("[^:]*"):match("[^.]*$"))
end
---Get the path to the parent directory of the given path. Returns `nil` if the
---path has no parent.
---@param path string

@ -110,16 +110,17 @@ M.buffers = function(opts)
local bufnrstr = string.format("%s%s%s", leftbr,
utils.ansi_codes.yellow(string.format(buf.bufnr)), rightbr)
local buficon = ''
local hl = ''
if opts.file_icons then
local extension = path.extension(buf.info.name)
if utils.is_term_bufname(buf.info.name) then
-- get shell-like icon for terminal buffers
buficon = core.get_devicon(buf.info.name, "sh")
buficon, hl = core.get_devicon(buf.info.name, "sh")
else
buficon = core.get_devicon(buf.info.name, extension)
local extension = path.extension(buf.info.name)
buficon, hl = core.get_devicon(buf.info.name, extension)
end
if opts.color_icons then
buficon = utils.ansi_codes[config.globals.file_icon_colors[extension] or "dark_grey"](buficon)
buficon = utils.ansi_codes[hl](buficon)
end
end
local item_str = string.format("%s%s%s%s%s%s%s",

@ -173,13 +173,18 @@ M.ansi_colors = {
white = "",
}
M.add_ansi_code = function(name, escseq)
M.ansi_codes[name] = function(string)
if string == nil or #string == 0 then return '' end
return escseq .. string .. M.ansi_colors.clear
end
end
for color, escseq in pairs(M.ansi_colors) do
M.ansi_codes[color] = function(string)
if string == nil or #string == 0 then return '' end
return escseq .. string .. M.ansi_colors.clear
end
M.add_ansi_code(color, escseq)
end
function M.strip_ansi_coloring(str)
if not str then return str end
-- remove escape sequences of the following formats:

Loading…
Cancel
Save