-
Notifications
You must be signed in to change notification settings - Fork 180
/
mini-fuzzy.txt
160 lines (128 loc) · 6.38 KB
/
mini-fuzzy.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
*mini.fuzzy* Fuzzy matching
*MiniFuzzy*
MIT License Copyright (c) 2021 Evgeni Chasnovski
==============================================================================
Features:
- Minimal and fast fuzzy matching algorithm which prioritizes match width.
- Functions to for common fuzzy matching operations:
- |MiniFuzzy.match()|.
- |MiniFuzzy.filtersort()|.
- |MiniFuzzy.process_lsp_items()|.
- Generator of |telescope.nvim| sorter: |MiniFuzzy.get_telescope_sorter()|.
# Setup ~
This module doesn't need setup, but it can be done to improve usability.
Setup with `require('mini.fuzzy').setup({})` (replace `{}` with your
`config` table). It will create global Lua table `MiniFuzzy` which you can
use for scripting or manually (with `:lua MiniFuzzy.*`).
See |MiniFuzzy.config| for `config` structure and default values.
You can override runtime config settings locally to buffer inside
`vim.b.minifuzzy_config` which should have same structure as
`MiniFuzzy.config`.
See |mini.nvim-buffer-local-config| for more details.
# Notes ~
1. Currently there is no explicit design to work with multibyte symbols,
but simple examples should work.
2. Smart case is used: case insensitive if input word (which is usually a
user input) is all lower case. Case sensitive otherwise.
------------------------------------------------------------------------------
*MiniFuzzy-algorithm*
# Algorithm design ~
General design uses only width of found match and index of first letter
match. No special characters or positions (like in fzy and fzf) are used.
Given input `word` and target `candidate`:
- The goal is to find matching between `word`'s letters and letters in
`candidate`, which minimizes certain score. It is assumed that order of
letters in `word` and those matched in `candidate` should be the same.
- Matching is represented by matched positions: an array `positions` of
integers with length equal to number of letters in `word`. The following
should be always true in case of a match: `candidate`'s letter at index
`positions[i]` is letters[i]` for all valid `i`.
- Matched positions are evaluated based only on two features: their width
(number of indexes between first and last positions) and first match
(index of first letter match). There is a global setting `cutoff` for
which all feature values greater than it can be considered "equally bad".
- Score of matched positions is computed with following explicit formula:
`cutoff * min(width, cutoff) + min(first, cutoff)`. It is designed to be
equivalent to first comparing widths (lower is better) and then comparing
first match (lower is better). For example, if `word = 'time'`:
- '_time' (width 4) will have a better match than 't_ime' (width 5).
- 'time_a' (width 4, first 1) will have a better match than 'a_time'
(width 4, first 3).
- Final matched positions are those which minimize score among all possible
matched positions of `word` and `candidate`.
------------------------------------------------------------------------------
*MiniFuzzy.setup()*
`MiniFuzzy.setup`({config})
Module setup
Parameters ~
{config} `(table|nil)` Module config table. See |MiniFuzzy.config|.
Usage ~
>lua
require('mini.fuzzy').setup() -- use default config
-- OR
require('mini.fuzzy').setup({}) -- replace {} with your config table
<
------------------------------------------------------------------------------
*MiniFuzzy.config*
`MiniFuzzy.config`
Module config
Default values:
>lua
MiniFuzzy.config = {
-- Maximum allowed value of match features (width and first match). All
-- feature values greater than cutoff can be considered "equally bad".
cutoff = 100,
}
<
------------------------------------------------------------------------------
*MiniFuzzy.match()*
`MiniFuzzy.match`({word}, {candidate})
Compute match data of input `word` and `candidate` strings
It tries to find best match for input string `word` (usually user input)
and string `candidate`. Returns table with elements:
- `positions` - array with letter indexes inside `candidate` which
matched to corresponding letters in `word`. Or `nil` if no match.
- `score` - positive number representing how good the match is (lower is
better). Or `-1` if no match.
Parameters ~
{word} `(string)` Input word (usually user input).
{candidate} `(string)` Target word (usually with which matching is done).
Return ~
`(table)` Table with matching information (see function's description).
------------------------------------------------------------------------------
*MiniFuzzy.filtersort()*
`MiniFuzzy.filtersort`({word}, {candidate_array})
Filter string array
This leaves only those elements of input array which matched with `word`
and sorts from best to worst matches (based on score and index in original
array, both lower is better).
Parameters ~
{word} `(string)` String which will be searched.
{candidate_array} `(table)` Lua array of strings inside which word will be
searched.
Return ~
`(...)` Arrays of matched candidates and their indexes in original input.
------------------------------------------------------------------------------
*MiniFuzzy.process_lsp_items()*
`MiniFuzzy.process_lsp_items`({items}, {base})
Fuzzy matching for `lsp_completion.process_items` of |MiniCompletion.config|
Parameters ~
{items} `(table)` Array with LSP 'textDocument/completion' response items.
{base} `(string)` Word to complete.
------------------------------------------------------------------------------
*MiniFuzzy.get_telescope_sorter()*
`MiniFuzzy.get_telescope_sorter`({opts})
Custom getter for `telescope.nvim` sorter
Designed to be used as value for |telescope.defaults.file_sorter| and
|telescope.defaults.generic_sorter| inside `setup()` call.
Parameters ~
{opts} `(table|nil)` Options (currently not used).
Usage ~
>lua
require('telescope').setup({
defaults = {
generic_sorter = require('mini.fuzzy').get_telescope_sorter
}
})
<
vim:tw=78:ts=8:noet:ft=help:norl: