mini.starter documentation
Generated from the main
branch of ‘mini.nvim’
mini.starter Start screen
MIT License Copyright (c) 2021 Evgeni Chasnovski
Module
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.
Key design ideas:
All available actions are defined inside items. Each item should have the following info:
<action> - function or string for vim.cmd() which is executed when item is chosen. Empty string result in placeholder “inactive” item.
<name> - string which will be displayed and used for choosing.
<section> - string representing to which section item belongs. There are pre-configured whole sections in MiniStarter.sections.
Configure what items are displayed by supplying an array which can be normalized to an array of items. Read about how supplied items are normalized in MiniStarter.refresh().
Modify the final look by supplying content hooks: functions which take buffer content (see MiniStarter.get_content()) and identifier as input while returning buffer content as output. There are pre-configured content hook generators in MiniStarter.gen_hook.
Choosing an item can be done in two ways:
Type prefix query to filter item by matching its name (ignoring case). Displayed information is updated after every typed character. For every item its unique prefix is highlighted.
Use Up/Down arrows and hit Enter.
Allow multiple simultaneously open Starter buffers.
What is doesn’t do:
- It doesn’t support fuzzy query for items. And probably will never do.
Setup
This module needs a setup with require('mini.starter').setup({})
(replace {}
with your config
table). It will create global Lua table MiniStarter
which you can use for scripting or manually (with :lua MiniStarter.*
).
See MiniStarter.config for config
structure and default values. For some configuration examples (including one similar to ‘vim-startify’ and ‘dashboard-nvim’), see MiniStarter-example-config.
You can override runtime config settings locally to buffer inside vim.b.ministarter_config
which should have same structure as MiniStarter.config
. See mini.nvim-buffer-local-config for more details. Note: vim.b.ministarter_config
is copied to Starter buffer from current buffer allowing full customization.
To stop module from showing non-error feedback, set config.silent = true
.
Highlight groups
MiniStarterCurrent
- current item.MiniStarterFooter
- footer units.MiniStarterHeader
- header units.MiniStarterInactive
- inactive item.MiniStarterItem
- item name.MiniStarterItemBullet
- units from MiniStarter.gen_hook.adding_bullet().MiniStarterItemPrefix
- unique query for item.MiniStarterSection
- section units.MiniStarterQuery
- current query in active items.
To change any highlight group, set it directly with nvim_set_hl().
Disabling
To disable core functionality, set vim.g.ministarter_disable
(globally) or vim.b.ministarter_disable
(for a buffer) to true
. Considering high number of different scenarios and customization intentions, writing exact rules for disabling module’s functionality is left to user. See mini.nvim-disabling-recipes for common recipes.
Example config
Similar to ‘mhinz/vim-startify’
local starter = require('mini.starter')
starter.setup({
evaluate_single = true,
items = {
starter.sections.builtin_actions(),
starter.sections.recent_files(10, false),
starter.sections.recent_files(10, true),
-- Use this if you set up 'mini.sessions'
starter.sections.sessions(5, true)
},
content_hooks = {
starter.gen_hook.adding_bullet(),
starter.gen_hook.indexing('all', { 'Builtin actions' }),
starter.gen_hook.padding(3, 2),
},
})
Similar to ‘glepnir/dashboard-nvim’
local starter = require('mini.starter')
starter.setup({
items = {
starter.sections.telescope(),
},
content_hooks = {
starter.gen_hook.adding_bullet(),
starter.gen_hook.aligning('center', 'center'),
},
})
Demo of capabilities
local my_items = {
{ name = 'Echo random number', action = 'lua print(math.random())', section = 'Section 1' },
function()
return {
{ name = 'Item #1 from function', action = [[echo 'Item #1']], section = 'From function' },
{ name = 'Placeholder (always inactive) item', action = '', section = 'From function' },
function()
return {
name = 'Item #1 from double function',
action = [[echo 'Double function']],
section = 'From double function',
}
end,
}
end,
{ name = [[Another item in 'Section 1']], action = 'lua print(math.random() + 10)', section = 'Section 1' },
}
local footer_n_seconds = (function()
local timer = vim.loop.new_timer()
local n_seconds = 0
timer:start(0, 1000, vim.schedule_wrap(function()
if vim.bo.filetype ~= 'ministarter' then
timer:stop()
return
end
n_seconds = n_seconds + 1
MiniStarter.refresh()
end))
return function()
return 'Number of seconds since opening: ' .. n_seconds
end
end)()
local hook_top_pad_10 = function(content)
-- Pad from top
for _ = 1, 10 do
-- Insert at start a line with single content unit
table.insert(content, 1, { { type = 'empty', string = '' } })
end
return content
end
local starter = require('mini.starter')
starter.setup({
items = my_items,
footer = footer_n_seconds,
content_hooks = { hook_top_pad_10 },
})
Lifecycle
Open with MiniStarter.open(). It includes creating buffer with appropriate options, mappings, behavior; call to MiniStarter.refresh(); issue
MiniStarterOpened
User event.Wait for user to choose an item. This is done using following logic:
Typing any character from
MiniStarter.config.query_updaters
leads to updating query. Read more in MiniStarter.add_to_query().<BS> deletes latest character from query.
<Down>/<Up>, <C-n>/<C-p>, <M-j>/<M-k> move current item.
<CR> executes action of current item.
<C-c> closes Starter buffer.
Evaluate current item when appropriate (after
<CR>
or when there is a single item andMiniStarter.config.evaluate_single
istrue
). This executes item’saction
.
setup()
MiniStarter.setup
({config})
Module setup
Parameters
{config} (table|nil)
Module config table. See MiniStarter.config.
Usage
require('mini.starter').setup() -- use default config
-- OR
require('mini.starter').setup({}) -- replace {} with your config table
config
MiniStarter.config
Defaults
MiniStarter.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.get_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_-.',
-- Whether to disable showing non-error feedback
silent = false,
}
open()
MiniStarter.open
({buf_id})
Open Starter buffer
Create buffer if necessary and move into it.
Set buffer options. Note that settings are done with :noautocmd to achieve a massive speedup.
Set buffer mappings. Besides basic mappings (described inside “Lifecycle of Starter buffer” of mini.starter), map every character from
MiniStarter.config.query_updaters
to add itself to query with MiniStarter.add_to_query().Populate buffer with MiniStarter.refresh().
Issue custom
MiniStarterOpened
event to allow acting upon opening Starter buffer. Use it withautocmd User MiniStarterOpened <your command>
.
Note: to fully use it in autocommand, use autocmd-nested. Example:
local starter_open = function() MiniStarter.open() end
local au_opts = { nested = true, callback = starter_open }
vim.api.nvim_create_autocmd('TabNewEntered', au_opts)
Parameters
{buf_id} (number|nil)
Identifier of existing valid buffer (see bufnr()) to open inside. Default: create a new one.
refresh()
MiniStarter.refresh
({buf_id})
Refresh Starter buffer
Normalize
MiniStarter.config.items
:Flatten: recursively (in depth-first fashion) parse its elements. If function is found, execute it and continue with parsing its output (this allows deferring item collection up until it is actually needed). If proper item is found (table with fields
action
,name
,section
), add it to output.Sort: order first by section and then by item id (both in order of appearance).
Normalize
MiniStarter.config.header
andMiniStarter.config.footer
to be multiple lines by splitting at\n
. If function - evaluate it first.Make initial buffer content (see MiniStarter.get_content() for a description of what a buffer content is). It consist from content lines with single content unit:
First lines contain strings of normalized header.
Body is for normalized items. Section names have own lines preceded by empty line.
Last lines contain separate strings of normalized footer.
Sequentially apply hooks from
MiniStarter.config.content_hooks
to content. All hooks are applied with(content, buf_id)
signature. Output of one hook serves as first argument to the next.Gather final items from content with MiniStarter.content_to_items().
Convert content to buffer lines with MiniStarter.content_to_lines() and add them to buffer.
Add highlighting of content units.
Position cursor.
Make current query. This results into some items being marked as “inactive” and updating highlighting of current query on “active” items.
Note: this function is executed on every VimResized to allow more responsive behavior.
Parameters
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
close()
MiniStarter.close
({buf_id})
Close Starter buffer
Parameters
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
sections
MiniStarter.sections
Table of pre-configured sections
sections.builtin_actions()
MiniStarter.sections.builtin_actions
()
Section with builtin actions
Return
(table)
Array of items.
sections.sessions()
MiniStarter.sections.sessions
({n}, {recent})
Section with mini.sessions sessions
Sessions are taken from MiniSessions.detected. Notes:
If it shows “‘mini.sessions’ is not set up”, it means that you didn’t call
require('mini.sessions').setup()
.If it shows “There are no detected sessions in ‘mini.sessions’”, it means that there are no sessions at the current sessions directory. Either create session or supply different directory where session files are stored (see MiniSessions.setup()).
Local session (if detected) is always displayed first.
Parameters
{n} (number|nil)
Number of returned items. Default: 5.
{recent} (boolean|nil)
Whether to use recent sessions (instead of alphabetically by name). Default: true.
Return
(function)
Function which returns array of items.
sections.recent_files()
MiniStarter.sections.recent_files
({n}, {current_dir}, {show_path})
Section with most recently used files
Files are taken from v:oldfiles.
Parameters
{n} (number|nil)
Number of returned items. Default: 5.
{current_dir} (boolean|nil)
Whether to return files only from current working directory and its subdirectories. Default: false
.
{show_path} (boolean|function|nil)
Whether to append file name with its path. If callable, will be called with full path and should return string to be directly appended to file name. Default: true
.
Return
(function)
Function which returns array of items.
sections.pick()
MiniStarter.sections.pick
()
Section with mini.pick pickers
Notes:
All actions require ‘mini.pick’ module of ‘mini.nvim’.
“Command history”, “Explorer”, and “Visited paths” items require mini.extra module of ‘mini.nvim’.
“Visited paths” items requires mini.visits module of ‘mini.nvim’.
Return
(function)
Function which returns array of items.
sections.telescope()
MiniStarter.sections.telescope
()
Section with basic Telescope pickers relevant to start screen
Notes:
All actions require nvim-telescope/telescope.nvim.
“Browser” item requires nvim-telescope/telescope-file-browser.nvim.
Return
(function)
Function which returns array of items.
gen_hook
MiniStarter.gen_hook
Table with pre-configured content hook generators
Each element is a function which returns content hook. So to use them inside MiniStarter.setup(), call them.
gen_hook.padding()
MiniStarter.gen_hook.padding
({left}, {top})
Hook generator for padding
Output is a content hook which adds constant padding from left and top. This allows tweaking the screen position of buffer content.
Parameters
{left} (number|nil)
Number of empty spaces to add to start of each content line. Default: 0.
{top} (number|nil)
Number of empty lines to add to start of content. Default: 0.
Return
(function)
Content hook.
gen_hook.adding_bullet()
MiniStarter.gen_hook.adding_bullet
({bullet}, {place_cursor})
Hook generator for adding bullet to items
Output is a content hook which adds supplied string to be displayed to the left of item.
Parameters
{bullet} (string|nil)
String to be placed to the left of item name. Default: “░”.
{place_cursor} (boolean|nil)
Whether to place cursor on the first character of bullet when corresponding item becomes current. Default: true.
Return
(function)
Content hook.
gen_hook.indexing()
MiniStarter.gen_hook.indexing
({grouping}, {exclude_sections})
Hook generator for indexing items
Output is a content hook which adds unique index to the start of item’s name. It results into shortening queries required to choose an item (at expense of clarity).
Parameters
{grouping} (string|nil)
One of “all” (number indexing across all sections) or “section” (letter-number indexing within each section). Default: “all”.
{exclude_sections} (table|nil)
Array of section names (values of section
element of item) for which index won’t be added. Default: {}
.
Return
(function)
Content hook.
gen_hook.aligning()
MiniStarter.gen_hook.aligning
({horizontal}, {vertical})
Hook generator for aligning content
Output is a content hook which independently aligns content horizontally and vertically. Window width and height are taken from first window in current tabpage displaying the Starter buffer.
Basically, this computes left and top pads for MiniStarter.gen_hook.padding() such that output lines would appear aligned in certain way.
Parameters
{horizontal} (string|nil)
One of “left”, “center”, “right”. Default: “left”.
{vertical} (string|nil)
One of “top”, “center”, “bottom”. Default: “top”.
Return
(function)
Content hook.
get_content()
MiniStarter.get_content
({buf_id})
Get content of Starter buffer
Generally, buffer content is a table in the form of “2d array” (or rather “2d list” because number of elements can differ):
Each element represents content line: an array with content units to be displayed in one buffer line.
Each content unit is a table with at least the following elements:
“type” - string with type of content. Something like “item”, “section”, “header”, “footer”, “empty”, etc.
“string” - which string should be displayed. May be an empty string.
“hl” - which highlighting should be applied to content string. May be
nil
for no highlighting.
See MiniStarter.content_to_lines() for converting content to buffer lines and MiniStarter.content_to_items() - to list of parsed items.
Notes:
- Content units with type “item” also have
item
element with all information about an item it represents. Those elements are used directly to create an array of items used for query.
Parameters
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
content_coords()
MiniStarter.content_coords
({content}, {predicate})
Helper to iterate through content
Basically, this traverses content “2d array” (in depth-first fashion; top to bottom, left to right) and returns “coordinates” of units for which predicate
is true-ish.
Parameters
{content} (table|nil)
Content “2d array”. Default: content of current buffer.
{predicate} (function|string|nil)
Predictate to filter units. If it is:
Function, then it is evaluated with unit as input.
String, then it checks unit to have this type (allows easy getting of units with some type).
nil
, all units are kept.
Return
(table)
Array of resulting units’ coordinates. Each coordinate is a table with <line> and <unit> keys. To retrieve actual unit from coordinate c
, use content[c.line][c.unit]
.
content_to_lines()
MiniStarter.content_to_lines
({content})
Convert content to buffer lines
One buffer line is made by concatenating string
element of units within same content line.
Parameters
{content} (table|nil)
Content “2d array”. Default: content of current buffer.
Return
(table)
Array of strings for each buffer line.
content_to_items()
MiniStarter.content_to_items
({content})
Convert content to items
Parse content (in depth-first fashion) and retrieve each item from item
element of content units with type “item”. This also:
Computes some helper information about how item will be actually displayed (after MiniStarter.content_to_lines()) and minimum number of prefix characters needed for a particular item to be queried single.
Modifies item’s
name
element taking it from correspondingstring
element of content unit. This allows modifying item’sname
at the stage of content hooks (like, for example, in MiniStarter.gen_hook.indexing()).
Parameters
{content} (table|nil)
Content “2d array”. Default: content of current buffer.
Return
(table)
Array of items.
eval_current_item()
MiniStarter.eval_current_item
({buf_id})
Evaluate current item
Note that it resets current query before evaluation, as it is rarely needed any more.
Parameters
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
update_current_item()
MiniStarter.update_current_item
({direction}, {buf_id})
Update current item
This makes next (with respect to direction
) active item to be current.
Parameters
{direction} (string)
One of “next” or “previous”.
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
add_to_query()
MiniStarter.add_to_query
({char}, {buf_id})
Add character to current query
Update current query by appending
char
to its end (only if it results into at least one active item) or delete latest character ifchar
isnil
.Recompute status of items: “active” if its name starts with new query, “inactive” otherwise.
Update highlighting: whole strings for “inactive” items, current query for “active” items.
Parameters
{char} (string|nil)
Single character to be added to query. If nil
, deletes latest character from query.
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.
set_query()
MiniStarter.set_query
({query}, {buf_id})
Set current query
Parameters
{query} (string|nil)
Query to be set (only if it results into at least one active item). Default: nil
for setting query to empty string, which essentially resets query.
{buf_id} (number|nil)
Buffer identifier of a valid Starter buffer. Default: current buffer.