Skip to content

Commit

Permalink
feat(#192): :NvimWebDeviconsHiTest (#405)
Browse files Browse the repository at this point in the history
* feat(#192): :NvimWebDeviconsHiTest

* feat(#192): :NvimWebDeviconsHiTest
  • Loading branch information
alex-courtis authored Feb 25, 2024
1 parent 7a19449 commit 0bb67ef
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ Run `make`. This will:

Please commit both `lua/nvim-web-devicons/icons-default.lua` and `lua/nvim-web-devicons/icons-light.lua`

## Test

Run `:NvimWebDeviconsHiTest` to view the icons and their highlighting.

Start neovim with `TERM=xterm-256color nvim ...` to test cterm.

Check with `&background` `dark` and `light`

## Pull Request

Please reference any issues in the description e.g. "resolves #1234".
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ use 'nvim-tree/nvim-web-devicons'

## Usage

### Viewing

Run `:NvimWebDeviconsHiTest` to see all icons and their highlighting.

### Variants

Light or dark color variants of the icons depend on `&background`.
Expand Down
12 changes: 12 additions & 0 deletions lua/nvim-web-devicons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,18 @@ function M.setup(opts)
group = vim.api.nvim_create_augroup("NvimWebDevicons", { clear = true }),
callback = M.set_up_highlights,
})

-- highlight test command
vim.api.nvim_create_user_command("NvimWebDeviconsHiTest", function()
require "nvim-web-devicons.hi-test"(
default_icon,
icons_by_filename,
icons_by_file_extension,
icons_by_operating_system
)
end, {
desc = "nvim-web-devicons: highlight test",
})
end

function M.get_default_icon()
Expand Down
112 changes: 112 additions & 0 deletions lua/nvim-web-devicons/hi-test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---Run a test similar to :so $VIMRUNTIME/syntax/hitest.vim
---Display all icons and their group highlighted, followed by the concrete definition
--
---@class IconDisplay for :NvimTreeHiTest
---@field tag any filename, os or extension, only strings accepted
---@field name string name without prefix
---@field icon string icon itself
---@field group string|nil :hi group name
---@field def string|nil :hi concrete definition
local IconDisplay = {}

---@param o IconDisplay
---@return IconDisplay
function IconDisplay:new(o)
setmetatable(o, self)
self.__index = self

o.group = "DevIcon" .. o.name
o.tag = type(o.tag) == "string" and o.tag or ""

-- concrete definition
local ok, res = pcall(vim.api.nvim_cmd, { cmd = "highlight", args = { o.group } }, { output = true })
if ok and type(res) == "string" then
o.def = res:gsub(".*xxx *", "")
else
o.def = ""
end

return o
end

---Write the line with highlighting
---@param bufnr number buffer number
---@param max_tag_len number longest tag length
---@param max_name_len number longest name length
---@param l number line number
---@return number l incremented
function IconDisplay:render(bufnr, max_tag_len, max_name_len, l)
local fmt = string.format("%%s %%-%d.%ds %%-%d.%ds %%s", max_name_len, max_name_len, max_tag_len, max_tag_len)
local text = string.format(fmt, self.icon, self.name, self.tag, self.def)

vim.api.nvim_buf_set_lines(bufnr, l, -1, true, { text })
vim.api.nvim_buf_add_highlight(bufnr, -1, self.group, l, 0, -1)

return l + 1
end

---Render a single line of text
---@param bufnr number
---@param l number line number
---@return number l incremented
local function render_line(bufnr, l, text)
vim.api.nvim_buf_set_lines(bufnr, l, -1, true, { text })
return l + 1
end

---Render all icons sorted by tag
---@param bufnr number
---@param l number line number
---@param icons table
---@param header string
---@return number l incremented
local function render_icons(bufnr, l, icons, header)
local displays = {}
local max_tag_len = 0
local max_name_len = 0

-- build all icon displays
for tag, icon in pairs(icons) do
local display = IconDisplay:new { tag = tag, name = icon.name, icon = icon.icon }
table.insert(displays, display)
max_tag_len = math.max(max_tag_len, #display.tag)
max_name_len = math.max(max_name_len, #display.name)
end

-- sort by name
table.sort(displays, function(a, b)
return a.name < b.name
end)

l = render_line(bufnr, l, header)
l = render_line(bufnr, l, header:gsub(".", "-"))
for _, display in ipairs(displays) do
l = display:render(bufnr, max_tag_len, max_name_len, l)
end
l = render_line(bufnr, l, "")

return l
end

---Create a buffer similar to :ru syntax/hitest.vim displaying each set icons
---Icon, name, <tag>, concrete highlight definition
---tag and header follows param
---@param default_icon table no tag "Default"
---@param icons_by_filename table[] filename "By File Name"
---@param icons_by_file_extension table[] extension "By File Extension"
---@param icons_by_operating_system table[] os "By Operating System"
return function(default_icon, icons_by_filename, icons_by_file_extension, icons_by_operating_system)
-- create a buffer
local bufnr = vim.api.nvim_create_buf(false, true)

-- render and highlight each section
local l = 0
l = render_icons(bufnr, l, { default_icon }, "Default")
l = render_icons(bufnr, l, icons_by_filename, "By File Name")
l = render_icons(bufnr, l, icons_by_file_extension, "By File Extension")
render_icons(bufnr, l, icons_by_operating_system, "By Operating System")

-- finalise and focus the buffer
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.cmd.buffer(bufnr)
end

0 comments on commit 0bb67ef

Please sign in to comment.