mini.bracketed documentation
Generated from the main
branch of ‘mini.nvim’
mini.bracketed Go forward/backward with square brackets
MIT License Copyright (c) 2023 Evgeni Chasnovski
Module
Features:
Configurable Lua functions to go forward/backward to a certain target. Each function can be customized with:
Direction. One of “forward”, “backward”, “first” (forward starting from first one), “last” (backward starting from last one).
Number of times to go.
Whether to wrap on edges (going forward on last one goes to first).
Some other target specific options.
Mappings using square brackets. They are created using configurable target suffix and can be selectively disabled.
Each mapping supports [count]. Mappings are created in Normal mode; for targets which move cursor in current buffer also Visual and Operator-pending (with dot-repeat) modes are supported.
Using
lower-suffix
andupper-suffix
(lower and upper case suffix) for a single target the following mappings are created:[
+upper-suffix
: go first.[
+lower-suffix
: go backward.]
+lower-suffix
: go forward.]
+upper-suffix
: go last.
Supported targets (for more information see help for corresponding Lua function):
Target |
Mappings |
Lua function |
---|---|---|
Buffer | [B [b ]b ]B |
MiniBracketed.buffer() |
Comment block | [C [c ]c ]C |
MiniBracketed.comment() |
Conflict marker | [X [x ]x ]X |
MiniBracketed.conflict() |
Diagnostic | [D [d ]d ]D |
MiniBracketed.diagnostic() |
File on disk | [F [f ]f ]F |
MiniBracketed.file() |
Indent change | [I [i ]i ]I |
MiniBracketed.indent() |
Jump inside current buffer | [J [j ]j ]J |
MiniBracketed.jump() |
Location from location-list | [L [l ]l ]L |
MiniBracketed.location() |
Old files | [O [o ]o ]O |
MiniBracketed.oldfile() |
Quickfix entry from Quickfix | [Q [q ]q ]Q |
MiniBracketed.quickfix() |
Tree-sitter node and parents | [T [t ]t ]T |
MiniBracketed.treesitter() |
Undo from linear history | [U [u ]u ]U |
MiniBracketed.undo() |
Window in current tab | [W [w ]w ]W |
MiniBracketed.window() |
Yank entry over put region | [Y [y ]y ]Y |
MiniBracketed.yank() |
Notes:
- The
undo
target remaps u and CTRL-R keys to register undo state after undo and redo respectively. If this conflicts with your setup, either disableundo
target or make your remaps after calling MiniBracketed.setup(). To useundo
target, remap your undo/redo keys to call MiniBracketed.register_undo_state() after the action.
Setup
This module needs a setup with require('mini.bracketed').setup({})
(replace {}
with your config
table). It will create global Lua table MiniBracketed
which you can use for scripting or manually (with :lua MiniBracketed.*
).
See MiniBracketed.config for available config settings.
You can override runtime config settings (like target options) locally to buffer inside vim.b.minibracketed_config
which should have same structure as MiniBracketed.config
. See mini.nvim-buffer-local-config for more details.
Comparisons
-
Supports buffer, conflict, file, location, and quickfix targets mostly via built-in commands (like :bprevious, etc.) without configuration.
Supports files from argument list and tags. This module does not.
Doesn’t support most other this module’s targets (comment, indent, …).
-
Target MiniBracketed.indent() target can go to “first” and “last” indent change. It also can go not only to line with smaller indent, but also bigger or different one.
Mappings from ‘mini.indentscope’ have more flexibility in computation of indent scope, like how to treat empty lines near border or whether to compute indent at cursor.
Disabling
To disable, set vim.g.minibracketed_disable
(globally) or vim.b.minibracketed_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.
setup()
MiniBracketed.setup
({config})
Module setup
Parameters
{config} (table|nil)
Module config table. See MiniBracketed.config.
Usage
require('mini.bracketed').setup() -- use default config
-- OR
require('mini.bracketed').setup({}) -- replace {} with your config table
config
MiniBracketed.config
Defaults
MiniBracketed.config = {
-- First-level elements are tables describing behavior of a target:
--
-- - <suffix> - single character suffix. Used after `[` / `]` in mappings.
-- For example, with `b` creates `[B`, `[b`, `]b`, `]B` mappings.
-- Supply empty string `''` to not create mappings.
--
-- - <options> - table overriding target options.
--
-- See `:h MiniBracketed.config` for more info.
buffer = { suffix = 'b', options = {} },
comment = { suffix = 'c', options = {} },
conflict = { suffix = 'x', options = {} },
diagnostic = { suffix = 'd', options = {} },
file = { suffix = 'f', options = {} },
indent = { suffix = 'i', options = {} },
jump = { suffix = 'j', options = {} },
location = { suffix = 'l', options = {} },
oldfile = { suffix = 'o', options = {} },
quickfix = { suffix = 'q', options = {} },
treesitter = { suffix = 't', options = {} },
undo = { suffix = 'u', options = {} },
window = { suffix = 'w', options = {} },
yank = { suffix = 'y', options = {} },
}
Options
Each entry configures target with the same name and can have data configuring mapping suffix and target options.
Example of configuration:
require('mini.bracketed').setup({
-- Map [N, [n, ]n, ]N for conflict marker like in 'tpope/vim-unimpaired'
conflict = { suffix = 'n' },
-- Make diagnostic advance only by errors
diagnostic = { options = { severity = vim.diagnostic.severity.ERROR } },
-- Disable creation of mappings for `indent` target (for example,
-- in favor of ones from |mini.indentscope|)
indent = { suffix = '' },
-- Disable mappings for `window` target in favor of custom ones
window = { suffix = '' },
})
-- Create custom `window` mappings
local map = vim.keymap.set
('n', '<Leader>wH', "<Cmd>lua MiniBracketed.window('first')<CR>")
map('n', '<Leader>wh', "<Cmd>lua MiniBracketed.window('backward')<CR>")
map('n', '<Leader>wl', "<Cmd>lua MiniBracketed.window('forward')<CR>")
map('n', '<Leader>wL', "<Cmd>lua MiniBracketed.window('last')<CR>") map
Suffix
The suffix
key is used to create target mappings.
Supply empty string to disable mapping creation for that particular target. To create a completely different mapping (like with <Leader>) use target function manually.
Using lower-suffix
and upper-suffix
(lower and upper case suffix) for a single target the following mappings are created:
[
+upper-suffix
: go first.[
+lower-suffix
: go backward.]
+lower-suffix
: go forward.]
+upper-suffix
: go last.
When supplied with a non-letter, only forward/backward mappings are created.
Options
The options
key is directly forwarded as opts
to corresponding Lua function.
buffer()
MiniBracketed.buffer
({direction}, {opts})
Listed buffer
Go to next/previous listed buffer. Order by their number (see bufnr()).
Direction “forward” increases number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
comment()
MiniBracketed.comment
({direction}, {opts})
Comment block
Go to next/previous comment block. Only linewise comments using ‘commentsring’ are recognized.
Direction “forward” increases line number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.<add_to_jumplist> (
boolean
) - Whether to add current position to jumplist. Default:false
.<block_side>
(string)
- which side of comment block to use. One of “near” (default; use nearest side), “start” (use first line), “end” (use last line), “both” (use both first and last lines).
conflict()
MiniBracketed.conflict
({direction}, {opts})
Git conflict marker
Go to next/previous lines containing Git conflict marker. That is, if it starts with “<<<<<<<”, “>>>>>>>”, or is “=======”.
Direction “forward” increases line number, “backward” - decreases.
Notes:
Using this target in Operator-pending mode allows the following approach at resolving merge conflicts:
Place cursor on
=======
line.Execute one of these:
d]x[xdd
(choose upper part) ord[x]xdd
(choose lower part).
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.<add_to_jumplist> (
boolean
) - Whether to add current position to jumplist. Default:false
.
diagnostic()
MiniBracketed.diagnostic
({direction}, {opts})
Diagnostic
Go to next/previous diagnostic. This is mostly similar to built-in vim.diagnostic.jump() (on Neovim<0.11 it is vim.diagnostic.goto_next() and vim.diagnostic.goto_prev()) which has an interface and behavior consistent with other methods of the module.
Direction “forward” increases line number, “backward” - decreases.
Notes:
Using
severity
option, this target can be used in mappings like “go to next/previous error” (), etc. Using code similar to this:local severity_error = vim.diagnostic.severity.ERROR -- Use these inside custom mappings MiniBracketed.diagnostic('forward', { severity = severity_error }) MiniBracketed.diagnostic('backward', { severity = severity_error })
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.<float>
(boolean|table)
- control floating window after movement. For available values see vim.diagnostic.goto_next().<severity>
(string|table)
- which severity to use. For available values see diagnostic-severity.
file()
MiniBracketed.file
({direction}, {opts})
File on disk
Go to next/previous file on disk alphabetically. Files are taken from directory of file in current buffer (or current working directory if buffer doesn’t contain a readable file). Only first-level files are used, i.e. it doesn’t go inside subdirectories.
Direction “forward” goes forward alphabetically, “backward” - backward.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
indent()
MiniBracketed.indent
({direction}, {opts})
Indent change
Go to next/previous line with different indent (see indent()). Can be used to go to lines with smaller, bigger, or different indent.
Notes:
Directions “first” and “last” work differently from most other targets for performance reasons. They are essentially “backward” and “forward” with very big
n_times
option.For similar reasons,
wrap
is not supported.Blank line inherit indent from near non-blank line in direction of movement.
Direction “forward” increases line number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<add_to_jumplist> (
boolean
) - Whether to add current position to jumplist. Default:false
.<change_type>
(string)
- which type of indent change to use. One of “less” (default; smaller indent), “more” (bigger indent), “diff” (different indent).
jump()
MiniBracketed.jump
({direction}, {opts})
Jump inside current buffer
Go to next/previous jump from jumplist which is inside current buffer.
Notes:
- There are no Visual mode mappings due to implementation problems.
Direction “forward” increases jump number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
location()
MiniBracketed.location
({direction}, {opts})
Location from location list
Go to next/previous location from location-list. This is similar to :lfirst, :lprevious, :lnext, and :llast but with support of wrapping around edges and [count] for “first”/“last” direction.
Direction “forward” increases location number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
oldfile()
MiniBracketed.oldfile
({direction}, {opts})
Old files from previous and current sessions
Go to older/newer readable file either from previous session (see v:oldfiles) or the current one (updated automatically after MiniBracketed.setup() call).
Direction “forward” goes to more recent files, “backward” - to older.
Notes:
In current session it tracks only normal buffers (see ‘buftype’) for some readable file.
No new file is tracked when advancing this target. Only after buffer change is done not through this target (like with MiniBracketed.buffer()), it updates recency of last advanced and new buffers.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
quickfix()
MiniBracketed.quickfix
({direction}, {opts})
Quickfix from quickfix list
Go to next/previous entry from quickfix list. This is similar to :cfirst, :cprevious, :cnext, and :clast but with support of wrapping around edges and [count] for “first”/“last” direction.
Direction “forward” increases location number, “backward” - decreases.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
treesitter()
MiniBracketed.treesitter
({direction}, {opts})
Tree-sitter node
Go to end/start of current tree-sitter node and its parents (except root).
Notes:
Requires loaded tree-sitter parser in the current buffer.
Directions “first” and “last” work differently from most other targets for performance reasons. They are essentially “backward” and “forward” with very big
n_times
option.For similar reasons,
wrap
is not supported.
Direction “forward” moves cursor forward to node’s end, “backward” - backward to node’s start.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<add_to_jumplist> (
boolean
) - Whether to add current position to jumplist. Default:false
.
undo()
MiniBracketed.undo
({direction}, {opts})
Undo along a tracked linear history
In a nutshell:
Keys u and CTRL-R (although remapped) can be used as usual, but every their execution new state is recorded in this module’s linear undo history.
Advancing this target goes along linear undo history revealing undo states in order they actually appeared.
One big difference with built-in methods is that tracked linear history can repeat undo states (not consecutively, though).
Neovim’s default way of managing undo history is through branches (see undo-branches). Basically it means that if you undo several changes and then make new ones, it creates new undo branch while usually (see ‘undolevels’) saving previous buffer states in another branch. While there are commands to navigate by time of undo state creation (like :earlier and :later), there is no intuitive way to cycle through them. Existing g- and g+ cycle through undo states based on their creation time, which often gets confusing really guickly in extensively edited buffer.
This undo()
target provides a way to cycle through linear undo history in order states actually appeared. It does so by registering any new undo states plus every time MiniBracketed.register_undo_state() is called. To have more “out of the box” experience, u and CTRL-R are remapped to call it after they perform their undo/redo.
Example:
To show more clearly the difference between advancing this target and using built-in functionality, here is an example:
Create undo history in a new buffer (:new):
Enter
one two three
text.Delete first word with
daw
and undo the change withu
.Delete second word with
daw
and undo the change withu
.Delete third word with
daw
and undo the change withu
.
Now try one of the following (each one after performing previous steps in separate new buffer):
Press
u
. It goes back to empty buffer. Press<C-R>
twice and it goes to the latest change (one two
). No way to get to other states (liketwo three
orone three
) with these two keys.Press
g-
. It goes to an empty buffer. Pressg+
4 times. It cycles through all available undo states in order they were created.Finally, press
[u
. It goes back toone two
- state which was previously visited by the user. Another[u
restoresone two three
. Use]U
to go to latest visited undo state.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
register_undo_state()
MiniBracketed.register_undo_state
()
Register state for undo target
Use this function to add current undo state to this module’s linear undo history. It is used in MiniBracketed.setup() to remap u and CTRL-R keys to add their new state to linear undo history.
window()
MiniBracketed.window
({direction}, {opts})
Normal window
Go to next/previous normal window. Order by their number (see winnr()).
Direction “forward” increases window number, “backward” - decreases.
Only normal (non-floating) windows are used.
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.
yank()
MiniBracketed.yank
({direction}, {opts})
Replace “latest put region” with yank history entry
After MiniBracketed.setup() is called, on every yank/delete/change operation (technically, every trigger of TextYankPost event) the object of operation is added to yank history. Advancing this target will replace the region of latest put operation with entry from yank history.
By default works best if called right after text paste (like with p or P).
To better detect “latest put region”, use MiniBracketed.register_put_region() as described later.
Direction “forward” goes to newer yank history entry, “backward” - to older.
Example:
Type
one two three
.Yank each word with
yiw
.Create new line and press
p
. This should pastethree
.Type
[y
. This should replace latestthree
withtwo
.
Latest put region
“Latest put region” is (in order of decreasing priority):
The one from latest advance of this target.
The one registered by user with MiniBracketed.register_put_region().
The one taken from [‘ and [’]](https://neovim.io/doc/user/helptag.html?tag=’]) marks.
For users there are these approaches to manage which region will be used:
Do nothing. In this case region between
[
/]
marks will always be used for firstyank
advance. Although doable, this has several drawbacks: it will use latest yanked or changed region or the entire buffer if marks are not set. If remember to advance this target only after recent put operation, this should work as expected.Remap common put operations to use MiniBracketed.register_put_region(). After that, only regions from mapped put operations will be used for first advance. Example of custom mappings (note use of :map-expression):
local put_keys = { 'p', 'P' } for _, lhs in ipairs(put_keys) do local rhs = 'v:lua.MiniBracketed.register_put_region("' .. lhs .. '")' vim.keymap.set({ 'n', 'x' }, lhs, rhs, { expr = true }) end
Parameters
{direction} (string)
One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options. A table with fields:
<n_times>
(number)
- Number of times to advance. Default: v:count1.<wrap>
(boolean)
- Whether to wrap around edges. Default:true
.<operators>
(table)
- array of operator names (“c”, “d”, or “y”) for which yank entry should be used to advance. For example, use{ "y" }
to advance only by entries actually resulted from yank operation with y. Default:{ 'c', 'd', 'y' }
.
register_put_region()
MiniBracketed.register_put_region
({put_key})
Register “latest put region”
This function should be called after put register becomes relevant (v:register is appropriately set) but before put operation takes place ([‘ and [’]](https://neovim.io/doc/user/helptag.html?tag=’]) marks become relevant).
Designed to be used in a user-facing expression mapping (see :map-expression). For mapping examples see MiniBracketed.yank().
Parameters
{put_key} (string)
Put keys to be remapped.
Return
(string)
Returns put_key
for a better usage inside expression mappings.
advance()
MiniBracketed.advance
({iterator}, {direction}, {opts})
Advance iterator
This is the main function which performs any forward/backward/first/last advance in this module. Its basic idea is to take iterator (object containing information about current state and how to go to next/previous one) and go in certain direction until needed/allowed.
Notes:
Directions “first” and “last” are convenience wrappers for “forward” and “backward” with pre-setting initial state to
start_edge
andend_edge
.Iterators
next()
andprev()
methods should be able to handlenil
as input.This function only returns new state and doesn’t modify
iterator.state
.
Parameters
{iterator} (table)
Table:
Methods:
<next> - given state, return state in forward direction (no wrap).
<prev> - given state, return state in backward direction (no wrap).
Fields:
<state> - object describing current state.
<start_edge> (optional) - object with
forward(start_edge)
describing first state. Ifnil
, can’t wrap forward or use direction “first”.<end_edge> (optional) - object with
backward(end_edge)
describing last state. Ifnil
, can’t wrap backward or use direction “last”.
{direction} (string)
Direction. One of “first”, “backward”, “forward”, “last”.
{opts} (table|nil)
Options with the following keys:
<n_times>
(number)
- number of times to go in input direction. Default:v:count1
.<wrap>
(boolean)
- whether to wrap around edges whennext()
orprev()
returnnil
. Default:true
.
Return
(any)
Result state. If nil
, could not reach any valid result state.