retrovim 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.conda/retrovim.yaml +259 -0
- package/.conda/terax.icns +0 -0
- package/.conda/terax.ico +0 -0
- package/.conda/terax.png +0 -0
- package/.github/workflows/release.yml +95 -0
- package/.gitmodules +3 -0
- package/.npm/kanata_touchcursor.js +28 -0
- package/.npm/nvim.js +26 -0
- package/.npm/yazi.js +26 -0
- package/.npm/zsh.js +17 -0
- package/.pip/kanata_touchcursor/__init__.py +28 -0
- package/.pip/nvim/__init__.py +31 -0
- package/.pip/yazi/__init__.py +31 -0
- package/.pip/zsh/__init__.py +22 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +674 -0
- package/README.md +336 -0
- package/kanata/touchcursor.kbd +164 -0
- package/nvim/init.lua +813 -0
- package/nvim/plugins/mini.nvim/.github/DISCUSSION_TEMPLATE/q-a.yml +72 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/bug-report.yml +136 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/feature-request.yml +75 -0
- package/nvim/plugins/mini.nvim/.github/PULL_REQUEST_TEMPLATE.md +2 -0
- package/nvim/plugins/mini.nvim/.github/workflows/quality-control.yml +150 -0
- package/nvim/plugins/mini.nvim/.pre-commit-config.yaml +20 -0
- package/nvim/plugins/mini.nvim/.stylua.toml +7 -0
- package/nvim/plugins/mini.nvim/.styluaignore +1 -0
- package/nvim/plugins/mini.nvim/CHANGELOG.md +1894 -0
- package/nvim/plugins/mini.nvim/CODE_OF_CONDUCT.md +132 -0
- package/nvim/plugins/mini.nvim/CONTRIBUTING.md +331 -0
- package/nvim/plugins/mini.nvim/LICENSE +21 -0
- package/nvim/plugins/mini.nvim/MAINTAINING.md +330 -0
- package/nvim/plugins/mini.nvim/Makefile +51 -0
- package/nvim/plugins/mini.nvim/README.md +261 -0
- package/nvim/plugins/mini.nvim/TESTING.md +1011 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/README.md +35 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/benchmark.sh +56 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-alpha.lua +21 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-original.lua +17 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-starter.lua +18 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_empty.lua +4 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_starter-default.lua +7 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-alpha.lua +10 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-original.lua +7 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-starter.lua +20 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/install.sh +10 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/make_summary.py +68 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/startup-summary.md +10 -0
- package/nvim/plugins/mini.nvim/colors/miniautumn.lua +55 -0
- package/nvim/plugins/mini.nvim/colors/minicyan.lua +95 -0
- package/nvim/plugins/mini.nvim/colors/minischeme.lua +95 -0
- package/nvim/plugins/mini.nvim/colors/minispring.lua +53 -0
- package/nvim/plugins/mini.nvim/colors/minisummer.lua +49 -0
- package/nvim/plugins/mini.nvim/colors/miniwinter.lua +51 -0
- package/nvim/plugins/mini.nvim/colors/randomhue.lua +16 -0
- package/nvim/plugins/mini.nvim/doc/mini-ai.txt +889 -0
- package/nvim/plugins/mini.nvim/doc/mini-align.txt +923 -0
- package/nvim/plugins/mini.nvim/doc/mini-animate.txt +937 -0
- package/nvim/plugins/mini.nvim/doc/mini-base16.txt +285 -0
- package/nvim/plugins/mini.nvim/doc/mini-basics.txt +359 -0
- package/nvim/plugins/mini.nvim/doc/mini-bracketed.txt +622 -0
- package/nvim/plugins/mini.nvim/doc/mini-bufremove.txt +123 -0
- package/nvim/plugins/mini.nvim/doc/mini-clue.txt +760 -0
- package/nvim/plugins/mini.nvim/doc/mini-cmdline.txt +392 -0
- package/nvim/plugins/mini.nvim/doc/mini-colors.txt +880 -0
- package/nvim/plugins/mini.nvim/doc/mini-comment.txt +230 -0
- package/nvim/plugins/mini.nvim/doc/mini-completion.txt +477 -0
- package/nvim/plugins/mini.nvim/doc/mini-cursorword.txt +105 -0
- package/nvim/plugins/mini.nvim/doc/mini-deps.txt +590 -0
- package/nvim/plugins/mini.nvim/doc/mini-diff.txt +661 -0
- package/nvim/plugins/mini.nvim/doc/mini-doc.txt +434 -0
- package/nvim/plugins/mini.nvim/doc/mini-extra.txt +856 -0
- package/nvim/plugins/mini.nvim/doc/mini-files.txt +1018 -0
- package/nvim/plugins/mini.nvim/doc/mini-fuzzy.txt +160 -0
- package/nvim/plugins/mini.nvim/doc/mini-git.txt +425 -0
- package/nvim/plugins/mini.nvim/doc/mini-hipatterns.txt +489 -0
- package/nvim/plugins/mini.nvim/doc/mini-hues.txt +420 -0
- package/nvim/plugins/mini.nvim/doc/mini-icons.txt +508 -0
- package/nvim/plugins/mini.nvim/doc/mini-indentscope.txt +485 -0
- package/nvim/plugins/mini.nvim/doc/mini-input.txt +932 -0
- package/nvim/plugins/mini.nvim/doc/mini-jump.txt +202 -0
- package/nvim/plugins/mini.nvim/doc/mini-jump2d.txt +525 -0
- package/nvim/plugins/mini.nvim/doc/mini-keymap.txt +449 -0
- package/nvim/plugins/mini.nvim/doc/mini-map.txt +717 -0
- package/nvim/plugins/mini.nvim/doc/mini-misc.txt +431 -0
- package/nvim/plugins/mini.nvim/doc/mini-move.txt +181 -0
- package/nvim/plugins/mini.nvim/doc/mini-notify.txt +434 -0
- package/nvim/plugins/mini.nvim/doc/mini-nvim.txt +431 -0
- package/nvim/plugins/mini.nvim/doc/mini-operators.txt +472 -0
- package/nvim/plugins/mini.nvim/doc/mini-pairs.txt +346 -0
- package/nvim/plugins/mini.nvim/doc/mini-pick.txt +1535 -0
- package/nvim/plugins/mini.nvim/doc/mini-sessions.txt +239 -0
- package/nvim/plugins/mini.nvim/doc/mini-snippets.txt +1291 -0
- package/nvim/plugins/mini.nvim/doc/mini-splitjoin.txt +536 -0
- package/nvim/plugins/mini.nvim/doc/mini-starter.txt +618 -0
- package/nvim/plugins/mini.nvim/doc/mini-statusline.txt +361 -0
- package/nvim/plugins/mini.nvim/doc/mini-surround.txt +863 -0
- package/nvim/plugins/mini.nvim/doc/mini-tabline.txt +151 -0
- package/nvim/plugins/mini.nvim/doc/mini-test.txt +966 -0
- package/nvim/plugins/mini.nvim/doc/mini-trailspace.txt +91 -0
- package/nvim/plugins/mini.nvim/doc/mini-visits.txt +937 -0
- package/nvim/plugins/mini.nvim/logo.png +0 -0
- package/nvim/plugins/mini.nvim/lua/mini/ai.lua +2244 -0
- package/nvim/plugins/mini.nvim/lua/mini/align.lua +2076 -0
- package/nvim/plugins/mini.nvim/lua/mini/animate.lua +2127 -0
- package/nvim/plugins/mini.nvim/lua/mini/base16.lua +1752 -0
- package/nvim/plugins/mini.nvim/lua/mini/basics.lua +772 -0
- package/nvim/plugins/mini.nvim/lua/mini/bracketed.lua +2013 -0
- package/nvim/plugins/mini.nvim/lua/mini/bufremove.lua +283 -0
- package/nvim/plugins/mini.nvim/lua/mini/clue.lua +2096 -0
- package/nvim/plugins/mini.nvim/lua/mini/cmdline.lua +1182 -0
- package/nvim/plugins/mini.nvim/lua/mini/colors.lua +2483 -0
- package/nvim/plugins/mini.nvim/lua/mini/comment.lua +586 -0
- package/nvim/plugins/mini.nvim/lua/mini/completion.lua +2094 -0
- package/nvim/plugins/mini.nvim/lua/mini/cursorword.lua +311 -0
- package/nvim/plugins/mini.nvim/lua/mini/deps.lua +1660 -0
- package/nvim/plugins/mini.nvim/lua/mini/diff.lua +1938 -0
- package/nvim/plugins/mini.nvim/lua/mini/doc.lua +1371 -0
- package/nvim/plugins/mini.nvim/lua/mini/extra.lua +2290 -0
- package/nvim/plugins/mini.nvim/lua/mini/files.lua +3145 -0
- package/nvim/plugins/mini.nvim/lua/mini/fuzzy.lua +356 -0
- package/nvim/plugins/mini.nvim/lua/mini/git.lua +1737 -0
- package/nvim/plugins/mini.nvim/lua/mini/hipatterns.lua +1042 -0
- package/nvim/plugins/mini.nvim/lua/mini/hues.lua +2088 -0
- package/nvim/plugins/mini.nvim/lua/mini/icons.lua +2254 -0
- package/nvim/plugins/mini.nvim/lua/mini/indentscope.lua +1158 -0
- package/nvim/plugins/mini.nvim/lua/mini/init.lua +427 -0
- package/nvim/plugins/mini.nvim/lua/mini/input.lua +2183 -0
- package/nvim/plugins/mini.nvim/lua/mini/jump.lua +609 -0
- package/nvim/plugins/mini.nvim/lua/mini/jump2d.lua +1244 -0
- package/nvim/plugins/mini.nvim/lua/mini/keymap.lua +880 -0
- package/nvim/plugins/mini.nvim/lua/mini/map.lua +1709 -0
- package/nvim/plugins/mini.nvim/lua/mini/misc.lua +969 -0
- package/nvim/plugins/mini.nvim/lua/mini/move.lua +509 -0
- package/nvim/plugins/mini.nvim/lua/mini/notify.lua +938 -0
- package/nvim/plugins/mini.nvim/lua/mini/operators.lua +1349 -0
- package/nvim/plugins/mini.nvim/lua/mini/pairs.lua +657 -0
- package/nvim/plugins/mini.nvim/lua/mini/pick.lua +3876 -0
- package/nvim/plugins/mini.nvim/lua/mini/sessions.lua +689 -0
- package/nvim/plugins/mini.nvim/lua/mini/snippets.lua +2828 -0
- package/nvim/plugins/mini.nvim/lua/mini/splitjoin.lua +1132 -0
- package/nvim/plugins/mini.nvim/lua/mini/starter.lua +1599 -0
- package/nvim/plugins/mini.nvim/lua/mini/statusline.lua +686 -0
- package/nvim/plugins/mini.nvim/lua/mini/surround.lua +2388 -0
- package/nvim/plugins/mini.nvim/lua/mini/tabline.lua +564 -0
- package/nvim/plugins/mini.nvim/lua/mini/test.lua +2516 -0
- package/nvim/plugins/mini.nvim/lua/mini/trailspace.lua +215 -0
- package/nvim/plugins/mini.nvim/lua/mini/visits.lua +1577 -0
- package/nvim/plugins/mini.nvim/readmes/mini-ai.md +190 -0
- package/nvim/plugins/mini.nvim/readmes/mini-align.md +203 -0
- package/nvim/plugins/mini.nvim/readmes/mini-animate.md +214 -0
- package/nvim/plugins/mini.nvim/readmes/mini-base16.md +198 -0
- package/nvim/plugins/mini.nvim/readmes/mini-basics.md +184 -0
- package/nvim/plugins/mini.nvim/readmes/mini-bracketed.md +193 -0
- package/nvim/plugins/mini.nvim/readmes/mini-bufremove.md +139 -0
- package/nvim/plugins/mini.nvim/readmes/mini-clue.md +260 -0
- package/nvim/plugins/mini.nvim/readmes/mini-cmdline.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-colors.md +169 -0
- package/nvim/plugins/mini.nvim/readmes/mini-comment.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-completion.md +217 -0
- package/nvim/plugins/mini.nvim/readmes/mini-cursorword.md +137 -0
- package/nvim/plugins/mini.nvim/readmes/mini-deps.md +271 -0
- package/nvim/plugins/mini.nvim/readmes/mini-diff.md +289 -0
- package/nvim/plugins/mini.nvim/readmes/mini-doc.md +198 -0
- package/nvim/plugins/mini.nvim/readmes/mini-extra.md +158 -0
- package/nvim/plugins/mini.nvim/readmes/mini-files.md +247 -0
- package/nvim/plugins/mini.nvim/readmes/mini-fuzzy.md +134 -0
- package/nvim/plugins/mini.nvim/readmes/mini-git.md +168 -0
- package/nvim/plugins/mini.nvim/readmes/mini-hipatterns.md +176 -0
- package/nvim/plugins/mini.nvim/readmes/mini-hues.md +285 -0
- package/nvim/plugins/mini.nvim/readmes/mini-icons.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-indentscope.md +191 -0
- package/nvim/plugins/mini.nvim/readmes/mini-input.md +163 -0
- package/nvim/plugins/mini.nvim/readmes/mini-jump.md +161 -0
- package/nvim/plugins/mini.nvim/readmes/mini-jump2d.md +197 -0
- package/nvim/plugins/mini.nvim/readmes/mini-keymap.md +205 -0
- package/nvim/plugins/mini.nvim/readmes/mini-map.md +191 -0
- package/nvim/plugins/mini.nvim/readmes/mini-misc.md +145 -0
- package/nvim/plugins/mini.nvim/readmes/mini-move.md +163 -0
- package/nvim/plugins/mini.nvim/readmes/mini-notify.md +175 -0
- package/nvim/plugins/mini.nvim/readmes/mini-operators.md +193 -0
- package/nvim/plugins/mini.nvim/readmes/mini-pairs.md +158 -0
- package/nvim/plugins/mini.nvim/readmes/mini-pick.md +340 -0
- package/nvim/plugins/mini.nvim/readmes/mini-sessions.md +164 -0
- package/nvim/plugins/mini.nvim/readmes/mini-snippets.md +373 -0
- package/nvim/plugins/mini.nvim/readmes/mini-splitjoin.md +194 -0
- package/nvim/plugins/mini.nvim/readmes/mini-starter.md +176 -0
- package/nvim/plugins/mini.nvim/readmes/mini-statusline.md +155 -0
- package/nvim/plugins/mini.nvim/readmes/mini-surround.md +190 -0
- package/nvim/plugins/mini.nvim/readmes/mini-tabline.md +156 -0
- package/nvim/plugins/mini.nvim/readmes/mini-test.md +175 -0
- package/nvim/plugins/mini.nvim/readmes/mini-trailspace.md +137 -0
- package/nvim/plugins/mini.nvim/readmes/mini-visits.md +243 -0
- package/nvim/plugins/mini.nvim/scripts/dual_log.sh +13 -0
- package/nvim/plugins/mini.nvim/scripts/dual_push.sh +15 -0
- package/nvim/plugins/mini.nvim/scripts/dual_release.sh +102 -0
- package/nvim/plugins/mini.nvim/scripts/dual_sync.sh +115 -0
- package/nvim/plugins/mini.nvim/scripts/init-deps-example.lua +59 -0
- package/nvim/plugins/mini.nvim/scripts/lint-filename-length.sh +16 -0
- package/nvim/plugins/mini.nvim/scripts/lintcommit-ci.sh +18 -0
- package/nvim/plugins/mini.nvim/scripts/lintcommit.lua +393 -0
- package/nvim/plugins/mini.nvim/scripts/minidoc.lua +57 -0
- package/nvim/plugins/mini.nvim/scripts/minimal_init.lua +28 -0
- package/nvim/plugins/mini.nvim/scripts/minitest.lua +4 -0
- package/package.json +16 -0
- package/pyproject.toml +43 -0
- package/yazi/init.lua +12 -0
- package/yazi/keymap.toml +114 -0
- package/yazi/lesskey +5 -0
- package/yazi/plugins/bookmarks.yazi/main.lua +86 -0
- package/yazi/plugins/cd-git-root.yazi/main.lua +31 -0
- package/yazi/plugins/smart-enter.yazi/main.lua +11 -0
- package/yazi/theme.toml +26 -0
- package/yazi/yazi.toml +15 -0
- package/zsh/.zshrc +145 -0
- package/zsh/starship.toml +20 -0
- package/zsh/zsh-patina.toml +2 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
--- *mini.fuzzy* Fuzzy matching
|
|
2
|
+
---
|
|
3
|
+
--- MIT License Copyright (c) 2021 Evgeni Chasnovski
|
|
4
|
+
|
|
5
|
+
--- Features:
|
|
6
|
+
--- - Minimal and fast fuzzy matching algorithm which prioritizes match width.
|
|
7
|
+
---
|
|
8
|
+
--- - Functions to for common fuzzy matching operations:
|
|
9
|
+
--- - |MiniFuzzy.match()|.
|
|
10
|
+
--- - |MiniFuzzy.filtersort()|.
|
|
11
|
+
--- - |MiniFuzzy.process_lsp_items()|.
|
|
12
|
+
---
|
|
13
|
+
--- - Generator of sorter (|MiniFuzzy.get_telescope_sorter()|) for
|
|
14
|
+
--- [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
|
|
15
|
+
---
|
|
16
|
+
--- # Setup ~
|
|
17
|
+
---
|
|
18
|
+
--- This module doesn't need setup, but it can be done to improve usability.
|
|
19
|
+
--- Setup with `require('mini.fuzzy').setup({})` (replace `{}` with your
|
|
20
|
+
--- `config` table). It will create global Lua table `MiniFuzzy` which you can
|
|
21
|
+
--- use for scripting or manually (with `:lua MiniFuzzy.*`).
|
|
22
|
+
---
|
|
23
|
+
--- See |MiniFuzzy.config| for `config` structure and default values.
|
|
24
|
+
---
|
|
25
|
+
--- You can override runtime config settings locally to buffer inside
|
|
26
|
+
--- `vim.b.minifuzzy_config` which should have same structure as
|
|
27
|
+
--- `MiniFuzzy.config`.
|
|
28
|
+
--- See |mini.nvim-buffer-local-config| for more details.
|
|
29
|
+
---
|
|
30
|
+
--- # Notes ~
|
|
31
|
+
---
|
|
32
|
+
--- 1. Currently there is no explicit design to work with multibyte symbols,
|
|
33
|
+
--- but simple examples should work.
|
|
34
|
+
--- 2. Smart case is used: case insensitive if input word (which is usually a
|
|
35
|
+
--- user input) is all lower case. Case sensitive otherwise.
|
|
36
|
+
---@tag MiniFuzzy
|
|
37
|
+
|
|
38
|
+
--- General design uses only width of found match and index of first letter
|
|
39
|
+
--- match. No special characters or positions (like in fzy and fzf) are used.
|
|
40
|
+
---
|
|
41
|
+
--- Given non-empty input `word` and target `candidate`:
|
|
42
|
+
--- - The goal is to find matching between letters in `word` and letters in
|
|
43
|
+
--- `candidate` which minimizes certain score. It is assumed that order of
|
|
44
|
+
--- letters in `word` and those matched in `candidate` should be the same.
|
|
45
|
+
---
|
|
46
|
+
--- - Matching is represented by matched positions: an array `positions` of
|
|
47
|
+
--- integers with length equal to number of letters in `word`. The following
|
|
48
|
+
--- should be always true in case of a match: `candidate` letter at index
|
|
49
|
+
--- `positions[i]` is `letters[i]` for all valid `i`.
|
|
50
|
+
---
|
|
51
|
+
--- - Matched positions are evaluated based only on two features: their width
|
|
52
|
+
--- (number of indexes between first and last positions) and first match
|
|
53
|
+
--- (index of first letter match). There is a global setting `cutoff` for
|
|
54
|
+
--- which all feature values greater than it can be considered "equally bad".
|
|
55
|
+
---
|
|
56
|
+
--- - Score of matched positions is computed with following explicit formula:
|
|
57
|
+
--- `cutoff * min(width, cutoff) + min(first, cutoff)`. It is designed to be
|
|
58
|
+
--- equivalent to first comparing widths (lower is better) and then comparing
|
|
59
|
+
--- first match (lower is better). For example, if `word = 'time'`:
|
|
60
|
+
--- - `_time` (width 4) will have a better match than `t_ime` (width 5).
|
|
61
|
+
--- - `time_a` (width 4, first 1) will have a better match than `a_time`
|
|
62
|
+
--- (width 4, first 3).
|
|
63
|
+
---
|
|
64
|
+
--- - Final matched positions are those which minimize score among all possible
|
|
65
|
+
--- matched positions of `word` and `candidate`.
|
|
66
|
+
---@tag MiniFuzzy-algorithm
|
|
67
|
+
|
|
68
|
+
-- Module definition ==========================================================
|
|
69
|
+
local MiniFuzzy = {}
|
|
70
|
+
local H = {}
|
|
71
|
+
|
|
72
|
+
--- Module setup
|
|
73
|
+
---
|
|
74
|
+
---@param config table|nil Module config table. See |MiniFuzzy.config|.
|
|
75
|
+
---
|
|
76
|
+
---@usage >lua
|
|
77
|
+
--- require('mini.fuzzy').setup() -- use default config
|
|
78
|
+
--- -- OR
|
|
79
|
+
--- require('mini.fuzzy').setup({}) -- replace {} with your config table
|
|
80
|
+
--- <
|
|
81
|
+
MiniFuzzy.setup = function(config)
|
|
82
|
+
-- TODO: Remove after Neovim=0.9 support is dropped
|
|
83
|
+
if vim.fn.has('nvim-0.10') == 0 then
|
|
84
|
+
vim.notify(
|
|
85
|
+
'(mini.fuzzy) Neovim<0.10 is soft deprecated (module works but is not supported).'
|
|
86
|
+
.. " It will be deprecated after the next 'mini.nvim' release (module might not work)."
|
|
87
|
+
.. ' Please update your Neovim version.'
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
-- Export module
|
|
92
|
+
_G.MiniFuzzy = MiniFuzzy
|
|
93
|
+
|
|
94
|
+
-- Setup config
|
|
95
|
+
config = H.setup_config(config)
|
|
96
|
+
|
|
97
|
+
-- Apply config
|
|
98
|
+
H.apply_config(config)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
--- Defaults ~
|
|
102
|
+
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
|
|
103
|
+
MiniFuzzy.config = {
|
|
104
|
+
-- Maximum allowed value of match features (width and first match). All
|
|
105
|
+
-- feature values greater than cutoff can be considered "equally bad".
|
|
106
|
+
cutoff = 100,
|
|
107
|
+
}
|
|
108
|
+
--minidoc_afterlines_end
|
|
109
|
+
|
|
110
|
+
-- Module functionality =======================================================
|
|
111
|
+
--- Compute match data
|
|
112
|
+
---
|
|
113
|
+
---@param word string Input word (usually user input).
|
|
114
|
+
---@param candidate string Target word (usually with which matching is done).
|
|
115
|
+
---
|
|
116
|
+
---@return table Matching information:
|
|
117
|
+
--- - <positions> `(table|nil)` - array with letter indexes inside `candidate`
|
|
118
|
+
--- which matched to corresponding letters in `word`. It is empty array if
|
|
119
|
+
--- `word` is empty string and `nil` if no match.
|
|
120
|
+
--- - <score> `number` - positive number representing how good the match is
|
|
121
|
+
--- (lower is better). It is `-1` if no match or word is empty string.
|
|
122
|
+
MiniFuzzy.match = function(word, candidate)
|
|
123
|
+
-- Use 'smart case'
|
|
124
|
+
candidate = word == word:lower() and candidate:lower() or candidate
|
|
125
|
+
local positions = H.find_best_positions(H.string_to_letters(word), candidate)
|
|
126
|
+
return { positions = positions, score = H.score_positions(positions) }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
--- Filter string array
|
|
130
|
+
---
|
|
131
|
+
--- - Keep only input elements which match `word`.
|
|
132
|
+
--- - Sort from best to worst matches (based on score and index in original
|
|
133
|
+
--- array, both lower is better).
|
|
134
|
+
---
|
|
135
|
+
---@param word string String which will be searched.
|
|
136
|
+
---@param candidate_array table Lua array of strings inside which word will be
|
|
137
|
+
--- searched.
|
|
138
|
+
---
|
|
139
|
+
---@return ... Arrays of matched candidates and their indexes in original input.
|
|
140
|
+
MiniFuzzy.filtersort = function(word, candidate_array)
|
|
141
|
+
-- Use 'smart case'. Create new array to preserve input for later filtering
|
|
142
|
+
local cand_array = word == word:lower() and vim.tbl_map(string.lower, candidate_array) or candidate_array
|
|
143
|
+
local filter_ids = H.make_filter_indexes(word, cand_array)
|
|
144
|
+
table.sort(filter_ids, H.compare_filter_indexes)
|
|
145
|
+
|
|
146
|
+
return H.filter_by_indexes(candidate_array, filter_ids)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
--- Fuzzy matching for `lsp_completion.process_items` of |MiniCompletion.config|
|
|
150
|
+
---
|
|
151
|
+
---@param items table Array with LSP `'textDocument/completion'` response items.
|
|
152
|
+
---@param base string Word to complete.
|
|
153
|
+
---
|
|
154
|
+
---@return table Array of items with text (`filterText` or `label`) fuzzy matching `base`.
|
|
155
|
+
MiniFuzzy.process_lsp_items = function(items, base)
|
|
156
|
+
local words = vim.tbl_map(function(x) return x.filterText or x.label end, items)
|
|
157
|
+
local _, match_inds = MiniFuzzy.filtersort(base, words)
|
|
158
|
+
return vim.tbl_map(function(i) return items[i] end, match_inds)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
--- Custom getter for `telescope.nvim` sorter
|
|
162
|
+
---
|
|
163
|
+
--- Designed as a value for file and generic sorter of `telescope.nvim`.
|
|
164
|
+
---
|
|
165
|
+
---@param opts table|nil Options (currently not used).
|
|
166
|
+
---
|
|
167
|
+
---@usage >lua
|
|
168
|
+
--- require('telescope').setup({
|
|
169
|
+
--- defaults = {
|
|
170
|
+
--- generic_sorter = require('mini.fuzzy').get_telescope_sorter
|
|
171
|
+
--- }
|
|
172
|
+
--- })
|
|
173
|
+
--- <
|
|
174
|
+
MiniFuzzy.get_telescope_sorter = function(opts)
|
|
175
|
+
opts = opts or {}
|
|
176
|
+
|
|
177
|
+
return require('telescope.sorters').Sorter:new({
|
|
178
|
+
start = function(self, prompt)
|
|
179
|
+
-- Cache prompt's letters
|
|
180
|
+
self.letters = H.string_to_letters(prompt)
|
|
181
|
+
|
|
182
|
+
-- Use 'smart case': insensitive if `prompt` is lowercase
|
|
183
|
+
self.case_sensitive = prompt ~= prompt:lower()
|
|
184
|
+
end,
|
|
185
|
+
|
|
186
|
+
-- @param self
|
|
187
|
+
-- @param prompt (which is the text on the line)
|
|
188
|
+
-- @param line (entry.ordinal)
|
|
189
|
+
-- @param entry (the whole entry)
|
|
190
|
+
scoring_function = function(self, _, line, _)
|
|
191
|
+
if #self.letters == 0 then return 1 end
|
|
192
|
+
line = self.case_sensitive and line or line:lower()
|
|
193
|
+
local positions = H.find_best_positions(self.letters, line)
|
|
194
|
+
return H.score_positions(positions)
|
|
195
|
+
end,
|
|
196
|
+
|
|
197
|
+
-- Currently there doesn't seem to be a proper way to cache matched
|
|
198
|
+
-- positions from inside of `scoring_function` (see `highlighter` code of
|
|
199
|
+
-- `get_fzy_sorter`'s output). Besides, it seems that `display` and `line`
|
|
200
|
+
-- arguments might be different. So, extra calls to `match` are made.
|
|
201
|
+
highlighter = function(self, _, display)
|
|
202
|
+
if #self.letters == 0 or #display == 0 then return {} end
|
|
203
|
+
display = self.case_sensitive and display or display:lower()
|
|
204
|
+
return H.find_best_positions(self.letters, display)
|
|
205
|
+
end,
|
|
206
|
+
})
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
-- Helper data ================================================================
|
|
210
|
+
-- Module default config
|
|
211
|
+
H.default_config = vim.deepcopy(MiniFuzzy.config)
|
|
212
|
+
|
|
213
|
+
-- Helper functionality =======================================================
|
|
214
|
+
-- Settings -------------------------------------------------------------------
|
|
215
|
+
H.setup_config = function(config)
|
|
216
|
+
H.check_type('config', config, 'table', true)
|
|
217
|
+
config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {})
|
|
218
|
+
|
|
219
|
+
if not (type(config.cutoff) == 'number' and config.cutoff >= 1) then
|
|
220
|
+
H.error('`cutoff` should be number not less than 1, not ' .. type(config.cutoff))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
return config
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
H.apply_config = function(config) MiniFuzzy.config = config end
|
|
227
|
+
|
|
228
|
+
H.is_disabled = function() return vim.g.minifuzzy_disable == true or vim.b.minifuzzy_disable == true end
|
|
229
|
+
|
|
230
|
+
H.get_config = function(config)
|
|
231
|
+
return vim.tbl_deep_extend('force', MiniFuzzy.config, vim.b.minifuzzy_config or {}, config or {})
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
-- Fuzzy matching -------------------------------------------------------------
|
|
235
|
+
---@param letters table Array of letters from input word
|
|
236
|
+
---@param candidate string String of interest
|
|
237
|
+
---
|
|
238
|
+
---@return table|nil Table with matched positions (in `candidate`) if there is a
|
|
239
|
+
--- match, `nil` otherwise.
|
|
240
|
+
---@private
|
|
241
|
+
H.find_best_positions = function(letters, candidate)
|
|
242
|
+
local n_candidate, n_letters = #candidate, #letters
|
|
243
|
+
if n_letters == 0 then return {} end
|
|
244
|
+
if n_candidate < n_letters then return nil end
|
|
245
|
+
|
|
246
|
+
-- Search forward to find matching positions with left-most last letter match
|
|
247
|
+
local pos_last = 0
|
|
248
|
+
for let_i = 1, #letters do
|
|
249
|
+
pos_last = candidate:find(letters[let_i], pos_last + 1)
|
|
250
|
+
if not pos_last then break end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
-- Candidate is matched only if word's last letter is found
|
|
254
|
+
if not pos_last then return nil end
|
|
255
|
+
|
|
256
|
+
-- If there is only one letter, it is already the best match (there will not
|
|
257
|
+
-- be better width and it has lowest first match)
|
|
258
|
+
if n_letters == 1 then return { pos_last } end
|
|
259
|
+
|
|
260
|
+
-- Compute best match positions by iteratively checking all possible last
|
|
261
|
+
-- letter matches (at and after initial one). At end of each iteration
|
|
262
|
+
-- `best_pos_last` holds best match for last letter among all previously
|
|
263
|
+
-- checked such matches.
|
|
264
|
+
local best_pos_last, best_width = pos_last, math.huge
|
|
265
|
+
local rev_candidate = candidate:reverse()
|
|
266
|
+
|
|
267
|
+
local cutoff = H.get_config().cutoff
|
|
268
|
+
while pos_last do
|
|
269
|
+
-- Simulate computing best match positions ending exactly at `pos_last` by
|
|
270
|
+
-- going backwards from current last letter match. This works because it
|
|
271
|
+
-- minimizes width which is the only way to find match with lower score.
|
|
272
|
+
-- Not actually creating table with positions and then directly computing
|
|
273
|
+
-- score increases speed by up to 40% (on small frequent input word with
|
|
274
|
+
-- relatively wide candidate, such as file paths of nested directories).
|
|
275
|
+
local rev_first = n_candidate - pos_last + 1
|
|
276
|
+
for i = #letters - 1, 1, -1 do
|
|
277
|
+
rev_first = rev_candidate:find(letters[i], rev_first + 1)
|
|
278
|
+
end
|
|
279
|
+
local first = n_candidate - rev_first + 1
|
|
280
|
+
local width = math.min(pos_last - first + 1, cutoff)
|
|
281
|
+
|
|
282
|
+
-- Using strict sign is crucial because when two last letter matches result
|
|
283
|
+
-- into positions with similar width, the one which was created earlier
|
|
284
|
+
-- (i.e. with smaller last letter match) will have smaller first letter
|
|
285
|
+
-- match (hence better score).
|
|
286
|
+
if width < best_width then
|
|
287
|
+
best_pos_last, best_width = pos_last, width
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
-- Advance iteration
|
|
291
|
+
pos_last = candidate:find(letters[n_letters], pos_last + 1)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
-- Actually compute best matched positions from best last letter match
|
|
295
|
+
local best_positions = { best_pos_last }
|
|
296
|
+
local rev_pos = n_candidate - best_pos_last + 1
|
|
297
|
+
for i = #letters - 1, 1, -1 do
|
|
298
|
+
rev_pos = rev_candidate:find(letters[i], rev_pos + 1)
|
|
299
|
+
-- For relatively small number of letters (around 10, which is main use
|
|
300
|
+
-- case) inserting to front seems to have better performance than
|
|
301
|
+
-- inserting at end and then reversing.
|
|
302
|
+
table.insert(best_positions, 1, n_candidate - rev_pos + 1)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
return best_positions
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
-- Compute score of matched positions. Smaller values indicate better match
|
|
309
|
+
-- (i.e. like distance). Reasoning behind the score is for it to produce the
|
|
310
|
+
-- same ordering as with sequential comparison of match's width and first
|
|
311
|
+
-- position. So it shouldn't really be perceived as linear distance (difference
|
|
312
|
+
-- between scores don't really matter, only their comparison with each other).
|
|
313
|
+
--
|
|
314
|
+
-- Reasoning behind comparison logic (based on 'time' input):
|
|
315
|
+
-- - '_time' is better than 't_ime' (width is smaller).
|
|
316
|
+
-- - 'time_aa' is better than 'aa_time' (same width, first match is smaller).
|
|
317
|
+
--
|
|
318
|
+
-- Returns -1 if `positions` is `nil` or empty.
|
|
319
|
+
H.score_positions = function(positions)
|
|
320
|
+
if positions == nil or #positions == 0 then return -1 end
|
|
321
|
+
local first, last = positions[1], positions[#positions]
|
|
322
|
+
local cutoff = H.get_config().cutoff
|
|
323
|
+
return cutoff * math.min(last - first + 1, cutoff) + math.min(first, cutoff)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
H.make_filter_indexes = function(word, candidate_array)
|
|
327
|
+
local res, letters = {}, H.string_to_letters(word)
|
|
328
|
+
for i, cand in ipairs(candidate_array) do
|
|
329
|
+
local positions = H.find_best_positions(letters, cand)
|
|
330
|
+
if positions ~= nil then table.insert(res, { index = i, score = H.score_positions(positions) }) end
|
|
331
|
+
end
|
|
332
|
+
return res
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
H.compare_filter_indexes = function(a, b) return a.score < b.score or (a.score == b.score and a.index < b.index) end
|
|
336
|
+
|
|
337
|
+
H.filter_by_indexes = function(candidate_array, ids)
|
|
338
|
+
local res, res_ids = {}, {}
|
|
339
|
+
for _, id in pairs(ids) do
|
|
340
|
+
table.insert(res, candidate_array[id.index])
|
|
341
|
+
table.insert(res_ids, id.index)
|
|
342
|
+
end
|
|
343
|
+
return res, res_ids
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
-- Utilities ------------------------------------------------------------------
|
|
347
|
+
H.error = function(msg) error('(mini.fuzzy) ' .. msg, 0) end
|
|
348
|
+
|
|
349
|
+
H.check_type = function(name, val, ref, allow_nil)
|
|
350
|
+
if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
|
|
351
|
+
H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
H.string_to_letters = function(s) return vim.tbl_map(vim.pesc, vim.split(s, '')) end
|
|
355
|
+
|
|
356
|
+
return MiniFuzzy
|