487 lines
20 KiB
Plaintext
487 lines
20 KiB
Plaintext
*mini.hipatterns* Highlight patterns in text
|
|
*MiniHipatterns*
|
|
|
|
MIT License Copyright (c) 2023 Evgeni Chasnovski
|
|
|
|
==============================================================================
|
|
|
|
Features:
|
|
- Highlight text with configurable patterns and highlight groups (can be
|
|
string or callable).
|
|
|
|
- Highlighting is updated asynchronously with configurable debounce delay.
|
|
|
|
- Function to get matches in a buffer (see |MiniHipatterns.get_matches()|).
|
|
|
|
See |MiniHipatterns-examples| for common configuration examples.
|
|
|
|
Notes:
|
|
- It does not define any highlighters by default. Add to `config.highlighters`
|
|
to have a visible effect.
|
|
|
|
- Sometimes (especially during frequent buffer updates on same line numbers)
|
|
highlighting can be outdated or not applied when it should be. This is due
|
|
to asynchronous nature of updates reacting to text changes (via
|
|
`on_lines` of |nvim_buf_attach()|).
|
|
To make them up to date, use one of the following:
|
|
- Scroll window (for example, with |CTRL-E| / |CTRL-Y|). This will ensure
|
|
up to date highlighting inside window view.
|
|
- Hide and show buffer.
|
|
- Execute `:edit` (if you enabled highlighting with |MiniHipatterns.setup()|).
|
|
- Manually call |MiniHipatterns.update()|.
|
|
|
|
- If you experience flicker when typing near highlighted pattern in Insert
|
|
mode, it might be due to `delay` configuration of 'mini.completion' or
|
|
using built-in completion.
|
|
For better experience with 'mini.completion', make sure that its
|
|
`delay.completion` is less than this module's `delay.text_change` (which
|
|
it is by default).
|
|
The reason for this is (currently unresolvable) limitations of Neovim's
|
|
built-in completion implementation.
|
|
|
|
# Setup ~
|
|
|
|
Setting up highlights can be done in two ways:
|
|
- Manually for every buffer with `require('mini.hipatterns').enable()`.
|
|
This will enable highlighting only in one particular buffer until it is
|
|
unloaded (which also includes calling `:edit` on current file).
|
|
|
|
- Globally with `require('mini.hipatterns').setup({})` (replace `{}` with
|
|
your `config` table). This will auto-enable highlighting in "normal"
|
|
buffers (see 'buftype'). Use |MiniHipatterns.enable()| to manually enable
|
|
in other buffers.
|
|
It will also create global Lua table `MiniHipatterns` which you can use
|
|
for scripting or manually (with `:lua MiniHipatterns.*`).
|
|
|
|
See |MiniHipatterns.config| for `config` structure and default values.
|
|
|
|
You can override runtime config settings (like highlighters and delays)
|
|
locally to buffer inside `vim.b.minihipatterns_config` which should have
|
|
same structure as `MiniHipatterns.config`.
|
|
See |mini.nvim-buffer-local-config| for more details.
|
|
|
|
# Comparisons ~
|
|
|
|
- 'folke/todo-comments':
|
|
- Oriented for "TODO", "NOTE", "FIXME" like patterns, while this module
|
|
can work with any Lua patterns and computable highlight groups.
|
|
- Has functionality beyond text highlighting (sign placing,
|
|
"telescope.nvim" extension, etc.), while this module only focuses on
|
|
highlighting text.
|
|
- 'folke/paint.nvim':
|
|
- Mostly similar to this module, but with slightly less functionality,
|
|
such as computed pattern and highlight group, asynchronous delay, etc.
|
|
- 'NvChad/nvim-colorizer.lua':
|
|
- Oriented for color highlighting, while this module can work with any
|
|
Lua patterns and computable highlight groups.
|
|
- Has more built-in color spaces to highlight, while this module out of
|
|
the box provides only hex color highlighting
|
|
(see |MiniHipatterns.gen_highlighter.hex_color()|). Other types are
|
|
also possible to implement.
|
|
- 'uga-rosa/ccc.nvim':
|
|
- Has more than color highlighting functionality, which is compared to
|
|
this module in the same way as 'NvChad/nvim-colorizer.lua'.
|
|
|
|
# Highlight groups ~
|
|
|
|
* `MiniHipatternsFixme` - suggested group to use for `FIXME`-like patterns.
|
|
* `MiniHipatternsHack` - suggested group to use for `HACK`-like patterns.
|
|
* `MiniHipatternsTodo` - suggested group to use for `TODO`-like patterns.
|
|
* `MiniHipatternsNote` - suggested group to use for `NOTE`-like patterns.
|
|
|
|
To change any highlight group, modify it directly with |:highlight|.
|
|
|
|
# Disabling ~
|
|
|
|
This module can be disabled in three ways:
|
|
- Globally: set `vim.g.minihipatterns_disable` to `true`.
|
|
- Locally for buffer permanently: set `vim.b.minihipatterns_disable` to `true`.
|
|
- Locally for buffer temporarily (until next auto-enabling event if set up
|
|
with |MiniHipatterns.setup()|): call |MiniHipatterns.disable()|.
|
|
|
|
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.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns-examples*
|
|
# Common configuration examples ~
|
|
|
|
- Special words used to convey different level of attention: >lua
|
|
|
|
require('mini.hipatterns').setup({
|
|
highlighters = {
|
|
fixme = { pattern = 'FIXME', group = 'MiniHipatternsFixme' },
|
|
hack = { pattern = 'HACK', group = 'MiniHipatternsHack' },
|
|
todo = { pattern = 'TODO', group = 'MiniHipatternsTodo' },
|
|
note = { pattern = 'NOTE', group = 'MiniHipatternsNote' },
|
|
}
|
|
})
|
|
<
|
|
- To match only when pattern appears as a standalone word, use frontier
|
|
patterns `%f`. For example, instead of `'TODO'` pattern use
|
|
`'%f[%w]()TODO()%f[%W]'`. In this case, for example, 'TODOING' or 'MYTODO'
|
|
won't match, but 'TODO' and 'TODO:' will.
|
|
|
|
- Color hex (like `#rrggbb`) highlighting: >lua
|
|
|
|
local hipatterns = require('mini.hipatterns')
|
|
hipatterns.setup({
|
|
highlighters = {
|
|
hex_color = hipatterns.gen_highlighter.hex_color(),
|
|
}
|
|
})
|
|
<
|
|
You can customize which part of hex color is highlighted by using `style`
|
|
field of input options. See |MiniHipatterns.gen_highlighter.hex_color()|.
|
|
|
|
- Colored words: >lua
|
|
|
|
local words = { red = '#ff0000', green = '#00ff00', blue = '#0000ff' }
|
|
local word_color_group = function(_, match)
|
|
local hex = words[match]
|
|
if hex == nil then return nil end
|
|
return MiniHipatterns.compute_hex_color_group(hex, 'bg')
|
|
end
|
|
|
|
local hipatterns = require('mini.hipatterns')
|
|
hipatterns.setup({
|
|
highlighters = {
|
|
word_color = { pattern = '%S+', group = word_color_group },
|
|
},
|
|
})
|
|
<
|
|
- Trailing whitespace (if don't want to use more specific 'mini.trailspace'): >lua
|
|
|
|
{ pattern = '%f[%s]%s*$', group = 'Error' }
|
|
<
|
|
- Censor certain sensitive information: >lua
|
|
|
|
local censor_extmark_opts = function(_, match, _)
|
|
local mask = string.rep('x', vim.fn.strchars(match))
|
|
return {
|
|
virt_text = { { mask, 'Comment' } }, virt_text_pos = 'overlay',
|
|
priority = 200, right_gravity = false,
|
|
}
|
|
end
|
|
|
|
require('mini.hipatterns').setup({
|
|
highlighters = {
|
|
censor = {
|
|
pattern = 'password: ()%S+()',
|
|
group = '',
|
|
extmark_opts = censor_extmark_opts,
|
|
},
|
|
},
|
|
})
|
|
<
|
|
- Enable only in certain filetypes. There are at least these ways to do it:
|
|
- (Suggested) With `vim.b.minihipatterns_config` in |filetype-plugin|.
|
|
Basically, create "after/ftplugin/<filetype>.lua" file in your config
|
|
directory (see |$XDG_CONFIG_HOME|) and define `vim.b.minihipatterns_config`
|
|
there with filetype specific highlighters.
|
|
|
|
This assumes `require('mini.hipatterns').setup()` call.
|
|
|
|
For example, to highlight keywords in EmmyLua comments in Lua files,
|
|
create "after/ftplugin/lua.lua" with the following content: >lua
|
|
|
|
vim.b.minihipatterns_config = {
|
|
highlighters = {
|
|
emmylua = { pattern = '^%s*%-%-%-()@%w+()', group = 'Special' }
|
|
}
|
|
}
|
|
<
|
|
- Use callable `pattern` with condition. For example: >lua
|
|
|
|
require('mini.hipatterns').setup({
|
|
highlighters = {
|
|
emmylua = {
|
|
pattern = function(buf_id)
|
|
if vim.bo[buf_id].filetype ~= 'lua' then return nil end
|
|
return '^%s*%-%-%-()@%w+()'
|
|
end,
|
|
group = 'Special',
|
|
},
|
|
},
|
|
})
|
|
<
|
|
- Disable only in certain filetypes. Enable with |MiniHipatterns.setup()|
|
|
and set `vim.b.minihipatterns_disable` buffer-local variable to `true` for
|
|
buffer you want disabled. See |mini.nvim-disabling-recipes| for more examples.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.setup()*
|
|
`MiniHipatterns.setup`({config})
|
|
Module setup
|
|
|
|
Parameters ~
|
|
{config} `(table|nil)` Module config table. See |MiniHipatterns.config|.
|
|
|
|
Usage ~
|
|
>lua
|
|
require('mini.hipatterns').setup({}) -- replace {} with your config table
|
|
-- needs `highlighters` field present
|
|
<
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.config*
|
|
`MiniHipatterns.config`
|
|
Module config
|
|
|
|
Default values:
|
|
>lua
|
|
MiniHipatterns.config = {
|
|
-- Table with highlighters (see |MiniHipatterns.config| for more details).
|
|
-- Nothing is defined by default. Add manually for visible effect.
|
|
highlighters = {},
|
|
|
|
-- Delays (in ms) defining asynchronous highlighting process
|
|
delay = {
|
|
-- How much to wait for update after every text change
|
|
text_change = 200,
|
|
|
|
-- How much to wait for update after window scroll
|
|
scroll = 50,
|
|
},
|
|
}
|
|
<
|
|
# Options ~
|
|
|
|
## Highlighters ~
|
|
|
|
`highlighters` table defines which patterns will be highlighted by placing
|
|
|extmark| at the match start. It might or might not have explicitly named
|
|
fields, but having them is recommended and is required for proper use of
|
|
`vim.b.minihipatterns_config` as buffer-local config. By default it is
|
|
empty expecting user definition.
|
|
|
|
Each entry defines single highlighter as a table with the following fields:
|
|
- <pattern> `(string|function|table)` - Lua pattern to highlight. Can be
|
|
either string, callable returning the string, or an array of those.
|
|
If string:
|
|
- It can have submatch delimited by placing `()` on start and end, NOT
|
|
by surrounding with it. Otherwise it will result in error containing
|
|
`number expected, got string`. Example: `xx()abcd()xx` will match `abcd`
|
|
only if `xx` is placed before and after it.
|
|
|
|
If callable:
|
|
- It will be called for every enabled buffer with its identifier as input.
|
|
|
|
- It can return `nil` meaning this particular highlighter will not work
|
|
in this particular buffer.
|
|
|
|
If array:
|
|
- Each element is matched and highlighted with the same highlight group.
|
|
|
|
- <group> `(string|function)` - name of highlight group to use. Can be either
|
|
string or callable returning the string.
|
|
If callable:
|
|
- It will be called for every pattern match with the following arguments:
|
|
- `buf_id` - buffer identifier.
|
|
- `match` - string pattern match to be highlighted.
|
|
- `data` - extra table with information about the match.
|
|
It has at least these fields:
|
|
- <full_match> - string with full pattern match.
|
|
- <line> - match line number (1-indexed).
|
|
- <from_col> - match starting byte column (1-indexed).
|
|
- <to_col> - match ending byte column (1-indexed, inclusive).
|
|
|
|
- It can return `nil` meaning this particular match will not be highlighted.
|
|
|
|
- <extmark_opts> `(table|function|nil)` - optional extra options
|
|
for |nvim_buf_set_extmark()|. If callable, will be called in the same way
|
|
as callable <group> (`data` will also contain `hl_group` key with <group>
|
|
value) and should return a table with all options for extmark (including
|
|
`end_row`, `end_col`, `hl_group`, and `priority`).
|
|
Note: if <extmark_opts> is supplied, <priority> is ignored.
|
|
|
|
- <priority> `(number|nil)` - SOFT DEPRECATED in favor
|
|
of `extmark_opts = { priority = <value> }`.
|
|
Optional highlighting priority (as in |nvim_buf_set_extmark()|).
|
|
Default: 200. See also |vim.highlight.priorities|.
|
|
|
|
See "Common use cases" section for the examples.
|
|
|
|
## Delay ~
|
|
|
|
`delay` is a table defining delays in milliseconds used for asynchronous
|
|
highlighting process.
|
|
|
|
`delay.text_change` is used to delay highlighting updates by accumulating
|
|
them (in debounce fashion). Smaller values will lead to faster response but
|
|
more frequent updates. Bigger - slower response but less frequent updates.
|
|
|
|
`delay.scroll` is used to delay updating highlights in current window view
|
|
during scrolling (see |WinScrolled| event). These updates are present to
|
|
ensure up to date highlighting after scroll.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.enable()*
|
|
`MiniHipatterns.enable`({buf_id}, {config})
|
|
Enable highlighting in buffer
|
|
|
|
Notes:
|
|
- With default config it will highlight nothing, as there are no default
|
|
highlighters.
|
|
|
|
- Buffer highlighting is enabled until buffer is unloaded from memory
|
|
or |MiniHipatterns.disable()| on this buffer is called.
|
|
|
|
- `:edit` disables this, as it is mostly equivalent to closing and opening
|
|
buffer. In order for highlighting to persist after `:edit`, call
|
|
|MiniHipatterns.setup()|.
|
|
|
|
Parameters ~
|
|
{buf_id} `(number|nil)` Buffer identifier in which to enable highlighting.
|
|
Default: 0 for current buffer.
|
|
{config} `(table|nil)` Optional buffer-local config. Should have the same
|
|
structure as |MiniHipatterns.config|. Values will be taken in this order:
|
|
- From this `config` argument (if supplied).
|
|
- From buffer-local config in `vim.b.minihipatterns_config` (if present).
|
|
- From global config (if |MiniHipatterns.setup()| was called).
|
|
- From default values.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.disable()*
|
|
`MiniHipatterns.disable`({buf_id})
|
|
Disable highlighting in buffer
|
|
|
|
Note that if |MiniHipatterns.setup()| was called, the effect is present
|
|
until the next auto-enabling event. To permanently disable highlighting in
|
|
buffer, set `vim.b.minihipatterns_disable` to `true`
|
|
|
|
Parameters ~
|
|
{buf_id} `(number|nil)` Buffer identifier in which to enable highlighting.
|
|
Default: 0 for current buffer.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.toggle()*
|
|
`MiniHipatterns.toggle`({buf_id}, {config})
|
|
Toggle highlighting in buffer
|
|
|
|
Call |MiniHipatterns.disable()| if enabled; |MiniHipatterns.enable()| otherwise.
|
|
|
|
Parameters ~
|
|
{buf_id} `(number|nil)` Buffer identifier in which to enable highlighting.
|
|
Default: 0 for current buffer.
|
|
{config} `(table|nil)` Forwarded to |MiniHipatterns.enable()|.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.update()*
|
|
`MiniHipatterns.update`({buf_id}, {from_line}, {to_line})
|
|
Update highlighting in range
|
|
|
|
Works only in buffer with enabled highlighting. Effect takes immediately
|
|
without delay.
|
|
|
|
Parameters ~
|
|
{buf_id} `(number|nil)` Buffer identifier in which to enable highlighting.
|
|
Default: 0 for current buffer.
|
|
{from_line} `(number|nil)` Start line from which to update (1-indexed).
|
|
{to_line} `(number|nil)` End line from which to update (1-indexed, inclusive).
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.get_enabled_buffers()*
|
|
`MiniHipatterns.get_enabled_buffers`()
|
|
Get an array of enabled buffers
|
|
|
|
Return ~
|
|
`(table)` Array of buffer identifiers with enabled highlighting.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.get_matches()*
|
|
`MiniHipatterns.get_matches`({buf_id}, {highlighters})
|
|
Get buffer matches
|
|
|
|
Parameters ~
|
|
{buf_id} `(number|nil)` Buffer identifier for which to return matches.
|
|
Default: `nil` for current buffer.
|
|
{highlighters} `(table|nil)` Array of highlighter identifiers (as in
|
|
`highlighters` field of |MiniHipatterns.config|) for which to return matches.
|
|
Default: all available highlighters (ordered by string representation).
|
|
|
|
Return ~
|
|
`(table)` Array of buffer matches which are tables with following fields:
|
|
- <bufnr> `(number)` - buffer identifier of a match.
|
|
- <highlighter> `(any)` - highlighter identifier which produced the match.
|
|
- <lnum> `(number)` - line number of the match start (starts with 1).
|
|
- <col> `(number)` - column number of the match start (starts with 1).
|
|
- <end_lnum> `(number|nil)` - line number of the match end (starts with 1).
|
|
- <end_col> `(number|nil)` - column number next to the match end
|
|
(implements end-exclusive region; starts with 1).
|
|
- <hl_group> `(string|nil)` - name of match's highlight group.
|
|
|
|
Matches are ordered first by supplied `highlighters`, then by line and
|
|
column of match start.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.gen_highlighter*
|
|
`MiniHipatterns.gen_highlighter`
|
|
Generate builtin highlighters
|
|
|
|
This is a table with function elements. Call to actually get highlighter.
|
|
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.gen_highlighter.hex_color()*
|
|
`MiniHipatterns.gen_highlighter.hex_color`({opts})
|
|
Highlight hex color string
|
|
|
|
This will match color hex string in format `#rrggbb` and highlight it
|
|
according to `opts.style` displaying matched color.
|
|
|
|
Highlight group is computed using |MiniHipatterns.compute_hex_color_group()|,
|
|
so all its usage notes apply here.
|
|
|
|
Parameters ~
|
|
{opts} `(table|nil)` Options. Possible fields:
|
|
- <style> `(string)` - one of:
|
|
- `'full'` - highlight background of whole hex string with it. Default.
|
|
- `'#'` - highlight background of only `#`.
|
|
- `'line'` - highlight underline with that color.
|
|
- `'inline'` - highlight text of <inline_text>.
|
|
Note: requires Neovim>=0.10.
|
|
- <priority> `(number)` - priority of highlighting. Default: 200.
|
|
- <filter> `(function)` - callable object used to filter buffers in which
|
|
highlighting will take place. It should take buffer identifier as input
|
|
and return `false` or `nil` to not highlight inside this buffer.
|
|
- <inline_text> `(string)` - string to be placed and highlighted with color
|
|
to the right of match in case <style> is "inline". Default: "█".
|
|
|
|
Return ~
|
|
`(table)` Highlighter table ready to be used as part of `config.highlighters`.
|
|
Both `pattern` and `group` are callable.
|
|
|
|
Usage ~
|
|
>lua
|
|
local hipatterns = require('mini.hipatterns')
|
|
hipatterns.setup({
|
|
highlighters = {
|
|
hex_color = hipatterns.gen_highlighter.hex_color(),
|
|
}
|
|
})
|
|
<
|
|
------------------------------------------------------------------------------
|
|
*MiniHipatterns.compute_hex_color_group()*
|
|
`MiniHipatterns.compute_hex_color_group`({hex_color}, {style})
|
|
Compute and create group to highlight hex color string
|
|
|
|
Notes:
|
|
- This works properly only with enabled |termguicolors|.
|
|
|
|
- To increase performance, it caches highlight groups per `hex_color` and
|
|
`style` combination. Needs a call to |MiniHipatterns.setup()| to have
|
|
these groups be persistent across color scheme changes.
|
|
|
|
Parameters ~
|
|
{hex_color} `(string)` Hex color string in format `#rrggbb`.
|
|
{style|nil} `(string)` One of:
|
|
- `'bg'` - highlight background with `hex_color` and foreground with black or
|
|
white (whichever is more visible). Default.
|
|
- `'fg'` - highlight foreground with `hex_color`.
|
|
- `'line'` - highlight underline with `hex_color`.
|
|
|
|
Return ~
|
|
`(string)` Name of created highlight group appropriate to show `hex_color`.
|
|
|
|
|
|
vim:tw=78:ts=8:noet:ft=help:norl: |