|
| 1 | +---Run a test similar to :so $VIMRUNTIME/syntax/hitest.vim |
| 2 | +---Display all icons and their group highlighted, followed by the concrete definition |
| 3 | +-- |
| 4 | +---@class IconDisplay for :NvimTreeHiTest |
| 5 | +---@field tag any filename, os or extension, only strings accepted |
| 6 | +---@field name string name without prefix |
| 7 | +---@field icon string icon itself |
| 8 | +---@field group string|nil :hi group name |
| 9 | +---@field def string|nil :hi concrete definition |
| 10 | +local IconDisplay = {} |
| 11 | + |
| 12 | +---@param o IconDisplay |
| 13 | +---@return IconDisplay |
| 14 | +function IconDisplay:new(o) |
| 15 | + setmetatable(o, self) |
| 16 | + self.__index = self |
| 17 | + |
| 18 | + o.group = "DevIcon" .. o.name |
| 19 | + o.tag = type(o.tag) == "string" and o.tag or "" |
| 20 | + |
| 21 | + -- concrete definition |
| 22 | + local ok, res = pcall(vim.api.nvim_cmd, { cmd = "highlight", args = { o.group } }, { output = true }) |
| 23 | + if ok and type(res) == "string" then |
| 24 | + o.def = res:gsub(".*xxx *", "") |
| 25 | + else |
| 26 | + o.def = "" |
| 27 | + end |
| 28 | + |
| 29 | + return o |
| 30 | +end |
| 31 | + |
| 32 | +---Write the line with highlighting |
| 33 | +---@param bufnr number buffer number |
| 34 | +---@param max_tag_len number longest tag length |
| 35 | +---@param max_name_len number longest name length |
| 36 | +---@param l number line number |
| 37 | +---@return number l incremented |
| 38 | +function IconDisplay:render(bufnr, max_tag_len, max_name_len, l) |
| 39 | + local fmt = string.format("%%s %%-%d.%ds %%-%d.%ds %%s", max_name_len, max_name_len, max_tag_len, max_tag_len) |
| 40 | + local text = string.format(fmt, self.icon, self.name, self.tag, self.def) |
| 41 | + |
| 42 | + vim.api.nvim_buf_set_lines(bufnr, l, -1, true, { text }) |
| 43 | + vim.api.nvim_buf_add_highlight(bufnr, -1, self.group, l, 0, -1) |
| 44 | + |
| 45 | + return l + 1 |
| 46 | +end |
| 47 | + |
| 48 | +---Render a single line of text |
| 49 | +---@param bufnr number |
| 50 | +---@param l number line number |
| 51 | +---@return number l incremented |
| 52 | +local function render_line(bufnr, l, text) |
| 53 | + vim.api.nvim_buf_set_lines(bufnr, l, -1, true, { text }) |
| 54 | + return l + 1 |
| 55 | +end |
| 56 | + |
| 57 | +---Render all icons sorted by tag |
| 58 | +---@param bufnr number |
| 59 | +---@param l number line number |
| 60 | +---@param icons table |
| 61 | +---@param header string |
| 62 | +---@return number l incremented |
| 63 | +local function render_icons(bufnr, l, icons, header) |
| 64 | + local displays = {} |
| 65 | + local max_tag_len = 0 |
| 66 | + local max_name_len = 0 |
| 67 | + |
| 68 | + -- build all icon displays |
| 69 | + for tag, icon in pairs(icons) do |
| 70 | + local display = IconDisplay:new { tag = tag, name = icon.name, icon = icon.icon } |
| 71 | + table.insert(displays, display) |
| 72 | + max_tag_len = math.max(max_tag_len, #display.tag) |
| 73 | + max_name_len = math.max(max_name_len, #display.name) |
| 74 | + end |
| 75 | + |
| 76 | + -- sort by name |
| 77 | + table.sort(displays, function(a, b) |
| 78 | + return a.name < b.name |
| 79 | + end) |
| 80 | + |
| 81 | + l = render_line(bufnr, l, header) |
| 82 | + l = render_line(bufnr, l, header:gsub(".", "-")) |
| 83 | + for _, display in ipairs(displays) do |
| 84 | + l = display:render(bufnr, max_tag_len, max_name_len, l) |
| 85 | + end |
| 86 | + l = render_line(bufnr, l, "") |
| 87 | + |
| 88 | + return l |
| 89 | +end |
| 90 | + |
| 91 | +return function(default_icon, icons_by_filename, icons_by_file_extension, icons_by_operating_system) |
| 92 | + -- create a buffer |
| 93 | + local bufnr = vim.api.nvim_create_buf(false, true) |
| 94 | + |
| 95 | + -- render and highlight each section |
| 96 | + local l = 0 |
| 97 | + l = render_icons(bufnr, l, { default_icon }, "Default") |
| 98 | + l = render_icons(bufnr, l, icons_by_filename, "By File Name") |
| 99 | + l = render_icons(bufnr, l, icons_by_file_extension, "By File Extension") |
| 100 | + l = render_icons(bufnr, l, icons_by_operating_system, "By Operating System") |
| 101 | + |
| 102 | + -- finalise and focus the buffer |
| 103 | + vim.api.nvim_buf_set_option(bufnr, "modifiable", false) |
| 104 | + vim.cmd.buffer(bufnr) |
| 105 | +end |
0 commit comments