506 lines
20 KiB
Plaintext
506 lines
20 KiB
Plaintext
*mini.icons* Icon provider
|
|
*MiniIcons*
|
|
|
|
MIT License Copyright (c) 2024 Evgeni Chasnovski
|
|
|
|
==============================================================================
|
|
|
|
Features:
|
|
|
|
- Provide icons with their highlighting via a single |MiniIcons.get()| for
|
|
various categories: filetype, file/directory path, extension, operating
|
|
system, LSP kind values. Icons and category defaults can be overridden.
|
|
|
|
- Configurable styles: "glyph" (icon glyphs) or "ascii" (non-glyph fallback).
|
|
|
|
- Fixed set of highlight groups (linked to built-in groups by default) for
|
|
better blend with color scheme.
|
|
|
|
- Caching for maximum performance.
|
|
|
|
- Integration with |vim.filetype.add()| and |vim.filetype.match()|.
|
|
|
|
- Mocking methods of 'nvim-tree/nvim-web-devicons' for better integrations
|
|
with plugins outside 'mini.nvim'. See |MiniIcons.mock_nvim_web_devicons()|.
|
|
|
|
- Tweaking built-in maps for "LSP kind" to include icons. In particular, this
|
|
makes |mini.completion| use icons in LSP step. See |MiniIcons.tweak_lsp_kind()|.
|
|
|
|
Notes:
|
|
|
|
- It is not a goal to become a collection of icons for as much use cases as
|
|
possible. There are specific criteria for icon data to be included as
|
|
built-in in each category (see |MiniIcons.get()|).
|
|
The main supported category is "filetype".
|
|
|
|
Recommendations for plugin authors using 'mini.icons' as a dependency:
|
|
|
|
- Check if `_G.MiniIcons` table is present (which means that user explicitly
|
|
enabled 'mini.icons') and provide icons only if it is.
|
|
|
|
- Use |MiniIcons.get()| function to get icon string and more data about it.
|
|
|
|
- For file icons prefer using full path instead of relative or only basename.
|
|
It makes a difference if path matches pattern that uses parent directories.
|
|
The |MiniIcons.config| has an example of that.
|
|
|
|
# Dependencies ~
|
|
|
|
Suggested dependencies:
|
|
|
|
- Terminal emulator that supports showing special utf8 glyphs, possibly with
|
|
"overflow" view (displaying is done not in one but two visual cells).
|
|
Most modern feature-rich terminal emulators support this out of the box:
|
|
WezTerm, Kitty, Alacritty, iTerm2, Ghostty.
|
|
Not having "overflow" feature only results into smaller icons.
|
|
Not having support for special utf8 glyphs will result into seemingly
|
|
random symbols (or question mark squares) instead of icon glyphs.
|
|
|
|
- Font that supports Nerd Fonts (https://www.nerdfonts.com) icons from
|
|
version 3.0.0+ (in particular `nf-md-*` class).
|
|
This should be configured on terminal emulator level either by using font
|
|
patched with Nerd Fonts icons or using `NerdFontsSymbolsOnly` font as
|
|
a fallback for glyphs that are not supported in main font.
|
|
|
|
If using terminal emulator and/or font with icon support is impossible, use
|
|
`config.style = 'ascii'`. It will use a (less visually appealing) set of
|
|
non-glyph icons.
|
|
|
|
# Setup ~
|
|
|
|
This module needs a setup with `require('mini.icons').setup({})` (replace `{}`
|
|
with your `config` table). It will create global Lua table `MiniIcons` which you
|
|
can use for scripting or manually (with `:lua MiniIcons.*`).
|
|
|
|
See |MiniIcons.config| for `config` structure and default values.
|
|
|
|
# Comparisons ~
|
|
|
|
- 'nvim-tree/nvim-web-devicons' (for users):
|
|
- Sets individual colors to each icon with separate specific highlight
|
|
groups, while this modules uses fixed set of highlight groups.
|
|
This makes it easier to customize in bulk and actually blend with any
|
|
color scheme.
|
|
|
|
- This module prefers richer set of `nf-md-*` (from "Material design" set)
|
|
Nerd Fonts icons while 'nvim-web-devicons' mostly prefers `nf-dev-*`
|
|
(from "devicons" set).
|
|
|
|
- Supported categories are slightly different (with much overlap).
|
|
|
|
- Both support customization of any icon. Only this module supports
|
|
customization of default ones per supported category.
|
|
|
|
- Using this module can occasionally result in small delays when used
|
|
synchronously for many times to get icons for not typical files (like
|
|
in |mini.files|). This is due to using |vim.filetype.match()| fallback and
|
|
is present only during first call, as value is cached for later uses.
|
|
|
|
- This module supports different icon styles (like "ascii" for when using
|
|
glyphs is not possible), while 'nvim-web-devicons' does not.
|
|
|
|
- This module provides |MiniIcons.mock_nvim_web_devicons()| function which
|
|
when called imitates installed 'nvim-web-devicons' plugin to support
|
|
other plugins which do not provide 'mini.icons' yet.
|
|
|
|
- 'nvim-tree/nvim-web-devicons' (for plugin developers):
|
|
- Both have main "get icon" type of function:
|
|
- Both return tuple of icon and highlight group strings.
|
|
|
|
- This module always returns icon data possibly falling back to
|
|
user's configured default, while 'nvim-web-devicons' is able to
|
|
return `nil`. This module's approach is more aligned with the most
|
|
common use case of always showing an icon instead or near some data.
|
|
There is a third returned value indicating if output is a result of
|
|
a fallback (see |MiniIcons.get()|).
|
|
|
|
- This module uses |vim.filetype.match()| as a fallback for "file"
|
|
and "extension" categories, while 'nvim-web-devicons' completely
|
|
relies on the manually maintained tables of supported filenames
|
|
and extensions.
|
|
Using fallback results in a wider support and deeper integration
|
|
with Neovim's filetype detection at the cost of occasional slower
|
|
first call. The difference is reduced as much as is reasonable by
|
|
preferring faster file extension resolution over filetype matching.
|
|
|
|
- This module caches all its return values resulting in really fast
|
|
next same argument calls, while 'nvim-web-devicons' doesn't do that.
|
|
|
|
- This module works with full file/directory paths as input.
|
|
|
|
- Different sets of supported categories (see |MiniIcons.config|):
|
|
- Both support "file", "extension", "filetype", "operating system".
|
|
Albeit in different volumes: 'nvim-web-devicons' covers more
|
|
cases for "operating system", while this module has better eventual
|
|
coverage for other cases.
|
|
|
|
- This module supports "directory" and "lsp" categories.
|
|
|
|
- 'nvim-web-devicons' covers "desktop environment" and "window
|
|
management" categories. This modules does not include them due to
|
|
relatively low demand.
|
|
|
|
- 'onsails/lspkind.nvim':
|
|
- Provides icons only for `CompletionItemKind`, while this module also has
|
|
icons for `SymbolKind` and other non-LSP categories.
|
|
- Provides dedicated formatting function for 'hrsh7th/nvim-cmp' while this
|
|
module intentionally does not (adding icons should be straightforward
|
|
to manually implement while anything else is out of scope).
|
|
|
|
# Highlight groups ~
|
|
|
|
Only the following set of highlight groups is used as icon highlight.
|
|
It is recommended that they all only define colored foreground:
|
|
|
|
* `MiniIconsAzure` - azure.
|
|
* `MiniIconsBlue` - blue.
|
|
* `MiniIconsCyan` - cyan.
|
|
* `MiniIconsGreen` - green.
|
|
* `MiniIconsGrey` - grey.
|
|
* `MiniIconsOrange` - orange.
|
|
* `MiniIconsPurple` - purple.
|
|
* `MiniIconsRed` - red.
|
|
* `MiniIconsYellow` - yellow.
|
|
|
|
To change any highlight group, modify it directly with |:highlight|.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.setup()*
|
|
`MiniIcons.setup`({config})
|
|
Module setup
|
|
|
|
Parameters ~
|
|
{config} `(table|nil)` Module config table. See |MiniIcons.config|.
|
|
|
|
Usage ~
|
|
>lua
|
|
require('mini.icons').setup() -- use default config
|
|
-- OR
|
|
require('mini.icons').setup({}) -- replace {} with your config table
|
|
<
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.config*
|
|
`MiniIcons.config`
|
|
Module config
|
|
|
|
Default values:
|
|
>lua
|
|
MiniIcons.config = {
|
|
-- Icon style: 'glyph' or 'ascii'
|
|
style = 'glyph',
|
|
|
|
-- Customize per category. See `:h MiniIcons.config` for details.
|
|
default = {},
|
|
directory = {},
|
|
extension = {},
|
|
file = {},
|
|
filetype = {},
|
|
lsp = {},
|
|
os = {},
|
|
|
|
-- Control which extensions will be considered during "file" resolution
|
|
use_file_extension = function(ext, file) return true end,
|
|
}
|
|
<
|
|
# Style ~
|
|
|
|
`config.style` is a string defining which icon style to use. It can be:
|
|
- `'glyph'` (default) - use glyph icons (like and ).
|
|
- `'ascii'` - use fallback ASCII-compatible icons. Those are computed as
|
|
an upper first character of the icon's resolved name inside its category.
|
|
Examples: >lua
|
|
|
|
MiniIcons.get('file', 'Makefile') -- Has `'M'` as icon
|
|
MiniIcons.get('extension', 'lua') -- Has `'L'` as icon
|
|
MiniIcons.get('file', 'file.lua') -- Has `'L'` as icon; it is resolved to
|
|
-- come from 'lua' 'extension' category
|
|
MiniIcons.get('file', 'myfile') -- Has `'F'` as icon; it is resolved to
|
|
-- come from 'file' 'default' category
|
|
<
|
|
# Customization per category ~
|
|
|
|
The following entries can be used to customize icons for supported categories:
|
|
- `config.default`
|
|
- `config.directory`
|
|
- `config.extension`
|
|
- `config.file`
|
|
- `config.filetype`
|
|
- `config.lsp`
|
|
- `config.os`
|
|
|
|
Customization should be done by supplying a table with <glyph> (icon glyph)
|
|
and/or <hl> (name of highlight group) string fields as a value for an icon
|
|
name entry. Example: >lua
|
|
|
|
require('mini.icons').setup({
|
|
default = {
|
|
-- Override default glyph for "file" category (reuse highlight group)
|
|
file = { glyph = '' },
|
|
},
|
|
extension = {
|
|
-- Override highlight group (not necessary from 'mini.icons')
|
|
lua = { hl = 'Special' },
|
|
|
|
-- Add icons for custom extension. This will also be used in
|
|
-- 'file' category for input like 'file.my.ext'.
|
|
['my.ext'] = { glyph = '', hl = 'MiniIconsRed' },
|
|
},
|
|
})
|
|
<
|
|
Notes:
|
|
- These customizations only take effect inside |MiniIcons.setup()| call.
|
|
Changing interactively via `:lua MiniIcons.config.xxx = { ... }` does not work
|
|
for performance reasons.
|
|
- Use lower case names for categories which are matched ignoring case.
|
|
See |MiniIcons.get()| for more details.
|
|
|
|
# Using extension during file resolution ~
|
|
|
|
`config.use_file_extension` is a function which can be used to control which
|
|
extensions will be considered as a source of icon data during "file" category
|
|
resolution (see |MiniIcons.get()| for more details).
|
|
Default: function which always returns `true` (i.e. consider all extensions).
|
|
|
|
Will be called once for the biggest suffix after dot found in the file name.
|
|
The arguments will be `ext` (found extension; lowercase) and `file` (input for
|
|
which icon is computed; as is). Should explicitly return `true` if `ext` is to
|
|
be considered (i.e. call `MiniIcons.get('extension', ext)` and use its
|
|
output if it is not default). Otherwise extension won't be even considered.
|
|
|
|
The primary use case for this setting is to ensure that some extensions are
|
|
ignored in order for resolution to reach |vim.filetype.match()| stage. This
|
|
is needed if there is a set up filetype detection for files with recognizable
|
|
extension and conflicting icons (which you want to use). Note: if problematic
|
|
filetype detection involves only known in advance file names, prefer using
|
|
`config.file` customization.
|
|
|
|
Example: >lua
|
|
|
|
-- Built-in filetype detection recognizes files like "queries/.*%.scm"
|
|
-- as "query" filetype. However, without special setup, 'mini.icons' will
|
|
-- use "scm" extension to resolve as Scheme file. Here is a setup to ignore
|
|
-- "scm" extension and completely rely on `vim.filetype.match()` fallback.
|
|
require('mini.icons').setup({
|
|
-- Check last letters explicitly to account for dots in file name
|
|
use_file_extension = function(ext) return ext:sub(-3) ~= 'scm' end
|
|
})
|
|
|
|
-- Another common choices for extensions to ignore: "yml", "json", "txt".
|
|
<
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.get()*
|
|
`MiniIcons.get`({category}, {name})
|
|
Get icon data
|
|
|
|
Usage example: >lua
|
|
|
|
-- Results into `icon=''`, `hl='MiniIconsAzure'`, `is_default=false`
|
|
local icon, hl, is_default = MiniIcons.get('file', 'file.lua')
|
|
<
|
|
Notes:
|
|
- Always returns some data, even if icon name is not explicitly supported
|
|
within target category. Category "default" is used as a fallback. Use third
|
|
output value to check if this particular case is a result of a fallback.
|
|
|
|
- Glyphs are explicitly preferred (when reasonable) from a richer set of
|
|
`nf-md-*` class ("Material design" set) of Nerd Fonts icons.
|
|
|
|
- Output is cached after the first call to increase performance of next calls
|
|
with same arguments. To reset cache, call |MiniIcons.setup()|.
|
|
|
|
- To increase first call performance for "extension" and "file" categories,
|
|
add frequently used values in |MiniIcons.config|. They will be preferred
|
|
over executing |vim.filetype.match()|.
|
|
|
|
- Matching icon name for "file" and "directory" categories is done exactly
|
|
and respecting case. Others are done ignoring case.
|
|
|
|
Parameters ~
|
|
{category} `(string)` Category name. Supported categories:
|
|
- `'default'` - icon data used as fallback for any category.
|
|
Icon names:
|
|
- <Input>: any supported category name.
|
|
- <Built-in>: only supported category names.
|
|
|
|
Examples: >lua
|
|
|
|
MiniIcons.get('default', 'file')
|
|
<
|
|
- `'directory'` - icon data for directory path.
|
|
Icon names:
|
|
- <Input>: any string, but only basename is used. Works with not present
|
|
paths (no check is done).
|
|
- <Built-in>: popular directory names not tied to language/software
|
|
(with few notable exceptions like Neovim, Git, etc.).
|
|
|
|
Examples: >lua
|
|
|
|
-- All of these will result in the same output
|
|
MiniIcons.get('directory', '.config')
|
|
MiniIcons.get('directory', '~/.config')
|
|
MiniIcons.get('directory', '/home/user/.config')
|
|
|
|
-- Results in different output
|
|
MiniIcons.get('directory', '.Config')
|
|
<
|
|
- `'extension'` - icon data for extension.
|
|
Icon names:
|
|
- <Input>: any string (without extra dot prefix).
|
|
- <Built-in>: popular extensions without associated filetype plus a set
|
|
for which filetype detection gives not good enough result.
|
|
|
|
Icon data is attempted to be resolved in the following order:
|
|
- List of user configured and built-in extensions (for better results).
|
|
Run `:=MiniIcons.list('extension')` to see them.
|
|
Used also if present as suffix after the dot (widest one preferred).
|
|
- Filetype as a result of |vim.filetype.match()| with placeholder
|
|
file name. Uses icon data from "filetype" category.
|
|
|
|
Examples: >lua
|
|
|
|
-- All of these will result in the same output
|
|
MiniIcons.get('extension', 'lua')
|
|
MiniIcons.get('extension', 'LUA')
|
|
MiniIcons.get('extension', 'my.lua')
|
|
<
|
|
- `'file'` - icon data for file path.
|
|
Icon names:
|
|
- <Input>: any string. Works with not present paths (no check is done).
|
|
- <Built-in>: popular file names not tied to language/software
|
|
(with few notable exceptions like Neovim, Git, etc.) plus a set which
|
|
has recognizable extension but has special detectable filetype.
|
|
|
|
Icon data is attempted to be resolved in the following order:
|
|
- List of user configured and built-in file names (matched to basename
|
|
of the input exactly). Run `:=MiniIcons.list('flle')` to see them.
|
|
- Basename extension:
|
|
- Matched directly as `get('extension', ext)`, where `ext` is the
|
|
widest suffix after the dot.
|
|
- Considered only if `config.use_file_extension` returned `true`.
|
|
- Only recognizable extensions (i.e. not default fallback) are used.
|
|
- Filetype as a result of |vim.filetype.match()| with full input (not
|
|
basename) as `filename`. Uses icon data from "filetype" category.
|
|
|
|
Examples: >lua
|
|
|
|
-- All of these will result in the same output
|
|
MiniIcons.get('file', 'init.lua')
|
|
MiniIcons.get('file', '~/.config/nvim/init.lua')
|
|
MiniIcons.get('file', '/home/user/.config/nvim/init.lua')
|
|
|
|
-- Results in different output
|
|
MiniIcons.get('file', 'Init.lua')
|
|
MiniIcons.get('file', 'init.LUA')
|
|
|
|
-- Respects full path input in `vim.filetype.match()`
|
|
MiniIcons.get('file', '.git/info/attributes')
|
|
<
|
|
- `'filetype'` - icon data for 'filetype' values.
|
|
Icon names:
|
|
- <Input>: any string.
|
|
- <Built-in>: any filetype that is reasonably used in Neovim ecosystem.
|
|
This category is intended as a widest net for supporting use cases.
|
|
Users are encouraged to have a specific filetype detection set up.
|
|
|
|
Examples: >lua
|
|
|
|
MiniIcons.get('filetype', 'lua')
|
|
MiniIcons.get('filetype', 'help')
|
|
MiniIcons.get('filetype', 'minifiles')
|
|
<
|
|
- `'lsp'` - icon data for various "LSP kind" values.
|
|
Icon names:
|
|
- <Input>: any string.
|
|
- <Built-in>: only namesspace entries from LSP specification that are
|
|
can be displayed to user. Like `CompletionItemKind`, `SymbolKind`, etc.
|
|
|
|
Examples: >lua
|
|
|
|
MiniIcons.get('lsp', 'array')
|
|
MiniIcons.get('lsp', 'keyword')
|
|
<
|
|
- `'os'` - icon data for popular operating systems.
|
|
Icon names:
|
|
- <Input>: any string.
|
|
- <Built-in>: only operating systems which have `nf-md-*` class icon.
|
|
|
|
Examples: >lua
|
|
|
|
MiniIcons.get('os', 'linux')
|
|
MiniIcons.get('os', 'arch')
|
|
MiniIcons.get('os', 'macos')
|
|
<
|
|
{name} `(string)` Icon name within category. Use |MiniIcons.list()| to get icon
|
|
names which are explicitly supported for specific category.
|
|
|
|
Return ~
|
|
`(...)` Tuple of icon string, highlight group name it is suggested to be
|
|
highlighted with, and boolean indicating whether this icon was returned
|
|
as a result of fallback to default. Example: >lua
|
|
|
|
-- Results into `icon=''`, `hl='MiniIconsAzure'`, `is_default=false`
|
|
local icon, hl, is_default = MiniIcons.get('file', 'file.lua')
|
|
|
|
-- Results into `icon=''`, `hl='MiniIconsGrey'`, `is_default=true`
|
|
local icon, hl, is_default = MiniIcons.get('file', 'not-supported')
|
|
<
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.list()*
|
|
`MiniIcons.list`({category})
|
|
List explicitly supported icon names
|
|
|
|
Parameters ~
|
|
{category} `(string)` Category name supported by |MiniIcons.get()|.
|
|
|
|
Return ~
|
|
`(table)` Array of icon names which are explicitly supported for category.
|
|
Note, that `'file'` and `'extension'` categories support much more icon names
|
|
via their fallback to using |vim.filetype.match()| with `'filetype'` category.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.mock_nvim_web_devicons()*
|
|
`MiniIcons.mock_nvim_web_devicons`()
|
|
Mock 'nvim-web-devicons' module
|
|
|
|
Call this function to mock exported functions of 'nvim-tree/nvim-web-devicons'
|
|
plugin. It will mock all its functions which return icon data by
|
|
using |MiniIcons.get()| equivalent.
|
|
|
|
This function is useful if any plugins relevant to you depend solely on
|
|
'nvim-web-devicons' and have not yet added an integration with 'mini.icons'.
|
|
|
|
Full example of usage: >lua
|
|
|
|
require('mini.icons').setup()
|
|
MiniIcons.mock_nvim_web_devicons()
|
|
<
|
|
Works without installed 'nvim-web-devicons' and even with it installed (needs
|
|
to be called after 'nvim-web-devicons' is set up).
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniIcons.tweak_lsp_kind()*
|
|
`MiniIcons.tweak_lsp_kind`({mode})
|
|
Tweak built-in LSP kind names
|
|
|
|
Update in place appropriate maps in |vim.lsp.protocol| (`CompletionItemKind`
|
|
and `SymbolKind`) by using icon strings from "lsp" category. Only "numeric
|
|
id to kind name" part is updated (to preserve data from original map).
|
|
|
|
Updating is done in one of these modes:
|
|
- Append: add icon after text.
|
|
- Prepend: add icon before text (default).
|
|
- Replace: use icon instead of text.
|
|
|
|
Notes:
|
|
- Makes |mini.completion| show icons, as it uses built-in protocol map.
|
|
- Results in loading whole `vim.lsp` module, so might add significant amount
|
|
of time on startup. Call it lazily. For example, with |MiniDeps.later()|: >
|
|
|
|
require('mini.icons').setup()
|
|
MiniDeps.later(MiniIcons.tweak_lsp_kind)
|
|
<
|
|
Parameters ~
|
|
{mode} `(string|nil)` One of "prepend" (default), "append", "replace".
|
|
|
|
|
|
vim:tw=78:ts=8:noet:ft=help:norl: |