mini.icons documentation

Generated from the main branch of ‘mini.nvim’

mini.icons Icon provider

MIT License Copyright (c) 2024 Evgeni Chasnovski


Module

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, set it directly with nvim_set_hl().


setup()

MiniIcons.setup({config})

Module setup

Parameters

{config} (table|nil) Module config table. See MiniIcons.config.

Usage

require('mini.icons').setup() -- use default config
-- OR
require('mini.icons').setup({}) -- replace {} with your config table

config

MiniIcons.config

Defaults

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:

    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:

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:

-- 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".

get()

MiniIcons.get({category}, {name})

Get icon data

Usage example:

-- 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:

    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:

    -- 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:

    -- 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('file') 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:

    -- 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:

    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:

    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:

    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:

-- 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')

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.


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:

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).


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”.