Collection of 20+ minimal, independent, and fast Lua modules dedicated to improve Neovim (version 0.5 and higher) experience. Think about it as "Swiss Army knife" among Neovim plugins: it has many different independent tools (modules) suitable for most common tasks. Each module can be used as a separate sub-plugin without any startup and usage overhead.
If you want to help this project grow but don't know where to start, check out contributing guides or simply star this project on Github.
This plugin offers two branches to install from:
main
(default) will have latest development version of plugin. All changes since last stable release should be perceived as being in beta testing phase (meaning they already passed alpha-testing and are moderately settled).stable
will be updated only upon releases with code tested during public beta-testing phase inmain
branch.
There are at least the following ways to install this plugin:
-
Using wbthomason/packer.nvim:
-- Development use 'echasnovski/mini.nvim' -- Stable use { 'echasnovski/mini.nvim', branch = 'stable' }
-
Using junegunn/vim-plug:
" Development Plug 'echasnovski/mini.nvim' " Stable Plug 'echasnovski/mini.nvim', { 'branch': 'stable' }
-
Each module is independent and implemented within single file. You can copy corresponding file from 'lua/mini/' directory to your '.config/nvim/lua' directory and use it from there.
Don't forget to call module's setup()
(if required) to enable its functionality.
Note: if you are on Windows, there might be problems with too long file paths (like error: unable to create file <some file name>: Filename too long
). Try doing one of the following:
- Enable corresponding git global config value:
git config --system core.longpaths true
. Then try to reinstall. - Install plugin in other place with shorter path.
- Design. Each module is designed to solve a particular problem targeting balance between feature-richness (handling as many edge-cases as possible) and simplicity of implementation/support. Granted, not all of them ended up with the same balance, but it is the goal nevertheless.
- Independence. Modules are independent of each other and can be run without external dependencies. Although some of them may need dependencies for full experience.
- Structure. Each module is a submodule for a placeholder "mini" module. So, for example, "surround" module should be referred to as "mini.surround". As later will be explained, this plugin can also be referred to as "MiniSurround".
- Setup:
- Each module (if needed) should be setup separately with
require(<name of module>).setup({})
(possibly replace {} with your config table or omit to use defaults). You can supply only values which differ from defaults, which will be used for the rest ones. - Call to module's
setup()
always creates a global Lua object with coherent camel-case name:require('mini.surround').setup()
creates_G.MiniSurround
. This allows for a simpler usage of plugin functionality: instead ofrequire('mini.surround')
useMiniSurround
(or manually:lua MiniSurround.*
in command line); available fromv:lua
likev:lua.MiniSurround
. Considering this, "module" and "Lua object" names can be used interchangeably: 'mini.surround' and 'MiniSurround' will mean the same thing. - Each supplied
config
table is stored inconfig
field of global object. LikeMiniSurround.config
. - Values of
config
, which affect runtime activity, can be changed on the fly to have effect. For example,MiniSurround.config.n_lines
can be changed during runtime; but changingMiniSurround.config.mappings
won't have any effect (as mappings are created once duringsetup()
).
- Each module (if needed) should be setup separately with
- Buffer local configuration. Each module can be additionally configured to use certain runtime config settings locally to buffer. See
mini.nvim-buffer-local-config
section in help file for more information. - Disabling. Each module's core functionality can be disabled globally or locally to buffer by creating appropriate global or buffer-scoped variables equal to
v:true
. Seemini.nvim-disabling-recipes
section in help file for common recipes. - Highlight groups. Appearance of module's output is controlled by certain highlight group (see
:h highlight-groups
). To customize them, usehighlight
command. Note: currently not many Neovim themes support this plugin's highlight groups; fixing this situation is highly appreciated. To see a more calibrated look, use MiniBase16 or plugin's colorschememinischeme
. - Stability. Each module upon release is considered to be relatively stable: both in terms of setup and functionality. Any non-bugfix backward-incompatible change will be released gradually as much as possible.
This plugin comes with an official colorscheme named minischeme
. This is a MiniBase16 theme created with faster version of the following Lua code: require('mini.base16').setup({palette = palette, name = 'minischeme', use_cterm = true})
where palette
is:
- For dark 'background':
require('mini.base16').mini_palette('#112641', '#e2e98f', 75)
- For light 'background':
require('mini.base16').mini_palette('#e2e5ca', '#002a83', 75)
Activate it as a regular colorscheme
.
All examples use this colorscheme.
Extend and create a
/i
textobjects (like in di(
or va"
). It enhances some builtin textobjects (like a(
, a)
, a'
, and more), creates new ones (like a*
, a<Space>
, af
, a?
, and more), and allows user to create their own. Supports dot-repeat, v:count
, different search methods, consecutive application, and customization via Lua patterns or functions. Has builtins for brackets, quotes, function call, argument, tag, user prompt, and any punctuation/digit/whitespace character.
Default config
:
{
-- Table with textobject id as fields, textobject specification as values.
-- Also use this to disable builtin textobjects. See |MiniAi.config|.
custom_textobjects = nil,
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
-- Main textobject prefixes
around = 'a',
inside = 'i',
-- Next/last variants
around_next = 'an',
inside_next = 'in',
around_last = 'al',
inside_last = 'il',
-- Move cursor to corresponding edge of `a` textobject
goto_left = 'g[',
goto_right = 'g]',
},
-- Number of lines within which textobject is searched
n_lines = 50,
-- How to search for object (first inside current line, then inside
-- neighborhood). One of 'cover', 'cover_or_next', 'cover_or_prev',
-- 'cover_or_nearest', 'next', 'previous', 'nearest'.
search_method = 'cover_or_next',
}
For more information, read 'mini.ai' section of help file.
Plugins with similar functionality:
Fast implementation of chriskempson/base16 theme for manually supplied palette. Has unique palette generator which needs only background and foreground colors.
Default config
:
{
-- Table with names from `base00` to `base0F` and values being strings of
-- HEX colors with format "#RRGGBB". NOTE: this should be explicitly
-- supplied in `setup()`.
palette = nil,
-- Whether to support cterm colors. Can be boolean, `nil` (same as
-- `false`), or table with cterm colors. See `setup()` documentation for
-- more information.
use_cterm = nil,
}
For more information, read 'mini.base16' section of help file.
Plugins with similar functionality:
Buffer removing (unshow, delete, wipeout) while saving window layout.
Default config
:
{
-- Whether to set Vim's settings for buffers (allow hidden buffers)
set_vim_settings = true,
}
For more information, read 'mini.bufremove' section of help file.
Plugins with similar functionality:
Fast and familiar per-line code commenting.
Default config
:
{
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
-- Toggle comment (like `gcip` - comment inner paragraph) for both
-- Normal and Visual modes
comment = 'gc',
-- Toggle comment on current line
comment_line = 'gcc',
-- Define 'comment' textobject (like `dgc` - delete whole comment block)
textobject = 'gc',
},
-- Hook functions to be executed at certain stage of commenting
hooks = {
-- Before successful commenting. Does nothing by default.
pre = function() end,
-- After successful commenting. Does nothing by default.
post = function() end,
},
}
For more information, read 'mini.comment' section of help file.
Plugins with similar functionality:
Async (with customizable 'debounce' delay) 'two-stage chain completion': first builtin LSP, then configurable fallback. Also has functionality for completion item info and function signature (both in floating window appearing after customizable delay).
Default config
:
{
-- Delay (debounce type, in ms) between certain Neovim event and action.
-- This can be used to (virtually) disable certain automatic actions by
-- setting very high delay time (like 10^7).
delay = { completion = 100, info = 100, signature = 50 },
-- Maximum dimensions of floating windows for certain actions. Action
-- entry should be a table with 'height' and 'width' fields.
window_dimensions = {
info = { height = 25, width = 80 },
signature = { height = 25, width = 80 },
},
-- Way of how module does LSP completion
lsp_completion = {
-- `source_func` should be one of 'completefunc' or 'omnifunc'.
source_func = 'completefunc',
-- `auto_setup` should be boolean indicating if LSP completion is set up
-- on every `BufEnter` event.
auto_setup = true,
-- `process_items` should be a function which takes LSP
-- 'textDocument/completion' response items and word to complete. Its
-- output should be a table of the same nature as input items. The most
-- common use-cases are custom filtering and sorting. You can use
-- default `process_items` as `MiniCompletion.default_process_items()`.
process_items = --<function: filters out snippets; sorts by LSP specs>,
},
-- Fallback action. It will always be run in Insert mode. To use Neovim's
-- built-in completion (see `:h ins-completion`), supply its mapping as
-- string. Example: to use 'whole lines' completion, supply '<C-x><C-l>'.
fallback_action = --<function: like `<C-n>` completion>,
-- Module mappings. Use `''` (empty string) to disable one. Some of them
-- might conflict with system mappings.
mappings = {
force_twostep = '<C-Space>', -- Force two-step completion
force_fallback = '<A-Space>', -- Force fallback completion
},
-- Whether to set Vim's settings for better experience (modifies
-- `shortmess` and `completeopt`)
set_vim_settings = true,
}
For more information, read 'mini.completion' section of help file.
Plugins with similar functionality:
Automatic highlighting of word under cursor (displayed after customizable delay). Current word under cursor can be highlighted differently.
Default config
:
{
-- Delay (in ms) between when cursor moved and when highlighting appeared
delay = 100,
}
For more information, read 'mini.cursorword' section of help file.
Plugins with similar functionality:
Generation of help files from EmmyLua-like annotations. Allows flexible customization of output via hook functions. Used for documenting this plugin.
Default config
:
{
-- Lua string pattern to determine if line has documentation annotation.
-- First capture group should describe possible section id. Default value
-- means that annotation line should:
-- - Start with `---` at first column.
-- - Any non-whitespace after `---` will be treated as new section id.
-- - Single whitespace at the start of main text will be ignored.
annotation_pattern = '^%-%-%-(%S*) ?',
-- Identifier of block annotation lines until first captured identifier
default_section_id = '@text',
-- Hooks to be applied at certain stage of document life cycle. Should
-- modify its input in place (and not return new one).
hooks = {
-- Applied to block before anything else
block_pre = --<function: infers header sections (tag and/or signature)>,
-- Applied to section before anything else
section_pre = --<function: replaces current aliases>,
-- Applied if section has specified captured id
sections = {
['@alias'] = --<function: registers alias in MiniDoc.current.aliases>,
['@class'] = --<function>,
-- For most typical usage see |MiniDoc.afterlines_to_code|
['@eval'] = --<function: evaluates lines; replaces with their return>,
['@field'] = --<function>,
['@param'] = --<function>,
['@private'] = --<function: registers block for removal>,
['@return'] = --<function>,
['@seealso'] = --<function>,
['@signature'] = --<function: formats signature of documented object>,
['@tag'] = --<function: turns its line in proper tag lines>,
['@text'] = --<function: purposefully does nothing>,
['@type'] = --<function>,
['@usage'] = --<function>,
},
-- Applied to section after all previous steps
section_post = --<function: currently does nothing>,
-- Applied to block after all previous steps
block_post = --<function: does many things>,
-- Applied to file after all previous steps
file = --<function: adds separator>,
-- Applied to doc after all previous steps
doc = --<function: adds modeline>,
},
-- Path (relative to current directory) to script which handles project
-- specific help file generation (like custom input files, hooks, etc.).
script_path = 'scripts/minidoc.lua',
}
For more information, read 'mini.doc' section of help file (which is created with this module).
Plugins with similar functionality:
Functions for fast and simple fuzzy matching. It has not only functions to perform fuzzy matching of one string to others, but also a sorter for nvim-telescope/telescope.nvim.
Default config
:
{
-- Maximum allowed value of match features (width and first match). All
-- feature values greater than cutoff can be considered "equally bad".
cutoff = 100,
}
For more information, read 'mini.fuzzy' section of help file.
Plugins with similar functionality:
Visualize and operate on indent scope. Supports customization of debounce delay, animation style, and different granularity of options for scope computing algorithm.
Default config
:
{
draw = {
-- Delay (in ms) between event and start of drawing scope indicator
delay = 100,
-- Animation rule for scope's first drawing. A function which, given next
-- and total step numbers, returns wait time (in ms). See
-- |MiniIndentscope.gen_animation()| for builtin options. To not use
-- animation, supply `require('mini.indentscope').gen_animation('none')`.
animation = --<function: implements constant 20ms between steps>,
},
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
-- Textobjects
object_scope = 'ii',
object_scope_with_border = 'ai',
-- Motions (jump to respective border line; if not present - body line)
goto_top = '[i',
goto_bottom = ']i',
},
-- Options which control computation of scope. Buffer local values can be
-- supplied in buffer variable `vim.b.miniindentscope_options`.
options = {
-- Type of scope's border: which line(s) with smaller indent to
-- categorize as border. Can be one of: 'both', 'top', 'bottom', 'none'.
border = 'both',
-- Whether to use cursor column when computing reference indent. Useful to
-- see incremental scopes with horizontal cursor movements.
indent_at_cursor = true,
-- Whether to first check input line to be a border of adjacent scope.
-- Use it if you want to place cursor on function header to get scope of
-- its body.
try_as_border = false,
},
-- Which character to use for drawing scope indicator
symbol = 'â•Ž',
}
For more information, read 'mini.indentscope' section of help file.
Plugins with similar functionality:
Minimal and fast module for smarter jumping to a single character. Initial idea and implementation by Adam BlaĹľek.
Default config
:
{
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
forward = 'f',
backward = 'F',
forward_till = 't',
backward_till = 'T',
repeat_jump = ';',
},
-- Delay values (in ms) for different functionalities. Set any of them to
-- a very big number (like 10^7) to virtually disable.
delay = {
-- Delay between jump and highlighting all possible jumps
highlight = 250,
-- Delay between jump and automatic stop if idle (no jump is done)
idle_stop = 10000000,
},
}
For more information, read 'mini.jump' section of help file.
Plugins with similar functionality:
Minimal and fast Lua plugin for jumping (moving cursor) within visible lines via iterative label filtering. Supports custom jump targets (spots), labels, hooks, allowed windows and lines, and more.
Default config
:
{
-- Function producing jump spots (byte indexed) for a particular line.
-- For more information see |MiniJump2d.start|.
-- If `nil` (default) - use |MiniJump2d.default_spotter|
spotter = nil,
-- Characters used for labels of jump spots (in supplied order)
labels = 'abcdefghijklmnopqrstuvwxyz',
-- Which lines are used for computing spots
allowed_lines = {
blank = true, -- Blank line (not sent to spotter even if `true`)
cursor_before = true, -- Lines before cursor line
cursor_at = true, -- Cursor line
cursor_after = true, -- Lines after cursor line
fold = true, -- Start of fold (not sent to spotter even if `true`)
},
-- Which windows from current tabpage are used for visible lines
allowed_windows = {
current = true,
not_current = true,
},
-- Functions to be executed at certain events
hooks = {
before_start = nil, -- Before jump start
after_jump = nil, -- After jump was actually done
},
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
start_jumping = '<CR>',
},
}
For more information, read 'mini.jump2d' section of help file.
Plugins with similar functionality:
- phaazon/hop.nvim (main inspiration behind this module)
- ggandor/lightspeed.nvim
Collection of miscellaneous useful functions. Like put()
and put_text()
which print Lua objects to command line and current buffer respectively.
Default config
:
{
-- Array of fields to make global (to be used as independent variables)
make_global = { 'put', 'put_text' },
}
For more information, read 'mini.misc' section of help file.
Autopairs plugin which has minimal defaults and functionality to do per-key expression mappings.
Default config
:
{
-- In which modes mappings from this `config` should be created
modes = { insert = true, command = false, terminal = false },
-- Global mappings. Each right hand side should be a pair information, a
-- table with at least these fields (see more in |MiniPairs.map|):
-- - <action> - one of 'open', 'close', 'closeopen'.
-- - <pair> - two character string for pair to be used.
-- By default pair is not inserted after `\`, quotes are not recognized by
-- `<CR>`, `'` does not insert pair after a letter.
-- Only parts of tables can be tweaked (others will use these defaults).
mappings = {
['('] = { action = 'open', pair = '()', neigh_pattern = '[^\\].' },
['['] = { action = 'open', pair = '[]', neigh_pattern = '[^\\].' },
['{'] = { action = 'open', pair = '{}', neigh_pattern = '[^\\].' },
[')'] = { action = 'close', pair = '()', neigh_pattern = '[^\\].' },
[']'] = { action = 'close', pair = '[]', neigh_pattern = '[^\\].' },
['}'] = { action = 'close', pair = '{}', neigh_pattern = '[^\\].' },
['"'] = { action = 'closeopen', pair = '""', neigh_pattern = '[^\\].', register = { cr = false } },
["'"] = { action = 'closeopen', pair = "''", neigh_pattern = '[^%a\\].', register = { cr = false } },
['`'] = { action = 'closeopen', pair = '``', neigh_pattern = '[^\\].', register = { cr = false } },
},
}
For more information, read 'mini.pairs' section of help file.
Plugins with similar functionality:
Session management (read, write, delete) which works using |mksession|. It was heavily inspired by 'vim-startify' and should work out of the box with sessions created by it. Works with global (from configured directory) and local (from current directory) sessions.
Default config
:
{
-- Whether to read latest session if Neovim opened without file arguments
autoread = false,
-- Whether to write current session before quitting Neovim
autowrite = true,
-- Directory where global sessions are stored (use `''` to disable)
directory = --<"session" subdir of user data directory from |stdpath()|>,
-- File for local session (use `''` to disable)
file = 'Session.vim',
-- Whether to force possibly harmful actions (meaning depends on function)
force = { read = false, write = true, delete = false },
-- Hook functions for actions. Default `nil` means 'do nothing'.
hooks = {
-- Before successful action
pre = { read = nil, write = nil, delete = nil },
-- After successful action
post = { read = nil, write = nil, delete = nil },
},
-- Whether to print session path after action
verbose = { read = false, write = true, delete = true },
}
For more information, read 'mini.sessions' section of help file.
Plugins with similar functionality:
Minimal, fast, and flexible start screen. Displayed items are fully customizable both in terms of what they do and how they look (with reasonable defaults). Item selection can be done using prefix query with instant visual feedback.
Default config
:
{
-- Whether to open starter buffer on VimEnter. Not opened if Neovim was
-- started with intent to show something else.
autoopen = true,
-- Whether to evaluate action of single active item
evaluate_single = false,
-- Items to be displayed. Should be an array with the following elements:
-- - Item: table with <action>, <name>, and <section> keys.
-- - Function: should return one of these three categories.
-- - Array: elements of these three types (i.e. item, array, function).
-- If `nil` (default), default items will be used (see |mini.starter|).
items = nil,
-- Header to be displayed before items. Converted to single string via
-- `tostring` (use `\n` to display several lines). If function, it is
-- evaluated first. If `nil` (default), polite greeting will be used.
header = nil,
-- Footer to be displayed after items. Converted to single string via
-- `tostring` (use `\n` to display several lines). If function, it is
-- evaluated first. If `nil` (default), default usage help will be shown.
footer = nil,
-- Array of functions to be applied consecutively to initial content.
-- Each function should take and return content for 'Starter' buffer (see
-- |mini.starter| and |MiniStarter.content| for more details).
content_hooks = nil,
-- Characters to update query. Each character will have special buffer
-- mapping overriding your global ones. Be careful to not add `:` as it
-- allows you to go into command mode.
query_updaters = 'abcdefghijklmnopqrstuvwxyz0123456789_-.',
}
For more information, read 'mini.starter' section of help file (also contains example configurations similar to 'vim-startify' and 'dashboard-nvim'). For its benchmarks alongside plugins with similar functionality, see benchmarks/starter/startup-summary.md (more details here).
Plugins with similar functionality:
Minimal and fast statusline. Has ability to use custom content supplied with concise function (using module's provided section functions) along with builtin default. For full experience needs Nerd font, lewis6991/gitsigns.nvim plugin, and kyazdani42/nvim-web-devicons plugin (but works without any them).
Default config
:
{
-- Content of statusline as functions which return statusline string. See
-- `:h statusline` and code of default contents (used instead of `nil`).
content = {
-- Content for active window
active = nil,
-- Content for inactive window(s)
inactive = nil,
},
-- Whether to use icons by default
use_icons = true,
-- Whether to set Vim's settings for statusline (make it always shown with
-- 'laststatus' set to 2). To use global statusline in Neovim>=0.7.0, set
-- this to `false` and 'laststatus' to 3.
set_vim_settings = true,
}
For more information, read 'mini.statusline' section of help file.
Plugins with similar functionality:
Fast surround plugin. Add, delete, replace, find, highlight surrounding (like pair of parenthesis, quotes, etc.). Has special "function call", "tag", and "interactive" surroundings. Supports dot-repeatability, textobject, motions.
Default config
:
{
-- Add custom surroundings to be used on top of builtin ones. For more
-- information with examples, see `:h MiniSurround.config`.
custom_surroundings = nil,
-- Duration (in ms) of highlight when calling `MiniSurround.highlight()`
highlight_duration = 500,
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
add = 'sa', -- Add surrounding in Normal and Visual modes
delete = 'sd', -- Delete surrounding
find = 'sf', -- Find surrounding (to the right)
find_left = 'sF', -- Find surrounding (to the left)
highlight = 'sh', -- Highlight surrounding
replace = 'sr', -- Replace surrounding
update_n_lines = 'sn', -- Update `n_lines`
},
-- Number of lines within which surrounding is searched
n_lines = 20,
-- How to search for surrounding (first inside current line, then inside
-- neighborhood). One of 'cover', 'cover_or_next', 'cover_or_prev',
-- 'cover_or_nearest'. For more details, see `:h MiniSurround.config`.
search_method = 'cover',
}
For more information, read 'mini.surround' section of help file.
Plugins with similar functionality:
Minimal tabline which always shows listed (see :h buflisted
) buffers. Allows showing extra information section in case of multiple vim tabpages. For full experience needs kyazdani42/nvim-web-devicons.
Default config
:
{
-- Whether to show file icons (requires 'kyazdani42/nvim-web-devicons')
show_icons = true,
-- Whether to set Vim's settings for tabline (make it always shown and
-- allow hidden buffers)
set_vim_settings = true,
-- Where to show tabpage section in case of multiple vim tabpages.
-- One of 'left', 'right', 'none'.
tabpage_section = 'left',
}
For more information, read 'mini.tabline' section of help file.
Plugins with similar functionality:
Framework for writing extensive Neovim plugin tests. Supports hierarchical tests, hooks, parametrization, filtering (like from current file or cursor position), screen tests, "busted-style" emulation, customizable reporters, and more. Designed to be used with provided wrapper for managing child Neovim processes.
Default config
:
{
-- Options for collection of test cases. See `:h MiniTest.collect()`.
collect = {
-- Temporarily emulate functions from 'busted' testing framework
-- (`describe`, `it`, `before_each`, `after_each`, and more)
emulate_busted = true,
-- Function returning array of file paths to be collected.
-- Default: all Lua files in 'tests' directory starting with 'test_'.
find_files = function()
return vim.fn.globpath('tests', '**/test_*.lua', true, true)
end,
-- Predicate function indicating if test case should be executed
filter_cases = function(case) return true end,
},
-- Options for execution of test cases. See `:h MiniTest.execute()`.
execute = {
-- Table with callable fields `start()`, `update()`, and `finish()`
reporter = nil,
-- Whether to stop execution after first error
stop_on_error = false,
},
-- Path (relative to current directory) to script which handles project
-- specific test running
script_path = 'scripts/minitest.lua',
}
Further reading:
- For more detailed information, read 'mini.test' section of help file.
- For more hands-on introduction based on examples, see TESTING.md.
- For more in-depth usage see tests of this plugin.
Plugins with similar functionality:
- nvim-lua/plenary.nvim ('test_harness', 'busted', 'luassert' modules)
Automatic highlighting of trailing whitespace with functionality to remove it.
Default config
:
{
-- Highlight only in normal buffers (ones with empty 'buftype'). This is
-- useful to not show trailing whitespace where it usually doesn't matter.
only_in_normal_buffers = true,
}
For more information, read 'mini.trailspace' section of help file.
Plugins with similar functionality:
This is the list of modules I currently intend to implement eventually (as my free time and dedication will allow), in alphabetical order:
- 'mini.align' - align text with respect to some separators. Something like tommcdo/vim-lion.
- 'mini.basics' - configurable collection of options and mappings sets intended mostly for quick "up and running" Neovim config. Something like a combination of tpope/vim-sensible and tpope/vim-unimpaired.
- 'mini.clue' - "show as you type" floating window with customizable information. Something like folke/which-key.nvim and anuvyklack/hydra.nvim
- 'mini.filetree' - file tree viewer. Simplified version of kyazdani42/nvim-tree.
- 'mini.root' - automatically change current working directory. Something like airblade/vim-rooter.
- 'mini.snippets' - work with snippets. Something like L3MON4D3/LuaSnip but only with more straightforward functionality.
- 'mini.swap' - exchange two regions of text. Something like tommcdo/vim-exchange.
- 'mini.terminals' - coherently manage terminal windows and send text from buffers to terminal windows. Something like kassio/neoterm.