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,880 @@
|
|
|
1
|
+
--- *mini.keymap* Special key mappings
|
|
2
|
+
---
|
|
3
|
+
--- MIT License Copyright (c) 2025 Evgeni Chasnovski
|
|
4
|
+
|
|
5
|
+
--- Features:
|
|
6
|
+
---
|
|
7
|
+
--- - Map keys to perform configurable multi-step actions: if condition for step
|
|
8
|
+
--- one is true - execute step one action, else check step two, and so on until
|
|
9
|
+
--- falling back to executing original keys. This is usually referred to as
|
|
10
|
+
--- "smart" keys (like "smart tab"). See |MiniKeymap.map_multistep()|.
|
|
11
|
+
---
|
|
12
|
+
--- There are many built-in steps targeted for Insert mode mappings of special
|
|
13
|
+
--- keys like <Tab>, <S-Tab>, <CR>, and <BS>:
|
|
14
|
+
--- - Navigate and accept |popupmenu-completion|. Useful for |mini.completion|.
|
|
15
|
+
--- - Navigate and expand |mini.snippets|.
|
|
16
|
+
--- - Execute <CR> and <BS> respecting |mini.pairs|.
|
|
17
|
+
--- - Jump before/after current tree-sitter node.
|
|
18
|
+
--- - Jump before opening and after closing characters (brackets and quotes).
|
|
19
|
+
--- - Increase/decrease indent when cursor is inside of it.
|
|
20
|
+
--- - Delete all whitespace to the left ("hungry backspace").
|
|
21
|
+
--- - Navigate |vim.snippet|.
|
|
22
|
+
--- - Navigate and accept in [hrsh7th/nvim-cmp](https://github.com/hrsh7th/nvim-cmp) completion.
|
|
23
|
+
--- - Navigate and accept in [Saghen/blink.cmp](https://github.com/Saghen/blink.cmp) completion.
|
|
24
|
+
--- - Navigate and expand [L3MON4D3/LuaSnip](https://github.com/L3MON4D3/LuaSnip) snippets.
|
|
25
|
+
--- - Execute <CR> and <BS> respecting [windwp/nvim-autopairs](https://github.com/windwp/nvim-autopairs).
|
|
26
|
+
---
|
|
27
|
+
--- - Map keys as "combo": each key acts immediately plus execute extra action if
|
|
28
|
+
--- all are typed within configurable delay between each other.
|
|
29
|
+
--- See |MiniKeymap.map_combo()|. Some of the common use cases include:
|
|
30
|
+
--- - Map insertable keys (like "jk", "kj") in Insert and Command-line mode
|
|
31
|
+
--- to exit into Normal mode.
|
|
32
|
+
--- - Fight against bad habits of pressing the same navigation key by showing
|
|
33
|
+
--- a notification if there are too many of them pressed in a row.
|
|
34
|
+
---
|
|
35
|
+
--- Sources with more details:
|
|
36
|
+
--- - |MiniKeymap-examples|
|
|
37
|
+
---
|
|
38
|
+
--- # Setup ~
|
|
39
|
+
---
|
|
40
|
+
--- This module doesn't need setup, but it can be done to improve usability.
|
|
41
|
+
--- Setup with `require('mini.keymap').setup({})` (replace `{}` with your `config`
|
|
42
|
+
--- table). It will create global Lua table `MiniKeymap` which you can use for
|
|
43
|
+
--- scripting or manually (with `:lua MiniKeymap.*`).
|
|
44
|
+
---
|
|
45
|
+
--- See |MiniKeymap.config| for `config` structure and default values.
|
|
46
|
+
---
|
|
47
|
+
--- This module doesn't have runtime options, so using `vim.b.minikeymap_config`
|
|
48
|
+
--- will have no effect here.
|
|
49
|
+
---
|
|
50
|
+
--- # Comparisons ~
|
|
51
|
+
---
|
|
52
|
+
--- - [max397574/better-escape.nvim](https://github.com/max397574/better-escape.nvim):
|
|
53
|
+
--- - Mostly similar to |MiniKeymap.map_combo()| with a different approach
|
|
54
|
+
--- to creating mappings.
|
|
55
|
+
--- - Mostly targeted for Insert mode mappings as pressed keys get removed
|
|
56
|
+
--- automatically after typed. This module allows more general cases while
|
|
57
|
+
--- requiring explicit removal of keys (usually via explicit `<BS><BS>`).
|
|
58
|
+
---
|
|
59
|
+
--- - [abecodes/tabout.nvim](https://github.com/abecodes/tabout.nvim):
|
|
60
|
+
--- - Similar general idea as in `'jump_{after,before}_tsnode'` steps
|
|
61
|
+
--- of |MiniKeymap.map_multistep()|.
|
|
62
|
+
--- - Works only with enabled tree-sitter parser. This module provides
|
|
63
|
+
--- fallback via `'jump_after_close'` and `'jump_before_open'` that work
|
|
64
|
+
--- without tree-sitter parser.
|
|
65
|
+
--- - `tabout.nvim` has finer control of how the tree-sitter node movement
|
|
66
|
+
--- is done, while this module has "jump outside of current node" behavior.
|
|
67
|
+
---
|
|
68
|
+
--- # Disabling ~
|
|
69
|
+
---
|
|
70
|
+
--- To disable acting in mappings, set `vim.g.minikeymap_disable` (globally) or
|
|
71
|
+
--- `vim.b.minikeymap_disable` (for a buffer) to `true`. Considering high number
|
|
72
|
+
--- of different scenarios and customization intentions, writing exact rules
|
|
73
|
+
--- for disabling module's functionality is left to user.
|
|
74
|
+
--- See |mini.nvim-disabling-recipes| for common recipes.
|
|
75
|
+
---@tag MiniKeymap
|
|
76
|
+
|
|
77
|
+
--- # Multi-step ~
|
|
78
|
+
---
|
|
79
|
+
--- See |MiniKeymap.map_multistep()| for a general description of how multi-step
|
|
80
|
+
--- mappings work and what built-in steps are available.
|
|
81
|
+
---
|
|
82
|
+
--- Setup that works well with |mini.completion| and |mini.pairs|: >lua
|
|
83
|
+
---
|
|
84
|
+
--- local map_multistep = require('mini.keymap').map_multistep
|
|
85
|
+
--- map_multistep('i', '<Tab>', { 'pmenu_next' })
|
|
86
|
+
--- map_multistep('i', '<S-Tab>', { 'pmenu_prev' })
|
|
87
|
+
--- map_multistep('i', '<CR>', { 'pmenu_accept', 'minipairs_cr' })
|
|
88
|
+
--- map_multistep('i', '<BS>', { 'minipairs_bs' })
|
|
89
|
+
--- <
|
|
90
|
+
--- Use <Tab> / <S-Tab> to also navigate and expand |mini.snippets|: >lua
|
|
91
|
+
---
|
|
92
|
+
--- local map_multistep = require('mini.keymap').map_multistep
|
|
93
|
+
---
|
|
94
|
+
--- local tab_steps = { 'minisnippets_next','minisnippets_expand','pmenu_next' }
|
|
95
|
+
--- map_multistep('i', '<Tab>', tab_steps)
|
|
96
|
+
---
|
|
97
|
+
--- local shifttab_steps = { 'minisnippets_prev', 'pmenu_prev' }
|
|
98
|
+
--- map_multistep('i', '<S-Tab>', shifttab_steps)
|
|
99
|
+
--- <
|
|
100
|
+
--- An extra smart <Tab> and <S-Tab>: >lua
|
|
101
|
+
---
|
|
102
|
+
--- local map_multistep = require('mini.keymap').map_multistep
|
|
103
|
+
---
|
|
104
|
+
--- -- NOTE: this will never insert tab, press <C-v><Tab> for that
|
|
105
|
+
--- local tab_steps = {
|
|
106
|
+
--- 'minisnippets_next', 'minisnippets_expand', 'pmenu_next',
|
|
107
|
+
--- 'jump_after_tsnode', 'jump_after_close',
|
|
108
|
+
--- }
|
|
109
|
+
--- map_multistep('i', '<Tab>', tab_steps)
|
|
110
|
+
---
|
|
111
|
+
--- local shifttab_steps = {
|
|
112
|
+
--- 'minisnippets_prev', 'pmenu_prev',
|
|
113
|
+
--- 'jump_before_tsnode', 'jump_before_open',
|
|
114
|
+
--- }
|
|
115
|
+
--- map_multistep('i', '<S-Tab>', shifttab_steps)
|
|
116
|
+
--- <
|
|
117
|
+
--- Navigation in active |vim.snippet| session also requires mapping in |Select-mode|: >lua
|
|
118
|
+
---
|
|
119
|
+
--- local map_multistep = require('mini.keymap').map_multistep
|
|
120
|
+
--- map_multistep({ 'i', 's' }, '<Tab>', { 'vimsnippet_next', 'pmenu_next' })
|
|
121
|
+
--- map_multistep({ 'i', 's' }, '<S-Tab>', { 'vimsnippet_prev', 'pmenu_prev' })
|
|
122
|
+
--- <
|
|
123
|
+
--- # Combos ~
|
|
124
|
+
---
|
|
125
|
+
--- See |MiniKeymap.map_combo()| for a general description of what is a combo and
|
|
126
|
+
--- more caveats about its usage.
|
|
127
|
+
---
|
|
128
|
+
--- All combos require their left hand side keys to be typed relatively quickly.
|
|
129
|
+
--- To adjust the delay between keys, add `{ delay = 500 }` (use custom value) as
|
|
130
|
+
--- fourth argument.
|
|
131
|
+
---
|
|
132
|
+
--- ## "Better escape" to Normal mode ~
|
|
133
|
+
---
|
|
134
|
+
--- Leave into |Normal-mode| without having to reach for <Esc> key: >lua
|
|
135
|
+
---
|
|
136
|
+
--- -- Support most common modes. This can also contain 't', but would
|
|
137
|
+
--- -- only mean to press `<Esc>` inside terminal.
|
|
138
|
+
--- local mode = { 'i', 'c', 'x', 's' }
|
|
139
|
+
--- require('mini.keymap').map_combo(mode, 'jk', '<BS><BS><Esc>')
|
|
140
|
+
---
|
|
141
|
+
--- -- To not have to worry about the order of keys, also map "kj"
|
|
142
|
+
--- require('mini.keymap').map_combo(mode, 'kj', '<BS><BS><Esc>')
|
|
143
|
+
---
|
|
144
|
+
--- -- Escape into Normal mode from Terminal mode
|
|
145
|
+
--- require('mini.keymap').map_combo('t', 'jk', '<BS><BS><C-\\><C-n>')
|
|
146
|
+
--- require('mini.keymap').map_combo('t', 'kj', '<BS><BS><C-\\><C-n>')
|
|
147
|
+
--- <
|
|
148
|
+
--- ## Show bad navigation habits ~
|
|
149
|
+
---
|
|
150
|
+
--- Show notification if there is too much movement by repeating same key: >lua
|
|
151
|
+
---
|
|
152
|
+
--- local notify_many_keys = function(key)
|
|
153
|
+
--- local lhs = string.rep(key, 5)
|
|
154
|
+
--- local action = function() vim.notify('Too many ' .. key) end
|
|
155
|
+
--- require('mini.keymap').map_combo({ 'n', 'x' }, lhs, action)
|
|
156
|
+
--- end
|
|
157
|
+
--- notify_many_keys('h')
|
|
158
|
+
--- notify_many_keys('j')
|
|
159
|
+
--- notify_many_keys('k')
|
|
160
|
+
--- notify_many_keys('l')
|
|
161
|
+
--- <
|
|
162
|
+
--- ## Fix previous spelling mistake ~
|
|
163
|
+
---
|
|
164
|
+
--- Fix previous spelling mistake (see |[s| and |z=|) without manually leaving
|
|
165
|
+
--- Insert mode: >lua
|
|
166
|
+
---
|
|
167
|
+
--- local action = '<BS><BS><Esc>[s1z=gi<Right>'
|
|
168
|
+
--- require('mini.keymap').map_combo('i', 'kk', action)
|
|
169
|
+
--- <
|
|
170
|
+
--- ## Hide search highlighting ~
|
|
171
|
+
---
|
|
172
|
+
--- Use double <Esc><Esc> to execute |:nohlsearch|. Although this can also be done
|
|
173
|
+
--- with `nmap <Esc> <Cmd>nohl<CR>`, the combo approach also exists and can be used
|
|
174
|
+
--- to free <Esc> mapping in Normal mode for something else. >lua
|
|
175
|
+
---
|
|
176
|
+
--- local action = function() vim.cmd('nohlsearch') end
|
|
177
|
+
--- require('mini.keymap').map_combo({ 'n','i','x','c' }, '<Esc><Esc>', action)
|
|
178
|
+
--- <
|
|
179
|
+
--- ## Buffer navigation ~
|
|
180
|
+
---
|
|
181
|
+
--- Replace some movements with easier to type alternatives: >lua
|
|
182
|
+
---
|
|
183
|
+
--- local map_combo = require('mini.keymap').map_combo
|
|
184
|
+
--- map_combo({ 'n', 'x' }, 'll', 'g$')
|
|
185
|
+
--- map_combo({ 'n', 'x' }, 'hh', 'g^')
|
|
186
|
+
--- map_combo({ 'n', 'x' }, 'jj', '}')
|
|
187
|
+
--- map_combo({ 'n', 'x' }, 'kk', '{')
|
|
188
|
+
--- <
|
|
189
|
+
---@tag MiniKeymap-examples
|
|
190
|
+
|
|
191
|
+
---@diagnostic disable:undefined-field
|
|
192
|
+
---@diagnostic disable:discard-returns
|
|
193
|
+
---@diagnostic disable:unused-local
|
|
194
|
+
|
|
195
|
+
-- Module definition ==========================================================
|
|
196
|
+
local MiniKeymap = {}
|
|
197
|
+
local H = {}
|
|
198
|
+
|
|
199
|
+
--- Module setup
|
|
200
|
+
---
|
|
201
|
+
---@param config table|nil Module config table. See |MiniKeymap.config|.
|
|
202
|
+
---
|
|
203
|
+
---@usage >lua
|
|
204
|
+
--- require('mini.keymap').setup({}) -- replace {} with your config table
|
|
205
|
+
--- -- needs `keymap` field present
|
|
206
|
+
--- <
|
|
207
|
+
MiniKeymap.setup = function(config)
|
|
208
|
+
-- TODO: Remove after Neovim=0.9 support is dropped
|
|
209
|
+
if vim.fn.has('nvim-0.10') == 0 then
|
|
210
|
+
vim.notify(
|
|
211
|
+
'(mini.keymap) Neovim<0.10 is soft deprecated (module works but is not supported).'
|
|
212
|
+
.. " It will be deprecated after the next 'mini.nvim' release (module might not work)."
|
|
213
|
+
.. ' Please update your Neovim version.'
|
|
214
|
+
)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
-- Export module
|
|
218
|
+
_G.MiniKeymap = MiniKeymap
|
|
219
|
+
|
|
220
|
+
-- Setup config
|
|
221
|
+
config = H.setup_config(config)
|
|
222
|
+
|
|
223
|
+
-- Apply config
|
|
224
|
+
H.apply_config(config)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
--- Defaults ~
|
|
228
|
+
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
|
|
229
|
+
MiniKeymap.config = {}
|
|
230
|
+
--minidoc_afterlines_end
|
|
231
|
+
|
|
232
|
+
--- Map multi-step action
|
|
233
|
+
---
|
|
234
|
+
--- Mapping of a multi-step action is an expression mapping (|:map-expression|).
|
|
235
|
+
--- Executing a multi-step action is essentially:
|
|
236
|
+
--- - Check condition for step one. If `true` - execute step one action and stop.
|
|
237
|
+
--- - Check condition for step two, and so on.
|
|
238
|
+
--- - If there is no more steps, fall back to returning mapped key.
|
|
239
|
+
---
|
|
240
|
+
--- For better user experience there are many built-in steps mostly designed
|
|
241
|
+
--- to create Insert mode "smart" mappings of <Tab>, <S-Tab>, <CR>, and <BS>.
|
|
242
|
+
--- Available built-in steps ("For key" is a suggestion, any can be used):
|
|
243
|
+
--- >
|
|
244
|
+
--- ┌─────────────────────┬────────────────┬──────────────────────────┬─────────┐
|
|
245
|
+
--- │ Step name │ Condition │ Action │ For key │
|
|
246
|
+
--- ├─────────────────────┴────────────────┴──────────────────────────┴─────────┤
|
|
247
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ |ins-completion-menu| ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
248
|
+
--- │ pmenu_next │ Pmenu visible │ Select next (as <C-n>) │ <Tab> │
|
|
249
|
+
--- │ pmenu_prev │ Pmenu visible │ Select prev (as <C-p>) │ <S-Tab> │
|
|
250
|
+
--- │ pmenu_accept │ Item selected │ Accept (as <C-y>) │ <CR> │
|
|
251
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ |mini.snippets| ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
252
|
+
--- │ minisnippets_next │ Session active │ Jump to next tabstop │ <Tab> │
|
|
253
|
+
--- │ minisnippets_prev │ Session active │ Jump to prev tabstop │ <S-Tab> │
|
|
254
|
+
--- │ minisnippets_expand │ Can expand │ Expand snippet at cursor │ <Tab> │
|
|
255
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ |mini.pairs| ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
256
|
+
--- │ minipairs_cr │ Module set up │ <CR> respecting pairs │ <CR> │
|
|
257
|
+
--- │ minipairs_bs │ Module set up │ <BS> respecting pairs │ <BS> │
|
|
258
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ Jump around in Insert mode ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
259
|
+
--- │ jump_after_tsnode │ TS parser │ Jump after node end │ <Tab> │
|
|
260
|
+
--- │ jump_before_tsnode │ TS parser │ Jump before node start │ <S-Tab> │
|
|
261
|
+
--- │ jump_after_close │ Insert mode │ Jump after )]}"'` │ <Tab> │
|
|
262
|
+
--- │ jump_before_open │ Insert mode │ Jump before ([{"'` │ <S-Tab> │
|
|
263
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ Work with whitespace ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
264
|
+
--- │ increase_indent │ Is on indent │ Increase indent │ <Tab> │
|
|
265
|
+
--- │ decrease_indent │ Is on indent │ Decrease indent │ <S-Tab> │
|
|
266
|
+
--- │ hungry_bs │ Space to left │ Delete all space to left │ <BS> │
|
|
267
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ |vim.snippet| ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
268
|
+
--- │ vimsnippet_next │ Session active │ Jump to next tabstop │ <Tab> │
|
|
269
|
+
--- │ vimsnippet_prev │ Session active │ Jump to prev tabstop │ <S-Tab> │
|
|
270
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 'hrsh7th/nvim-cmp' ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
271
|
+
--- │ cmp_next │ Menu visible │ Select next item │ <Tab> │
|
|
272
|
+
--- │ cmp_prev │ Menu visible │ Select prev item │ <S-Tab> │
|
|
273
|
+
--- │ cmp_accept │ Item selected │ Accept selected item │ <CR> │
|
|
274
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 'Saghen/blink.cmp' ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
275
|
+
--- │ blink_next │ Menu visible │ Select next item │ <Tab> │
|
|
276
|
+
--- │ blink_prev │ Menu visible │ Select prev item │ <S-Tab> │
|
|
277
|
+
--- │ blink_accept │ Item selected │ Accept selected item │ <CR> │
|
|
278
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 'L3MON4D3/LuaSnip' ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
279
|
+
--- │ luasnip_next │ Session active │ Jump to next tabstop │ <Tab> │
|
|
280
|
+
--- │ luasnip_prev │ Session active │ Jump to prev tabstop │ <S-Tab> │
|
|
281
|
+
--- │ luasnip_expand │ Can expand │ Expand snippet at cursor │ <Tab> │
|
|
282
|
+
--- ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 'windwp/nvim-autopairs' ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
|
|
283
|
+
--- │ nvimautopairs_cr │ Module present │ <CR> respecting pairs │ <CR> │
|
|
284
|
+
--- │ nvimautopairs_bs │ Module present │ <BS> respecting pairs │ <BS> │
|
|
285
|
+
--- └─────────────────────┴────────────────┴──────────────────────────┴─────────┘
|
|
286
|
+
--- <
|
|
287
|
+
--- Notes:
|
|
288
|
+
--- - Executing action has limitations of |:map-expression| (like not allowed text
|
|
289
|
+
--- or buffer changes, etc.). To execute complex lua code, use |vim.schedule()|
|
|
290
|
+
--- inside action, return the code as string in |:map-cmd| format, or return
|
|
291
|
+
--- a function to be later executed. See usage examples.
|
|
292
|
+
---
|
|
293
|
+
--- - Some mapped keys (like <Tab>, <CR>) might require disabling smart presets
|
|
294
|
+
--- in plugins (like `nvim-cmp`, `blink-cmp`, `nvim-autopairs`).
|
|
295
|
+
---
|
|
296
|
+
---@param mode string|table Same as for |vim.keymap.set()|.
|
|
297
|
+
---@param lhs string Same as for |vim.keymap.set()|.
|
|
298
|
+
---@param steps table Array of steps. Each step can be a string with the name
|
|
299
|
+
--- of built-in step or a table with two callable methods (will be called
|
|
300
|
+
--- without arguments):
|
|
301
|
+
--- - <condition> - return `true` if the action should be executed.
|
|
302
|
+
--- - <action> - action to be executed if <condition> returns `true`.
|
|
303
|
+
--- For more flexibility, it can also return a value which can be:
|
|
304
|
+
--- - String - will be returned as expression output. Can be something like
|
|
305
|
+
--- `"<Tab>"` (treat as <Tab> key) or `"<Cmd>lua vim.notify('Hello')<CR>"`.
|
|
306
|
+
--- Should not escape keycodes (i.e. return "<Tab>" and not "\t").
|
|
307
|
+
--- To undo already done escape, use |keytrans()|.
|
|
308
|
+
--- - Function - will be executed as if `"<Cmd>lua f()<CR>"`, but does not
|
|
309
|
+
--- need to create a global function for that.
|
|
310
|
+
--- - `false` - do not stop going through steps.
|
|
311
|
+
---@param opts table|nil Same as for |vim.keymap.set()|.
|
|
312
|
+
---
|
|
313
|
+
---@usage See |MiniKeymap-examples| for practical examples.
|
|
314
|
+
---
|
|
315
|
+
--- Some illustrative examples: >lua
|
|
316
|
+
---
|
|
317
|
+
--- _G.log = {}
|
|
318
|
+
--- local steps = {}
|
|
319
|
+
--- steps[1] = {
|
|
320
|
+
--- condition = function() table.insert(_G.log, 'C1'); return _G.cond1 end,
|
|
321
|
+
--- -- Compute and return keys. Will be emulated as pressed.
|
|
322
|
+
--- action = function() table.insert(_G.log, 'A1'); return 'hello' end,
|
|
323
|
+
--- }
|
|
324
|
+
---
|
|
325
|
+
--- steps[2] = {
|
|
326
|
+
--- condition = function() table.insert(_G.log, 'C2'); return _G.cond2 end,
|
|
327
|
+
--- -- Perform action immediately, return `false` to keep asking other steps
|
|
328
|
+
--- action = function() table.insert(_G.log, 'A2'); return false end,
|
|
329
|
+
--- }
|
|
330
|
+
---
|
|
331
|
+
--- steps[3] = {
|
|
332
|
+
--- condition = function() table.insert(_G.log, 'C3'); return _G.cond3 end,
|
|
333
|
+
--- -- Perform action later (to overcom expression mapping limitations)
|
|
334
|
+
--- action = function()
|
|
335
|
+
--- table.insert(_G.log, 'A3_1')
|
|
336
|
+
--- return function() table.insert(_G.log, 'A3_2') end
|
|
337
|
+
--- end,
|
|
338
|
+
--- }
|
|
339
|
+
---
|
|
340
|
+
--- -- Make Insert mode <Tab> mapping
|
|
341
|
+
--- require('mini.keymap').map_multistep('i', '<Tab>', steps)
|
|
342
|
+
---
|
|
343
|
+
--- -- Pressing <Tab> inserts fallback `\t`; logs C1+C2+C3
|
|
344
|
+
--- _G.cond1, _G.cond2, _G.cond3 = false, false, false
|
|
345
|
+
---
|
|
346
|
+
--- -- Pressing <Tab> inserts `hello`; logs C1+A1
|
|
347
|
+
--- _G.cond1, _G.cond2, _G.cond3 = true, false, false
|
|
348
|
+
---
|
|
349
|
+
--- -- Pressing <Tab> inserts nothing; logs C1+C2+A2+C3+A3_1+A3_2
|
|
350
|
+
--- _G.cond1, _G.cond2, _G.cond3 = false, true, true
|
|
351
|
+
--- <
|
|
352
|
+
MiniKeymap.map_multistep = function(mode, lhs, steps, opts)
|
|
353
|
+
H.check_type('lhs', lhs, 'string')
|
|
354
|
+
local lhs_raw, n_steps = vim.api.nvim_replace_termcodes(lhs, true, true, true), #steps
|
|
355
|
+
local lhs_keycode = vim.fn.keytrans(lhs_raw)
|
|
356
|
+
steps = H.normalize_steps(steps)
|
|
357
|
+
|
|
358
|
+
local rhs = function()
|
|
359
|
+
if H.is_disabled() then return lhs_keycode end
|
|
360
|
+
for i = 1, n_steps do
|
|
361
|
+
if steps[i].condition() then
|
|
362
|
+
local out = steps[i].action()
|
|
363
|
+
-- Allow custom string as output of expression mapping
|
|
364
|
+
if type(out) == 'string' then return out end
|
|
365
|
+
-- Allow callable output to be properly wrapped in `<Cmd>...<CR>`
|
|
366
|
+
if vim.is_callable(out) then return H.wrap_in_cmd_lua(out) end
|
|
367
|
+
-- Allow `false` output to indicate "keep processing next steps"
|
|
368
|
+
if out ~= false then return '' end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
return lhs_keycode
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
local desc = 'Multi ' .. lhs_keycode
|
|
375
|
+
opts = vim.tbl_extend('force', { desc = desc }, opts or {}, { expr = true, replace_keycodes = true })
|
|
376
|
+
vim.keymap.set(mode, lhs, rhs, opts)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
--- Generate step for multi-step mappings
|
|
380
|
+
---
|
|
381
|
+
--- This is a table with function elements. Call to actually get a step.
|
|
382
|
+
MiniKeymap.gen_step = {}
|
|
383
|
+
|
|
384
|
+
--- Search pattern step
|
|
385
|
+
---
|
|
386
|
+
--- Use |search()| to jump to pattern match. Possibly adjust final position to
|
|
387
|
+
--- be just to the right of the match (useful in Insert mode).
|
|
388
|
+
---
|
|
389
|
+
---@param pattern string Same as for |search()|.
|
|
390
|
+
---@param flags string|nil Same as for |search()|.
|
|
391
|
+
---@param opts table|nil Options. Possible fields:
|
|
392
|
+
--- - <side> `(string)` - one of `"before"` (default) or `"after"`.
|
|
393
|
+
--- - <stopline> `(number|function)` - forwarded to |search()| (as number or
|
|
394
|
+
--- as function's output after calling it before every search).
|
|
395
|
+
--- - <timeout> `(number)` - forwarded to |search()|.
|
|
396
|
+
--- - <skip> `(string|function)` - forwarded to |search()|.
|
|
397
|
+
---
|
|
398
|
+
---@return table Step which searches pattern.
|
|
399
|
+
---
|
|
400
|
+
---@usage Built-in |MiniKeymap.map_multistep()| steps "jump_after_close" and
|
|
401
|
+
--- "jump_before_open" use this, but only in Insert mode.
|
|
402
|
+
---
|
|
403
|
+
--- Steps that jump before/after all consecutive brackets in several modes: >lua
|
|
404
|
+
---
|
|
405
|
+
--- local keymap = require('mini.keymap')
|
|
406
|
+
--- local tab_step_insert = keymap.gen_step.search_pattern(
|
|
407
|
+
--- -- Need to use 'c' flag and 'after' side for robust "chaining"
|
|
408
|
+
--- [=[[)\]}]\+]=], 'ceW', { side = 'after' }
|
|
409
|
+
--- )
|
|
410
|
+
--- keymap.map_multistep('i', '<Tab>', { tab_step_insert })
|
|
411
|
+
--- local tab_step = keymap.gen_step.search_pattern([=[[)\]}]\+]=], 'eW')
|
|
412
|
+
--- keymap.map_multistep({ 'n', 'x' }, '<Tab>', { tab_step })
|
|
413
|
+
---
|
|
414
|
+
--- local stab_step = keymap.gen_step.search_pattern([=[[(\[{]\+]=], 'bW')
|
|
415
|
+
--- keymap.map_multistep({ 'i', 'n', 'x' }, '<S-Tab>', { stab_step })
|
|
416
|
+
--- <
|
|
417
|
+
MiniKeymap.gen_step.search_pattern = function(pattern, flags, opts)
|
|
418
|
+
if type(pattern) ~= 'string' then H.error('`pattern` should be string, not ' .. vim.inspect(type(pattern))) end
|
|
419
|
+
flags = flags or ''
|
|
420
|
+
if type(flags) ~= 'string' then H.error('`flags` should be string, not ' .. vim.inspect(type(flags))) end
|
|
421
|
+
|
|
422
|
+
opts = vim.tbl_extend('force', { side = 'before', stopline = nil, timeout = nil, skip = nil }, opts or {})
|
|
423
|
+
local side = opts.side
|
|
424
|
+
if not (side == 'before' or side == 'after') then H.error('`opts.side` should be one of "before" or "after"') end
|
|
425
|
+
|
|
426
|
+
local stopline = opts.stopline or function() return nil end
|
|
427
|
+
if type(stopline) == 'number' then
|
|
428
|
+
local line = stopline
|
|
429
|
+
stopline = function() return line end
|
|
430
|
+
end
|
|
431
|
+
if not vim.is_callable(stopline) then H.error('`opts.stopline` should be number or callable') end
|
|
432
|
+
|
|
433
|
+
-- NOTEs:
|
|
434
|
+
-- - Using `normal!` doesn't go past the end of line and triggers
|
|
435
|
+
-- mode-change-related events.
|
|
436
|
+
-- - Adjusting pattern with `\zs` prefix doesn't work for consecutive matches
|
|
437
|
+
-- (like `)))`), as it will match every other one (first, third, etc.).
|
|
438
|
+
-- - Using `\@<=` quantifier doesn't work for the last match in consecutive
|
|
439
|
+
-- matches at end of line. Like `)))` at end of line won't put cursor at
|
|
440
|
+
-- end of line. The `[)\]}]\@<=\_.` also doesn't seem to work.
|
|
441
|
+
local adjust_cursor = function()
|
|
442
|
+
local pos = vim.api.nvim_win_get_cursor(0)
|
|
443
|
+
vim.api.nvim_win_set_cursor(0, { pos[1], pos[2] + 1 })
|
|
444
|
+
end
|
|
445
|
+
if side == 'before' then adjust_cursor = function() end end
|
|
446
|
+
|
|
447
|
+
local act = function()
|
|
448
|
+
H.hide_completion()
|
|
449
|
+
local had_match = vim.fn.search(pattern, flags, stopline(), opts.timeout, opts.skip)
|
|
450
|
+
if had_match ~= 0 then adjust_cursor() end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
return { condition = function() return true end, action = function() return act end }
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
--- Map combo post action
|
|
457
|
+
---
|
|
458
|
+
--- Create a combo: sequence of keys where each acts immediately plus execute
|
|
459
|
+
--- an extra action if all are typed within configurable delay between each other.
|
|
460
|
+
---
|
|
461
|
+
--- Example for Insert mode "better escape" `jk` combo with `<BS><BS><Esc>` action:
|
|
462
|
+
--- - Press `j`. It is visible immediately without any side effects.
|
|
463
|
+
--- - Quickly (no more than default 200 ms after) press `k`. This triggers the
|
|
464
|
+
--- action which is equivalent to typing <BS><BS> (delete already present `jk`)
|
|
465
|
+
--- and <Esc> to exit into Normal mode.
|
|
466
|
+
---
|
|
467
|
+
--- Notes:
|
|
468
|
+
--- - IMPORTANT! Combo is not a regular mapping but a separate key tracking
|
|
469
|
+
--- with |vim.on_key()|. This is important as combos will not be visible and
|
|
470
|
+
--- can not be managed as regular mappings. Instead each combo is associated
|
|
471
|
+
--- with a dedicated |namespace| (named for human readability). However, it is not
|
|
472
|
+
--- really expected to manage them on the fly after they are created.
|
|
473
|
+
---
|
|
474
|
+
--- - String action is executed with |nvim_input()|, i.e. emulated keys will
|
|
475
|
+
--- respect custom mappings.
|
|
476
|
+
---
|
|
477
|
+
--- - Different combos are tracked and act independent of each other. For example,
|
|
478
|
+
--- if there are combos for `jjk` and `jk` keys, fast typing `jjk` will execute both.
|
|
479
|
+
---
|
|
480
|
+
--- - Neovim>=0.11 is recommended due to |vim.on_key()| improvement to allow
|
|
481
|
+
--- watching for keys as they are typed and not as if coming from mappings.
|
|
482
|
+
--- For example, this matters when creating a `jk` combo for Visual mode while
|
|
483
|
+
--- also having `xnoremap j gj` style of remaps. On Neovim<0.11 the fix is to
|
|
484
|
+
--- use `gjgk` as combo's left hand side.
|
|
485
|
+
---
|
|
486
|
+
--- - Each combo adds very small but non-zero overhead on each keystroke.
|
|
487
|
+
--- Usually about 1-3 microseconds (i.e. 0.001-0.003 ms), which should be
|
|
488
|
+
--- fast enough for most setups. For a "normal, real world" coding session
|
|
489
|
+
--- with a total of ~20000 keystrokes it results in extra ~40ms of overhead
|
|
490
|
+
--- for a single created combo. Create many combos with caution.
|
|
491
|
+
---
|
|
492
|
+
---@param mode string|table String or array of string mode id (like "n", "i", etc.).
|
|
493
|
+
--- Array of several modes is more performant than several single mode combos.
|
|
494
|
+
---@param lhs string|table String with tracked key sequence or an array of
|
|
495
|
+
--- tracked keys (one element - one key).
|
|
496
|
+
---@param action string|function Action to perform after key sequence is detected.
|
|
497
|
+
--- If string, treated as keys and emulated with |nvim_input()|.
|
|
498
|
+
--- If function, executed in |vim.schedule()|. Can return string keys which will
|
|
499
|
+
--- be emulated.
|
|
500
|
+
---@param opts table|nil Options. Possible fields:
|
|
501
|
+
--- - <delay> `(number)` - delay in milliseconds within which keys should be
|
|
502
|
+
--- pressed to detect a key sequence. Default: 200.
|
|
503
|
+
---
|
|
504
|
+
---@usage See |MiniKeymap-examples| for practical examples.
|
|
505
|
+
---
|
|
506
|
+
--- Some illustrative examples: >lua
|
|
507
|
+
---
|
|
508
|
+
--- local map_combo = require('mini.keymap').map_combo
|
|
509
|
+
---
|
|
510
|
+
--- -- In Insert mode pressing `x` followed by `x` within 1 second logs 'A'
|
|
511
|
+
--- -- and emulates extra pressing of `yy`
|
|
512
|
+
--- _G.log = {}
|
|
513
|
+
--- local action = function() table.insert(_G.log, 'A'); return 'yy' end
|
|
514
|
+
--- map_combo('i', 'xx', action, { delay = 1000 })
|
|
515
|
+
--- <
|
|
516
|
+
MiniKeymap.map_combo = function(mode, lhs, action, opts)
|
|
517
|
+
if type(mode) == 'string' then mode = { mode } end
|
|
518
|
+
if not H.is_array_of(mode, H.is_string) then H.error('`mode` should be string or array of strings') end
|
|
519
|
+
local mode_tbl = H.combo_make_mode_tbl(mode)
|
|
520
|
+
|
|
521
|
+
local seq = H.combo_lhs_to_seq(lhs)
|
|
522
|
+
seq = vim.tbl_map(function(x) return vim.api.nvim_replace_termcodes(x, true, true, true) end, seq)
|
|
523
|
+
|
|
524
|
+
if not (type(action) == 'string' or vim.is_callable(action)) then
|
|
525
|
+
H.error('`action` should be either string of keys or callable')
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
-- Cache local values for better speed
|
|
529
|
+
opts = opts or {}
|
|
530
|
+
local delay = opts.delay or 200
|
|
531
|
+
if not (type(delay) == 'number' and delay > 0) then H.error('`opts.delay` should be a positive number') end
|
|
532
|
+
|
|
533
|
+
local hrtime, get_key = vim.loop.hrtime, H.combo_get_key
|
|
534
|
+
local i, last_time, n_seq = 0, hrtime(), #seq
|
|
535
|
+
local delay_ns = 1000000 * delay
|
|
536
|
+
-- NOTE: It is possible to track mode in 'ModeChanged' event and use it for
|
|
537
|
+
-- all combos (instead of `get_mode()` for each). Although it scales well
|
|
538
|
+
-- (O(1) instead of O(n) by number of combos), it can fail when something is
|
|
539
|
+
-- executed with 'eventignore' blocking 'ModeChanged' event (can happen with
|
|
540
|
+
-- plugins). Median `get_mode()` execution time is 0.15 microseconds and it
|
|
541
|
+
-- gets executed on every keystroke. If it proves to be too much, can be
|
|
542
|
+
-- reverted to 'ModeChanged' approach.
|
|
543
|
+
local get_mode = vim.fn.mode
|
|
544
|
+
|
|
545
|
+
-- Explicitly ignore keys from action. Otherwise they will be processed
|
|
546
|
+
-- because `nvim_input` mocks "as if typed" approach.
|
|
547
|
+
local input_keys = vim.schedule_wrap(function(keys)
|
|
548
|
+
H.combo_ignore = true
|
|
549
|
+
vim.api.nvim_input(keys)
|
|
550
|
+
-- NOTE: Can't unignore right away because `nvim_input` is executed later
|
|
551
|
+
H.combo_unignore_later()
|
|
552
|
+
end)
|
|
553
|
+
|
|
554
|
+
if type(action) == 'string' then
|
|
555
|
+
local keys = action
|
|
556
|
+
action = function() input_keys(keys) end
|
|
557
|
+
end
|
|
558
|
+
local act = vim.schedule_wrap(function()
|
|
559
|
+
if H.is_disabled() then return end
|
|
560
|
+
-- Allow action to return keys to manually mimic
|
|
561
|
+
local keys = action()
|
|
562
|
+
if type(keys) == 'string' and keys ~= '' then input_keys(keys) end
|
|
563
|
+
end)
|
|
564
|
+
local reset = function(key)
|
|
565
|
+
-- Make latest key start new combo, like for 'jjk' or j-wait-jj for 'jj'
|
|
566
|
+
i = seq[1] == key and 1 or 0
|
|
567
|
+
last_time = i == 0 and last_time or hrtime()
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
local watcher = function(key, typed)
|
|
571
|
+
-- Use only keys "as if typed" and in proper mode
|
|
572
|
+
key = get_key(key, typed)
|
|
573
|
+
if key == '' or (i == 0 and not mode_tbl[get_mode()]) or H.combo_ignore then return end
|
|
574
|
+
|
|
575
|
+
-- Advance tracking and reset if not in sequence
|
|
576
|
+
i = i + 1
|
|
577
|
+
if seq[i] ~= key then return reset(key) end
|
|
578
|
+
|
|
579
|
+
-- Reset if time between key presses is too big
|
|
580
|
+
local cur_time = hrtime()
|
|
581
|
+
if (cur_time - last_time) > delay_ns and i > 1 then return reset(key) end
|
|
582
|
+
last_time = cur_time
|
|
583
|
+
|
|
584
|
+
-- Wait for more info if sequence is not exhausted, act otherwise
|
|
585
|
+
if i < n_seq then return end
|
|
586
|
+
i = 0
|
|
587
|
+
act()
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
local combo_keys = table.concat(vim.tbl_map(vim.fn.keytrans, seq), '')
|
|
591
|
+
local ns_name = string.format('MiniKeymap-combo-%s-%s-%s', #H.ns_id_combo, table.concat(mode, ''), combo_keys)
|
|
592
|
+
local ns_id = vim.api.nvim_create_namespace(ns_name)
|
|
593
|
+
table.insert(H.ns_id_combo, ns_id)
|
|
594
|
+
|
|
595
|
+
return vim.on_key(watcher, ns_id)
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
-- Helper data ================================================================
|
|
599
|
+
-- Module default config
|
|
600
|
+
H.default_config = vim.deepcopy(MiniKeymap.config)
|
|
601
|
+
|
|
602
|
+
-- Namespaces for `on_key`
|
|
603
|
+
H.ns_id_combo = {}
|
|
604
|
+
|
|
605
|
+
-- Current mode used in "combo" mappings, for better speed
|
|
606
|
+
H.cur_mode = 'n'
|
|
607
|
+
|
|
608
|
+
-- Whether to ignore current keys as part of the combo. Needs to be global for
|
|
609
|
+
-- combo's RHS keys not interfering with tracking of other combos.
|
|
610
|
+
H.combo_ignore = false
|
|
611
|
+
|
|
612
|
+
-- Helper functionality =======================================================
|
|
613
|
+
-- Settings -------------------------------------------------------------------
|
|
614
|
+
H.setup_config = function(config)
|
|
615
|
+
H.check_type('config', config, 'table', true)
|
|
616
|
+
config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {})
|
|
617
|
+
return config
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
H.apply_config = function(config) MiniKeymap.config = config end
|
|
621
|
+
|
|
622
|
+
H.is_disabled = function() return vim.g.minikeymap_disable == true or vim.b.minikeymap_disable == true end
|
|
623
|
+
|
|
624
|
+
-- Combo ----------------------------------------------------------------------
|
|
625
|
+
H.combo_lhs_to_seq = function(lhs)
|
|
626
|
+
if H.is_array_of(lhs, H.is_string) then return vim.deepcopy(lhs) end
|
|
627
|
+
if type(lhs) ~= 'string' then H.error('`lhs` should be string or array of strings') end
|
|
628
|
+
|
|
629
|
+
local res, i = {}, 1
|
|
630
|
+
while i <= lhs:len() do
|
|
631
|
+
local k, new_i = string.match(lhs, '^(%b<>)()', i)
|
|
632
|
+
if k == nil or k:find('^.+<') ~= nil then
|
|
633
|
+
k, new_i = vim.fn.strcharpart(lhs, i - 1, 1), i + 1
|
|
634
|
+
end
|
|
635
|
+
table.insert(res, k)
|
|
636
|
+
i = new_i
|
|
637
|
+
end
|
|
638
|
+
return res
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
H.combo_make_mode_tbl = function(mode)
|
|
642
|
+
local res = {}
|
|
643
|
+
for _, m in ipairs(mode) do
|
|
644
|
+
if m == 'x' then
|
|
645
|
+
res.v, res.V, res['\22'] = true, true, true
|
|
646
|
+
elseif m == 'v' then
|
|
647
|
+
res.s, res.v, res.V, res['\22'] = true, true, true, true
|
|
648
|
+
else
|
|
649
|
+
res[m] = true
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
return res
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
H.combo_unignore_later = vim.schedule_wrap(function() H.combo_ignore = false end)
|
|
656
|
+
|
|
657
|
+
H.combo_get_key = function(_, typed) return typed end
|
|
658
|
+
if vim.fn.has('nvim-0.11') == 0 then H.combo_get_key = function(key) return key end end
|
|
659
|
+
|
|
660
|
+
-- Multi-step -----------------------------------------------------------------
|
|
661
|
+
H.normalize_steps = function(steps)
|
|
662
|
+
if not H.islist(steps) then H.error('`steps` should be array') end
|
|
663
|
+
local res = {}
|
|
664
|
+
for i, step in ipairs(steps) do
|
|
665
|
+
local s = type(step) == 'string' and H.steps_builtin[step] or step
|
|
666
|
+
local is_step = type(s) == 'table' and vim.is_callable(s.condition) and vim.is_callable(s.action)
|
|
667
|
+
if not is_step then H.error('`steps` should contain valid steps, not ' .. vim.inspect(step)) end
|
|
668
|
+
table.insert(res, s)
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
return res
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
H.wrap_in_cmd_lua = function(f)
|
|
675
|
+
local needs_global_cleanup = _G.MiniKeymap == nil
|
|
676
|
+
_G.MiniKeymap = _G.MiniKeymap or {}
|
|
677
|
+
_G.MiniKeymap._f = f
|
|
678
|
+
local extra_cleanup = needs_global_cleanup and '; MiniKeymap = nil' or ''
|
|
679
|
+
return '<Cmd>lua MiniKeymap._f(); MiniKeymap._f = nil' .. extra_cleanup .. '<CR>'
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
H.make_cmd_lua_action = function(cmd_string)
|
|
683
|
+
return function() return '<Cmd>lua ' .. cmd_string .. '<CR>' end
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
H.has_module = function(name) return (pcall(require, name)) end
|
|
687
|
+
|
|
688
|
+
--stylua: ignore start
|
|
689
|
+
H.steps_builtin = {}
|
|
690
|
+
|
|
691
|
+
H.is_visible_pmenu = function() return vim.fn.pumvisible() == 1 end
|
|
692
|
+
H.is_selected_pmenu = function() return vim.fn.complete_info({ 'selected' }).selected ~= -1 end
|
|
693
|
+
|
|
694
|
+
H.steps_builtin.pmenu_next = { condition = H.is_visible_pmenu, action = function() return '<C-n>' end }
|
|
695
|
+
H.steps_builtin.pmenu_prev = { condition = H.is_visible_pmenu, action = function() return '<C-p>' end }
|
|
696
|
+
H.steps_builtin.pmenu_accept = { condition = H.is_selected_pmenu, action = function() return '<C-y>' end }
|
|
697
|
+
|
|
698
|
+
H.is_minisnippets_session = function() return _G.MiniSnippets ~= nil and _G.MiniSnippets.session.get() ~= nil end
|
|
699
|
+
H.is_minisnippets_matched = function() return _G.MiniSnippets ~= nil and #_G.MiniSnippets.expand({ insert = false }) > 0 end
|
|
700
|
+
H.make_minisnippets_action = function(dir) return H.make_cmd_lua_action('MiniSnippets.session.jump("' .. dir .. '")') end
|
|
701
|
+
|
|
702
|
+
H.steps_builtin.minisnippets_next = { condition = H.is_minisnippets_session, action = H.make_minisnippets_action('next') }
|
|
703
|
+
H.steps_builtin.minisnippets_prev = { condition = H.is_minisnippets_session, action = H.make_minisnippets_action('prev') }
|
|
704
|
+
H.steps_builtin.minisnippets_expand = { condition = H.is_minisnippets_matched, action = H.make_cmd_lua_action('MiniSnippets.expand()') }
|
|
705
|
+
|
|
706
|
+
H.has_minipairs = function() return _G.MiniPairs ~= nil end
|
|
707
|
+
|
|
708
|
+
H.steps_builtin.minipairs_cr = { condition = H.has_minipairs, action = function() return vim.fn.keytrans(_G.MiniPairs.cr()) end }
|
|
709
|
+
H.steps_builtin.minipairs_bs = { condition = H.has_minipairs, action = function() return vim.fn.keytrans(_G.MiniPairs.bs()) end }
|
|
710
|
+
|
|
711
|
+
H.can_jump_tsnode = function()
|
|
712
|
+
-- TODO: Remove `opts.error` after compatibility with Neovim=0.11 is dropped
|
|
713
|
+
local has_parser, parser = pcall(vim.treesitter.get_parser, 0, nil, { error = false })
|
|
714
|
+
return has_parser and parser ~= nil
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
H.make_jump_tsnode = function(side)
|
|
718
|
+
local act = function()
|
|
719
|
+
local node, pos, new_pos = H.get_tsnode(), vim.api.nvim_win_get_cursor(0), nil
|
|
720
|
+
while node ~= nil do
|
|
721
|
+
-- Output of `get_node_range` is 0-indexed with "from" data inclusive and
|
|
722
|
+
-- "to" data exclusive. This is exactly what is needed here:
|
|
723
|
+
-- - For "before" direction exact left end is needed. This will be used
|
|
724
|
+
-- in Insert mode and cursor will be between target and its left cell.
|
|
725
|
+
-- - For "after" direction the one cell to right (after normalization) is
|
|
726
|
+
-- needed because cursor in Insert mode will be just after the node.
|
|
727
|
+
local from_row, from_col, to_row, to_col = vim.treesitter.get_node_range(node)
|
|
728
|
+
local row = side == 'before' and from_row or to_row
|
|
729
|
+
local col = side == 'before' and from_col or to_col
|
|
730
|
+
new_pos = H.normalize_pos(row, col)
|
|
731
|
+
-- Iterate up the tree until different position is found. This is useful
|
|
732
|
+
-- for "before" direction and non-Insert mode.
|
|
733
|
+
if not (new_pos[1] == pos[1] and new_pos[2] == pos[2]) then
|
|
734
|
+
H.hide_completion()
|
|
735
|
+
pcall(vim.api.nvim_win_set_cursor, 0, new_pos)
|
|
736
|
+
new_pos = vim.api.nvim_win_get_cursor(0)
|
|
737
|
+
end
|
|
738
|
+
if not (new_pos[1] == pos[1] and new_pos[2] == pos[2]) then break end
|
|
739
|
+
node = node:parent()
|
|
740
|
+
end
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
-- Return callable which is wrapped to be executed after expression mapping
|
|
744
|
+
return function() return act end
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
H.steps_builtin.jump_after_tsnode = { condition = H.can_jump_tsnode, action = H.make_jump_tsnode('after') }
|
|
748
|
+
H.steps_builtin.jump_before_tsnode = { condition = H.can_jump_tsnode, action = H.make_jump_tsnode('before') }
|
|
749
|
+
|
|
750
|
+
H.steps_builtin.jump_after_close = {
|
|
751
|
+
condition = function() return vim.fn.mode() == 'i' end,
|
|
752
|
+
-- NOTE: In Insert mode 'c' flag (accept at cursor) with 'after' adjust are
|
|
753
|
+
-- needed for working "chaining". In other modes it is no flag and no adjust,
|
|
754
|
+
-- which is why these steps only work in Insert mode.
|
|
755
|
+
action = MiniKeymap.gen_step.search_pattern([=[[)\]}"'`]]=], 'cW', { side = 'after' }).action,
|
|
756
|
+
}
|
|
757
|
+
H.steps_builtin.jump_before_open = {
|
|
758
|
+
condition = function() return vim.fn.mode() == 'i' end,
|
|
759
|
+
action = MiniKeymap.gen_step.search_pattern([=[[(\[{"'`]]=], 'bW', { side = 'before' }).action,
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
H.is_in_indent = function()
|
|
763
|
+
local line, col = vim.api.nvim_get_current_line(), vim.fn.col('.')
|
|
764
|
+
local offset = vim.fn.mode() == 'i' and 1 or 0
|
|
765
|
+
return line:sub(1, col - offset):find('^%s*$') ~= nil
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
H.increase_indent_keys = { i = '<C-t>', v = '>', V = '>', ['\22'] = '>' }
|
|
769
|
+
H.decrease_indent_keys = { i = '<C-d>', v = '<', V = '<', ['\22'] = '<' }
|
|
770
|
+
|
|
771
|
+
H.steps_builtin.increase_indent = { condition = H.is_in_indent, action = function() return H.increase_indent_keys[vim.fn.mode()] or '>>' end }
|
|
772
|
+
H.steps_builtin.decrease_indent = { condition = H.is_in_indent, action = function() return H.decrease_indent_keys[vim.fn.mode()] or '<<' end }
|
|
773
|
+
|
|
774
|
+
H.hungry_bs_condition = function()
|
|
775
|
+
local line, col = vim.api.nvim_get_current_line(), vim.fn.col('.')
|
|
776
|
+
local offset = vim.fn.mode() == 'i' and 1 or 0
|
|
777
|
+
return line:sub(1, col - offset):find('%s+$') ~= nil
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
H.hungry_bs_action = function()
|
|
781
|
+
return function()
|
|
782
|
+
local line, lnum, col = vim.api.nvim_get_current_line(), vim.fn.line('.'), vim.fn.col('.')
|
|
783
|
+
local offset = vim.fn.mode() == 'i' and 1 or 0
|
|
784
|
+
local from_col = line:sub(1, col - offset):match('()%s+$')
|
|
785
|
+
vim.api.nvim_buf_set_text(0, lnum - 1, from_col - 1, lnum - 1, col - offset, {})
|
|
786
|
+
vim.api.nvim_win_set_cursor(0, { lnum, from_col - 1 })
|
|
787
|
+
end
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
H.steps_builtin.hungry_bs = { condition = H.hungry_bs_condition, action = H.hungry_bs_action }
|
|
791
|
+
|
|
792
|
+
H.make_vimsnippet_condition = function(dir) return function() return vim.snippet.active({ direction = dir }) end end
|
|
793
|
+
H.make_vimsnippet_action = function(dir) return H.make_cmd_lua_action('vim.snippet.jump(' .. dir .. ')') end
|
|
794
|
+
|
|
795
|
+
H.steps_builtin.vimsnippet_next = { condition = H.make_vimsnippet_condition(1), action = H.make_vimsnippet_action(1) }
|
|
796
|
+
H.steps_builtin.vimsnippet_prev = { condition = H.make_vimsnippet_condition(-1), action = H.make_vimsnippet_action(-1) }
|
|
797
|
+
|
|
798
|
+
H.is_visible_cmp = function() return H.has_module('cmp') and require('cmp').visible() end
|
|
799
|
+
H.is_selected_cmp = function() return H.has_module('cmp') and require('cmp').get_selected_entry() ~= nil end
|
|
800
|
+
H.make_cmp_action = function(action) return H.make_cmd_lua_action('require("cmp").' .. action .. '()') end
|
|
801
|
+
|
|
802
|
+
H.steps_builtin.cmp_next = { condition = H.is_visible_cmp, action = H.make_cmp_action('select_next_item') }
|
|
803
|
+
H.steps_builtin.cmp_prev = { condition = H.is_visible_cmp, action = H.make_cmp_action('select_prev_item') }
|
|
804
|
+
H.steps_builtin.cmp_accept = { condition = H.is_selected_cmp, action = H.make_cmp_action('confirm') }
|
|
805
|
+
|
|
806
|
+
H.is_visible_blink = function() return H.has_module('blink.cmp') and require('blink.cmp').is_menu_visible() end
|
|
807
|
+
H.is_selected_blink = function() return H.is_visible_blink() and require('blink.cmp').get_selected_item() ~= nil end
|
|
808
|
+
H.make_blink_action = function(action) return H.make_cmd_lua_action('require("blink.cmp").' .. action .. '()') end
|
|
809
|
+
|
|
810
|
+
H.steps_builtin.blink_next = { condition = H.is_visible_blink, action = H.make_blink_action('select_next') }
|
|
811
|
+
H.steps_builtin.blink_prev = { condition = H.is_visible_blink, action = H.make_blink_action('select_prev') }
|
|
812
|
+
H.steps_builtin.blink_accept = { condition = H.is_selected_blink, action = H.make_blink_action('accept') }
|
|
813
|
+
|
|
814
|
+
H.make_luasnip_condition = function(dir) return function() return H.has_module('luasnip') and require('luasnip').jumpable(dir) end end
|
|
815
|
+
H.is_luasnip_expandable = function() return H.has_module('luasnip') and require('luasnip').expandable() end
|
|
816
|
+
H.make_luasnip_action = function(dir) return H.make_cmd_lua_action('require("luasnip").jump(' .. dir .. ')') end
|
|
817
|
+
|
|
818
|
+
H.steps_builtin.luasnip_next = { condition = H.make_luasnip_condition(1), action = H.make_luasnip_action(1) }
|
|
819
|
+
H.steps_builtin.luasnip_prev = { condition = H.make_luasnip_condition(-1), action = H.make_luasnip_action(-1) }
|
|
820
|
+
H.steps_builtin.luasnip_expand = { condition = H.is_luasnip_expandable, action = H.make_cmd_lua_action('require("luasnip").expand()') }
|
|
821
|
+
|
|
822
|
+
H.has_nvimautopairs = function() return H.has_module('nvim-autopairs') end
|
|
823
|
+
H.make_nvimautopairs_action = function(method) return function() return vim.fn.keytrans(require('nvim-autopairs')[method]()) end end
|
|
824
|
+
|
|
825
|
+
H.steps_builtin.nvimautopairs_cr = { condition = H.has_nvimautopairs, action = H.make_nvimautopairs_action('autopairs_cr') }
|
|
826
|
+
H.steps_builtin.nvimautopairs_bs = { condition = H.has_nvimautopairs, action = H.make_nvimautopairs_action('autopairs_bs') }
|
|
827
|
+
--stylua: ignore end
|
|
828
|
+
|
|
829
|
+
-- Validators -----------------------------------------------------------------
|
|
830
|
+
H.is_string = function(x) return type(x) == 'string' end
|
|
831
|
+
|
|
832
|
+
H.is_array_of = function(x, predicate)
|
|
833
|
+
if not H.islist(x) then return false end
|
|
834
|
+
for i = 1, #x do
|
|
835
|
+
if not predicate(x[i]) then return false end
|
|
836
|
+
end
|
|
837
|
+
return true
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
-- Utilities ------------------------------------------------------------------
|
|
841
|
+
H.error = function(msg) error('(mini.keymap) ' .. msg, 0) end
|
|
842
|
+
|
|
843
|
+
H.check_type = function(name, val, ref, allow_nil)
|
|
844
|
+
if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
|
|
845
|
+
H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
H.notify = function(msg, level_name, silent)
|
|
849
|
+
if not silent then vim.notify('(mini.keymap) ' .. msg, vim.log.levels[level_name]) end
|
|
850
|
+
end
|
|
851
|
+
|
|
852
|
+
H.normalize_pos = function(row, col)
|
|
853
|
+
-- Input is {0,0} indexed, output is {1,0} indexed
|
|
854
|
+
if row < 0 or (row == 0 and col < 0) then return { 1, 0 } end
|
|
855
|
+
local last_row = vim.api.nvim_buf_line_count(0) - 1
|
|
856
|
+
local n_col_last_row = H.get_row_cols(last_row)
|
|
857
|
+
-- Assume this is used in Insert node, so placing just after EOL can be done
|
|
858
|
+
if row > last_row or (row == last_row and col > n_col_last_row) then return { last_row + 1, n_col_last_row } end
|
|
859
|
+
|
|
860
|
+
if col < 0 then return { row, H.get_row_cols(row - 1) } end
|
|
861
|
+
if col > H.get_row_cols(row) then return { row + 2, 0 } end
|
|
862
|
+
return { row + 1, col }
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
H.get_row_cols = function(row) return vim.fn.getline(row + 1):len() end
|
|
866
|
+
|
|
867
|
+
H.get_tsnode = function() return vim.treesitter.get_node() end
|
|
868
|
+
|
|
869
|
+
H.hide_completion = function()
|
|
870
|
+
-- NOTE: `complete()` instead of emulating <C-y> works immediately (without
|
|
871
|
+
-- the need to `vim.schedule()`). See 'mini.snippets' for more details.
|
|
872
|
+
-- NOTE: Checking 'pumvisible() == 1' should not lead to edge cases from
|
|
873
|
+
-- 'mini.snippets' (as there is no extmarks involved).
|
|
874
|
+
if vim.fn.mode() == 'i' and vim.fn.pumvisible() == 1 then vim.cmd('silent noautocmd call complete(col("."), [])') end
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
-- TODO: Remove after compatibility with Neovim=0.9 is dropped
|
|
878
|
+
H.islist = vim.fn.has('nvim-0.10') == 1 and vim.islist or vim.tbl_islist
|
|
879
|
+
|
|
880
|
+
return MiniKeymap
|