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.
Files changed (218) hide show
  1. package/.conda/retrovim.yaml +259 -0
  2. package/.conda/terax.icns +0 -0
  3. package/.conda/terax.ico +0 -0
  4. package/.conda/terax.png +0 -0
  5. package/.github/workflows/release.yml +95 -0
  6. package/.gitmodules +3 -0
  7. package/.npm/kanata_touchcursor.js +28 -0
  8. package/.npm/nvim.js +26 -0
  9. package/.npm/yazi.js +26 -0
  10. package/.npm/zsh.js +17 -0
  11. package/.pip/kanata_touchcursor/__init__.py +28 -0
  12. package/.pip/nvim/__init__.py +31 -0
  13. package/.pip/yazi/__init__.py +31 -0
  14. package/.pip/zsh/__init__.py +22 -0
  15. package/CHANGELOG.md +26 -0
  16. package/LICENSE +674 -0
  17. package/README.md +336 -0
  18. package/kanata/touchcursor.kbd +164 -0
  19. package/nvim/init.lua +813 -0
  20. package/nvim/plugins/mini.nvim/.github/DISCUSSION_TEMPLATE/q-a.yml +72 -0
  21. package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/bug-report.yml +136 -0
  22. package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/config.yml +5 -0
  23. package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/feature-request.yml +75 -0
  24. package/nvim/plugins/mini.nvim/.github/PULL_REQUEST_TEMPLATE.md +2 -0
  25. package/nvim/plugins/mini.nvim/.github/workflows/quality-control.yml +150 -0
  26. package/nvim/plugins/mini.nvim/.pre-commit-config.yaml +20 -0
  27. package/nvim/plugins/mini.nvim/.stylua.toml +7 -0
  28. package/nvim/plugins/mini.nvim/.styluaignore +1 -0
  29. package/nvim/plugins/mini.nvim/CHANGELOG.md +1894 -0
  30. package/nvim/plugins/mini.nvim/CODE_OF_CONDUCT.md +132 -0
  31. package/nvim/plugins/mini.nvim/CONTRIBUTING.md +331 -0
  32. package/nvim/plugins/mini.nvim/LICENSE +21 -0
  33. package/nvim/plugins/mini.nvim/MAINTAINING.md +330 -0
  34. package/nvim/plugins/mini.nvim/Makefile +51 -0
  35. package/nvim/plugins/mini.nvim/README.md +261 -0
  36. package/nvim/plugins/mini.nvim/TESTING.md +1011 -0
  37. package/nvim/plugins/mini.nvim/benchmarks/starter/README.md +35 -0
  38. package/nvim/plugins/mini.nvim/benchmarks/starter/benchmark.sh +56 -0
  39. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-alpha.lua +21 -0
  40. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-original.lua +17 -0
  41. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-starter.lua +18 -0
  42. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_empty.lua +4 -0
  43. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_starter-default.lua +7 -0
  44. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-alpha.lua +10 -0
  45. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-original.lua +7 -0
  46. package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-starter.lua +20 -0
  47. package/nvim/plugins/mini.nvim/benchmarks/starter/install.sh +10 -0
  48. package/nvim/plugins/mini.nvim/benchmarks/starter/make_summary.py +68 -0
  49. package/nvim/plugins/mini.nvim/benchmarks/starter/startup-summary.md +10 -0
  50. package/nvim/plugins/mini.nvim/colors/miniautumn.lua +55 -0
  51. package/nvim/plugins/mini.nvim/colors/minicyan.lua +95 -0
  52. package/nvim/plugins/mini.nvim/colors/minischeme.lua +95 -0
  53. package/nvim/plugins/mini.nvim/colors/minispring.lua +53 -0
  54. package/nvim/plugins/mini.nvim/colors/minisummer.lua +49 -0
  55. package/nvim/plugins/mini.nvim/colors/miniwinter.lua +51 -0
  56. package/nvim/plugins/mini.nvim/colors/randomhue.lua +16 -0
  57. package/nvim/plugins/mini.nvim/doc/mini-ai.txt +889 -0
  58. package/nvim/plugins/mini.nvim/doc/mini-align.txt +923 -0
  59. package/nvim/plugins/mini.nvim/doc/mini-animate.txt +937 -0
  60. package/nvim/plugins/mini.nvim/doc/mini-base16.txt +285 -0
  61. package/nvim/plugins/mini.nvim/doc/mini-basics.txt +359 -0
  62. package/nvim/plugins/mini.nvim/doc/mini-bracketed.txt +622 -0
  63. package/nvim/plugins/mini.nvim/doc/mini-bufremove.txt +123 -0
  64. package/nvim/plugins/mini.nvim/doc/mini-clue.txt +760 -0
  65. package/nvim/plugins/mini.nvim/doc/mini-cmdline.txt +392 -0
  66. package/nvim/plugins/mini.nvim/doc/mini-colors.txt +880 -0
  67. package/nvim/plugins/mini.nvim/doc/mini-comment.txt +230 -0
  68. package/nvim/plugins/mini.nvim/doc/mini-completion.txt +477 -0
  69. package/nvim/plugins/mini.nvim/doc/mini-cursorword.txt +105 -0
  70. package/nvim/plugins/mini.nvim/doc/mini-deps.txt +590 -0
  71. package/nvim/plugins/mini.nvim/doc/mini-diff.txt +661 -0
  72. package/nvim/plugins/mini.nvim/doc/mini-doc.txt +434 -0
  73. package/nvim/plugins/mini.nvim/doc/mini-extra.txt +856 -0
  74. package/nvim/plugins/mini.nvim/doc/mini-files.txt +1018 -0
  75. package/nvim/plugins/mini.nvim/doc/mini-fuzzy.txt +160 -0
  76. package/nvim/plugins/mini.nvim/doc/mini-git.txt +425 -0
  77. package/nvim/plugins/mini.nvim/doc/mini-hipatterns.txt +489 -0
  78. package/nvim/plugins/mini.nvim/doc/mini-hues.txt +420 -0
  79. package/nvim/plugins/mini.nvim/doc/mini-icons.txt +508 -0
  80. package/nvim/plugins/mini.nvim/doc/mini-indentscope.txt +485 -0
  81. package/nvim/plugins/mini.nvim/doc/mini-input.txt +932 -0
  82. package/nvim/plugins/mini.nvim/doc/mini-jump.txt +202 -0
  83. package/nvim/plugins/mini.nvim/doc/mini-jump2d.txt +525 -0
  84. package/nvim/plugins/mini.nvim/doc/mini-keymap.txt +449 -0
  85. package/nvim/plugins/mini.nvim/doc/mini-map.txt +717 -0
  86. package/nvim/plugins/mini.nvim/doc/mini-misc.txt +431 -0
  87. package/nvim/plugins/mini.nvim/doc/mini-move.txt +181 -0
  88. package/nvim/plugins/mini.nvim/doc/mini-notify.txt +434 -0
  89. package/nvim/plugins/mini.nvim/doc/mini-nvim.txt +431 -0
  90. package/nvim/plugins/mini.nvim/doc/mini-operators.txt +472 -0
  91. package/nvim/plugins/mini.nvim/doc/mini-pairs.txt +346 -0
  92. package/nvim/plugins/mini.nvim/doc/mini-pick.txt +1535 -0
  93. package/nvim/plugins/mini.nvim/doc/mini-sessions.txt +239 -0
  94. package/nvim/plugins/mini.nvim/doc/mini-snippets.txt +1291 -0
  95. package/nvim/plugins/mini.nvim/doc/mini-splitjoin.txt +536 -0
  96. package/nvim/plugins/mini.nvim/doc/mini-starter.txt +618 -0
  97. package/nvim/plugins/mini.nvim/doc/mini-statusline.txt +361 -0
  98. package/nvim/plugins/mini.nvim/doc/mini-surround.txt +863 -0
  99. package/nvim/plugins/mini.nvim/doc/mini-tabline.txt +151 -0
  100. package/nvim/plugins/mini.nvim/doc/mini-test.txt +966 -0
  101. package/nvim/plugins/mini.nvim/doc/mini-trailspace.txt +91 -0
  102. package/nvim/plugins/mini.nvim/doc/mini-visits.txt +937 -0
  103. package/nvim/plugins/mini.nvim/logo.png +0 -0
  104. package/nvim/plugins/mini.nvim/lua/mini/ai.lua +2244 -0
  105. package/nvim/plugins/mini.nvim/lua/mini/align.lua +2076 -0
  106. package/nvim/plugins/mini.nvim/lua/mini/animate.lua +2127 -0
  107. package/nvim/plugins/mini.nvim/lua/mini/base16.lua +1752 -0
  108. package/nvim/plugins/mini.nvim/lua/mini/basics.lua +772 -0
  109. package/nvim/plugins/mini.nvim/lua/mini/bracketed.lua +2013 -0
  110. package/nvim/plugins/mini.nvim/lua/mini/bufremove.lua +283 -0
  111. package/nvim/plugins/mini.nvim/lua/mini/clue.lua +2096 -0
  112. package/nvim/plugins/mini.nvim/lua/mini/cmdline.lua +1182 -0
  113. package/nvim/plugins/mini.nvim/lua/mini/colors.lua +2483 -0
  114. package/nvim/plugins/mini.nvim/lua/mini/comment.lua +586 -0
  115. package/nvim/plugins/mini.nvim/lua/mini/completion.lua +2094 -0
  116. package/nvim/plugins/mini.nvim/lua/mini/cursorword.lua +311 -0
  117. package/nvim/plugins/mini.nvim/lua/mini/deps.lua +1660 -0
  118. package/nvim/plugins/mini.nvim/lua/mini/diff.lua +1938 -0
  119. package/nvim/plugins/mini.nvim/lua/mini/doc.lua +1371 -0
  120. package/nvim/plugins/mini.nvim/lua/mini/extra.lua +2290 -0
  121. package/nvim/plugins/mini.nvim/lua/mini/files.lua +3145 -0
  122. package/nvim/plugins/mini.nvim/lua/mini/fuzzy.lua +356 -0
  123. package/nvim/plugins/mini.nvim/lua/mini/git.lua +1737 -0
  124. package/nvim/plugins/mini.nvim/lua/mini/hipatterns.lua +1042 -0
  125. package/nvim/plugins/mini.nvim/lua/mini/hues.lua +2088 -0
  126. package/nvim/plugins/mini.nvim/lua/mini/icons.lua +2254 -0
  127. package/nvim/plugins/mini.nvim/lua/mini/indentscope.lua +1158 -0
  128. package/nvim/plugins/mini.nvim/lua/mini/init.lua +427 -0
  129. package/nvim/plugins/mini.nvim/lua/mini/input.lua +2183 -0
  130. package/nvim/plugins/mini.nvim/lua/mini/jump.lua +609 -0
  131. package/nvim/plugins/mini.nvim/lua/mini/jump2d.lua +1244 -0
  132. package/nvim/plugins/mini.nvim/lua/mini/keymap.lua +880 -0
  133. package/nvim/plugins/mini.nvim/lua/mini/map.lua +1709 -0
  134. package/nvim/plugins/mini.nvim/lua/mini/misc.lua +969 -0
  135. package/nvim/plugins/mini.nvim/lua/mini/move.lua +509 -0
  136. package/nvim/plugins/mini.nvim/lua/mini/notify.lua +938 -0
  137. package/nvim/plugins/mini.nvim/lua/mini/operators.lua +1349 -0
  138. package/nvim/plugins/mini.nvim/lua/mini/pairs.lua +657 -0
  139. package/nvim/plugins/mini.nvim/lua/mini/pick.lua +3876 -0
  140. package/nvim/plugins/mini.nvim/lua/mini/sessions.lua +689 -0
  141. package/nvim/plugins/mini.nvim/lua/mini/snippets.lua +2828 -0
  142. package/nvim/plugins/mini.nvim/lua/mini/splitjoin.lua +1132 -0
  143. package/nvim/plugins/mini.nvim/lua/mini/starter.lua +1599 -0
  144. package/nvim/plugins/mini.nvim/lua/mini/statusline.lua +686 -0
  145. package/nvim/plugins/mini.nvim/lua/mini/surround.lua +2388 -0
  146. package/nvim/plugins/mini.nvim/lua/mini/tabline.lua +564 -0
  147. package/nvim/plugins/mini.nvim/lua/mini/test.lua +2516 -0
  148. package/nvim/plugins/mini.nvim/lua/mini/trailspace.lua +215 -0
  149. package/nvim/plugins/mini.nvim/lua/mini/visits.lua +1577 -0
  150. package/nvim/plugins/mini.nvim/readmes/mini-ai.md +190 -0
  151. package/nvim/plugins/mini.nvim/readmes/mini-align.md +203 -0
  152. package/nvim/plugins/mini.nvim/readmes/mini-animate.md +214 -0
  153. package/nvim/plugins/mini.nvim/readmes/mini-base16.md +198 -0
  154. package/nvim/plugins/mini.nvim/readmes/mini-basics.md +184 -0
  155. package/nvim/plugins/mini.nvim/readmes/mini-bracketed.md +193 -0
  156. package/nvim/plugins/mini.nvim/readmes/mini-bufremove.md +139 -0
  157. package/nvim/plugins/mini.nvim/readmes/mini-clue.md +260 -0
  158. package/nvim/plugins/mini.nvim/readmes/mini-cmdline.md +183 -0
  159. package/nvim/plugins/mini.nvim/readmes/mini-colors.md +169 -0
  160. package/nvim/plugins/mini.nvim/readmes/mini-comment.md +183 -0
  161. package/nvim/plugins/mini.nvim/readmes/mini-completion.md +217 -0
  162. package/nvim/plugins/mini.nvim/readmes/mini-cursorword.md +137 -0
  163. package/nvim/plugins/mini.nvim/readmes/mini-deps.md +271 -0
  164. package/nvim/plugins/mini.nvim/readmes/mini-diff.md +289 -0
  165. package/nvim/plugins/mini.nvim/readmes/mini-doc.md +198 -0
  166. package/nvim/plugins/mini.nvim/readmes/mini-extra.md +158 -0
  167. package/nvim/plugins/mini.nvim/readmes/mini-files.md +247 -0
  168. package/nvim/plugins/mini.nvim/readmes/mini-fuzzy.md +134 -0
  169. package/nvim/plugins/mini.nvim/readmes/mini-git.md +168 -0
  170. package/nvim/plugins/mini.nvim/readmes/mini-hipatterns.md +176 -0
  171. package/nvim/plugins/mini.nvim/readmes/mini-hues.md +285 -0
  172. package/nvim/plugins/mini.nvim/readmes/mini-icons.md +183 -0
  173. package/nvim/plugins/mini.nvim/readmes/mini-indentscope.md +191 -0
  174. package/nvim/plugins/mini.nvim/readmes/mini-input.md +163 -0
  175. package/nvim/plugins/mini.nvim/readmes/mini-jump.md +161 -0
  176. package/nvim/plugins/mini.nvim/readmes/mini-jump2d.md +197 -0
  177. package/nvim/plugins/mini.nvim/readmes/mini-keymap.md +205 -0
  178. package/nvim/plugins/mini.nvim/readmes/mini-map.md +191 -0
  179. package/nvim/plugins/mini.nvim/readmes/mini-misc.md +145 -0
  180. package/nvim/plugins/mini.nvim/readmes/mini-move.md +163 -0
  181. package/nvim/plugins/mini.nvim/readmes/mini-notify.md +175 -0
  182. package/nvim/plugins/mini.nvim/readmes/mini-operators.md +193 -0
  183. package/nvim/plugins/mini.nvim/readmes/mini-pairs.md +158 -0
  184. package/nvim/plugins/mini.nvim/readmes/mini-pick.md +340 -0
  185. package/nvim/plugins/mini.nvim/readmes/mini-sessions.md +164 -0
  186. package/nvim/plugins/mini.nvim/readmes/mini-snippets.md +373 -0
  187. package/nvim/plugins/mini.nvim/readmes/mini-splitjoin.md +194 -0
  188. package/nvim/plugins/mini.nvim/readmes/mini-starter.md +176 -0
  189. package/nvim/plugins/mini.nvim/readmes/mini-statusline.md +155 -0
  190. package/nvim/plugins/mini.nvim/readmes/mini-surround.md +190 -0
  191. package/nvim/plugins/mini.nvim/readmes/mini-tabline.md +156 -0
  192. package/nvim/plugins/mini.nvim/readmes/mini-test.md +175 -0
  193. package/nvim/plugins/mini.nvim/readmes/mini-trailspace.md +137 -0
  194. package/nvim/plugins/mini.nvim/readmes/mini-visits.md +243 -0
  195. package/nvim/plugins/mini.nvim/scripts/dual_log.sh +13 -0
  196. package/nvim/plugins/mini.nvim/scripts/dual_push.sh +15 -0
  197. package/nvim/plugins/mini.nvim/scripts/dual_release.sh +102 -0
  198. package/nvim/plugins/mini.nvim/scripts/dual_sync.sh +115 -0
  199. package/nvim/plugins/mini.nvim/scripts/init-deps-example.lua +59 -0
  200. package/nvim/plugins/mini.nvim/scripts/lint-filename-length.sh +16 -0
  201. package/nvim/plugins/mini.nvim/scripts/lintcommit-ci.sh +18 -0
  202. package/nvim/plugins/mini.nvim/scripts/lintcommit.lua +393 -0
  203. package/nvim/plugins/mini.nvim/scripts/minidoc.lua +57 -0
  204. package/nvim/plugins/mini.nvim/scripts/minimal_init.lua +28 -0
  205. package/nvim/plugins/mini.nvim/scripts/minitest.lua +4 -0
  206. package/package.json +16 -0
  207. package/pyproject.toml +43 -0
  208. package/yazi/init.lua +12 -0
  209. package/yazi/keymap.toml +114 -0
  210. package/yazi/lesskey +5 -0
  211. package/yazi/plugins/bookmarks.yazi/main.lua +86 -0
  212. package/yazi/plugins/cd-git-root.yazi/main.lua +31 -0
  213. package/yazi/plugins/smart-enter.yazi/main.lua +11 -0
  214. package/yazi/theme.toml +26 -0
  215. package/yazi/yazi.toml +15 -0
  216. package/zsh/.zshrc +145 -0
  217. package/zsh/starship.toml +20 -0
  218. package/zsh/zsh-patina.toml +2 -0
@@ -0,0 +1,1291 @@
1
+ *mini.snippets* Manage and expand snippets
2
+
3
+ MIT License Copyright (c) 2024 Evgeni Chasnovski
4
+
5
+ ------------------------------------------------------------------------------
6
+ *MiniSnippets*
7
+ Snippet is a template for a frequently used text. Typical workflow is to type
8
+ snippet's (configurable) prefix and expand it into a snippet session.
9
+
10
+ The template usually contains both pre-defined text and places (called
11
+ "tabstops") for user to interactively change/add text during snippet session.
12
+
13
+ This module supports (only) snippet syntax defined in LSP specification (with
14
+ small deviations). See |MiniSnippets-syntax-specification|.
15
+
16
+ Features:
17
+ - Manage snippet collection by adding it explicitly or with a flexible set of
18
+ performant built-in loaders. See |MiniSnippets.gen_loader|.
19
+
20
+ - Configured snippets are efficiently resolved before every expand based on
21
+ current local context. This, for example, allows using different snippets
22
+ in different local tree-sitter languages (like in markdown code blocks).
23
+ See |MiniSnippets.default_prepare()|.
24
+
25
+ - Match which snippet to insert based on the currently typed text.
26
+ Supports both exact and fuzzy matching. See |MiniSnippets.default_match()|.
27
+
28
+ - Select from several matched snippets via `vim.ui.select()`.
29
+ See |MiniSnippets.default_select()|.
30
+
31
+ - Start specialized in-process LSP server to show loaded snippets inside
32
+ (auto)completion engines (like |mini.completion|).
33
+ See |MiniSnippets.start_lsp_server()|.
34
+
35
+ - Insert, jump, and edit during snippet session in a configurable manner:
36
+ - Configurable mappings for jumping and stopping.
37
+ - Jumping wraps around the tabstops for easier navigation.
38
+ - Easy to reason rules for when session automatically stops.
39
+ - Text synchronization of linked tabstops preserving relative indent.
40
+ - Dynamic tabstop state visualization (current/visited/unvisited, etc.)
41
+ - Inline visualization of empty tabstops (requires Neovim>=0.10).
42
+ - Works inside comments by preserving comment leader on new lines.
43
+ - Supports nested sessions (expand snippet while there is an active one).
44
+ See |MiniSnippets.default_insert()|.
45
+
46
+ - Exported function to parse snippet body into easy-to-reason data structure.
47
+ See |MiniSnippets.parse()|.
48
+
49
+ Notes:
50
+ - It does not set up any snippet collection by default. Explicitly populate
51
+ `config.snippets` to have snippets to match from.
52
+ - It does not come with a built-in snippet collection. It is expected from
53
+ users to add their own snippets, manually or with dedicated plugin(s).
54
+ - It does not support variable/tabstop transformations in default snippet
55
+ session. This requires ECMAScript Regular Expression parser which can not
56
+ be implemented concisely.
57
+
58
+ Sources with more details:
59
+ - |MiniSnippets-glossary|
60
+ - |MiniSnippets-overview|
61
+ - |MiniSnippets-examples|
62
+ - |MiniSnippets-in-other-plugins| (for plugin authors)
63
+
64
+ # Dependencies ~
65
+
66
+ This module doesn't come with snippet collection. Either create it manually
67
+ or install a dedicated plugin. For example,
68
+ [rafamadriz/friendly-snippets](https://github.com/rafamadriz/friendly-snippets).
69
+
70
+ # Setup ~
71
+
72
+ This module needs a setup with `require('mini.snippets').setup({})` (replace `{}`
73
+ with your `config` table). It will create global Lua table `MiniSnippets` which
74
+ you can use for scripting or manually (with `:lua MiniSnippets.*`).
75
+
76
+ See |MiniSnippets.config| for `config` structure and default values.
77
+
78
+ You can override runtime config settings locally to buffer inside
79
+ `vim.b.minisnippets_config` which should have same structure as
80
+ `MiniSnippets.config`. See |mini.nvim-buffer-local-config| for more details.
81
+
82
+ # Comparisons ~
83
+
84
+ - [L3MON4D3/LuaSnip](https://github.com/L3MON4D3/LuaSnip):
85
+ - Both contain functionality to load snippets from file system.
86
+ This module provides several common loader generators while `LuaSnip`
87
+ contains a more elaborate loading setup.
88
+ Also both require explicit opt-in for which snippets to load.
89
+ - Both support LSP snippet format. `LuaSnip` also provides own more
90
+ elaborate snippet format which is out of scope for this module.
91
+ - `LuaSnip` can autoexpand snippets, while this module always requires
92
+ an explicit user action to expand (by design).
93
+ - Both contain snippet expand functionality which differs in some aspects:
94
+ - `LuaSnip` has an elaborate dynamic tabstop visualization config.
95
+ This module provides a handful of dedicated highlight groups.
96
+ - This module provides configurable visualization of empty tabstops.
97
+ - `LuaSnip` implements nested sessions by essentially merging them
98
+ into one. This module treats each nested session separately (to not
99
+ visually overload) while storing them in stack (first in last out).
100
+ - `LuaSnip` uses |Select-mode| to power replacing current tabstop,
101
+ while this module always stays in |Insert-mode|. This enables easier
102
+ mapping understanding and more targeted highlighting.
103
+ - This module implements jumping which wraps after final tabstop
104
+ for more flexible navigation (enhanced with by a more flexible
105
+ autostopping rules), while `LuaSnip` autostops session once
106
+ jumping reached the final tabstop.
107
+
108
+ - Built-in |vim.snippet| (on Neovim>=0.10):
109
+ - Does not contain functionality to load or match snippets (by design),
110
+ while this module does.
111
+ - Both contain expand functionality based on LSP snippet format.
112
+ Differences in how snippet sessions are handled are similar to
113
+ comparison with `LuaSnip`.
114
+
115
+ - [rafamadriz/friendly-snippets](https://github.com/rafamadriz/friendly-snippets):
116
+ - A snippet collection plugin without features to manage or expand them.
117
+ This module is designed with `friendly-snippets` compatibility in mind.
118
+
119
+ - [abeldekat/cmp-mini-snippets](https://github.com/abeldekat/cmp-mini-snippets):
120
+ - A source for [hrsh7th/nvim-cmp](https://github.com/hrsh7th/nvim-cmp)
121
+ that integrates |mini.snippets|.
122
+
123
+ # Highlight groups ~
124
+ *MiniSnippets-hl-groups*
125
+
126
+ - `MiniSnippetsCurrent` - current tabstop.
127
+ - `MiniSnippetsCurrentReplace` - current tabstop, placeholder is to be replaced.
128
+ - `MiniSnippetsFinal` - special `$0` tabstop.
129
+ - `MiniSnippetsUnvisited` - not yet visited tabstop(s).
130
+ - `MiniSnippetsVisited` - visited tabstop(s).
131
+
132
+ To change any highlight group, set it directly with |nvim_set_hl()|.
133
+
134
+ # Disabling ~
135
+
136
+ To disable core functionality, set `vim.g.minisnippets_disable` (globally) or
137
+ `vim.b.minisnippets_disable` (for a buffer) to `true`. Considering high number
138
+ of different scenarios and customization intentions, writing exact rules
139
+ for disabling module's functionality is left to user. See
140
+ |mini.nvim-disabling-recipes| for common recipes.
141
+
142
+ # Using in other plugins ~
143
+ *MiniSnippets-in-other-plugins*
144
+
145
+ - Perform a `_G.MiniSnippets ~= nil` check before using any feature. This
146
+ ensures that user explicitly set up the module.
147
+
148
+ - To insert snippet given its body (like |vim.snippet.expand()|), use: >lua
149
+
150
+ -- Use configured `insert` method with falling back to default
151
+ local insert = MiniSnippets.config.expand.insert
152
+ or MiniSnippets.default_insert
153
+ -- Insert at cursor
154
+ insert({ body = snippet })
155
+ <
156
+ - To get available snippets, use: >lua
157
+
158
+ -- Get snippets matched at cursor
159
+ MiniSnippets.expand({ insert = false })
160
+
161
+ -- Get all snippets available at cursor context
162
+ MiniSnippets.expand({ match = false, insert = false })
163
+ <
164
+ ------------------------------------------------------------------------------
165
+ *MiniSnippets-glossary*
166
+ POSITION ~
167
+ Table representing position in a buffer. Fields:
168
+ - <line> `(number)` - line number (starts at 1).
169
+ - <col> `(number)` - column number (starts at 1).
170
+
171
+ REGION ~
172
+ Table representing region in a buffer.
173
+ Fields: <from> and <to> for inclusive start/end POSITIONs.
174
+
175
+ SNIPPET ~
176
+ Data about template to insert. Should contain fields:
177
+ - <prefix> - string snippet identifier.
178
+ - <body> - string snippet content with appropriate syntax.
179
+ - <desc> - string snippet description in human readable form.
180
+
181
+ Can also be used to mean snippet body if distinction is clear.
182
+
183
+ SNIPPET SESSION ~
184
+ Interactive state for user to adjust inserted snippet.
185
+
186
+ MATCHED SNIPPET ~
187
+ Snippet which contains <region> field with region that matched it.
188
+ Usually region needs to be removed.
189
+
190
+ SNIPPET NODE ~
191
+ Unit of parsed snippet body. See |MiniSnippets.parse()|.
192
+
193
+ TABSTOP ~
194
+ Dedicated places in snippet body for users to interactively adjust.
195
+ Specified in snippet body with `$` followed by digit(s).
196
+
197
+ LINKED TABSTOPS ~
198
+ Different nodes assigned the same tabstop. Updated in sync.
199
+
200
+ REFERENCE NODE ~
201
+ First (from left to right) node of linked tabstops. Used to determine
202
+ synced text and cursor placement after jump.
203
+
204
+ EXPAND ~
205
+ Action to start snippet session based on currently typed text.
206
+ Always done in current buffer at cursor. Executed steps:
207
+ - `PREPARE` - resolve raw config snippets at context.
208
+ - `MATCH` - match resolved snippets at cursor position.
209
+ - `SELECT` - possibly choose among matched snippets.
210
+ - `INSERT` - insert selected snippet and start snippet session.
211
+
212
+ ------------------------------------------------------------------------------
213
+ *MiniSnippets-overview*
214
+ Snippet is a template for a frequently used text. Typical workflow is to type
215
+ snippet's (configurable) prefix and expand it into a snippet session: add some
216
+ pre-defined text and allow user to interactively change/add at certain places.
217
+
218
+ This overview assumes default config for mappings and expand.
219
+ See |MiniSnippets.config| and |MiniSnippets-examples| for more details.
220
+
221
+ # Snippet structure ~
222
+
223
+ Snippet consists from three parts:
224
+ - `Prefix` - identifier used to match against current text.
225
+ - `Body` - actually inserted content with appropriate syntax.
226
+ - `Desc` - description in human readable form.
227
+
228
+ Example: `{ prefix = 'tis', body = 'This is snippet', desc = 'Snip' }`
229
+ Typing `tis` and pressing "expand" mapping (<C-j> by default) will remove "tis",
230
+ add "This is snippet", and place cursor at the end in Insert mode.
231
+
232
+ # Syntax ~
233
+ *MiniSnippets-syntax-specification*
234
+
235
+ Inserting just text after typing smaller prefix is already powerful enough.
236
+ For more flexibility, snippet body can be formatted in a special way to
237
+ provide extra features. This module implements support for syntax defined
238
+ in LSP specification (with small deviations). See this link for reference:
239
+ https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#snippet_syntax
240
+
241
+ A quick overview of basic syntax features:
242
+
243
+ - Tabstops are snippet parts meant for interactive editing at their location.
244
+ They are denoted as `$1`, `$2`, etc.
245
+ Navigating between them is called "jumping" and is done in numerical order
246
+ of tabstop identifiers by pressing special keys: <C-l> and <C-h> to jump
247
+ to next and previous tabstop respectively.
248
+ Special tabstop `$0` is called "final tabstop": it is used to decide when
249
+ snippet session is automatically stopped and is visited last during jumping.
250
+
251
+ Example: `T1=$1 T2=$2 T0=$0` is expanded as `T1= T2= T0=` with three tabstops.
252
+
253
+ - Tabstop can have placeholder: a text used if tabstop is not yet edited.
254
+ Text is preserved if no editing is done. It follows this same syntax, which
255
+ means it can itself contain tabstops with placeholders (i.e. be nested).
256
+ Tabstop with placeholder is denoted as `${1:placeholder}` (`$1` is `${1:}`).
257
+
258
+ Example: `T1=${1:text} T2=${2:<$1>}` is expanded as `T1=text T2=<text>`;
259
+ typing `x` at first placeholder results in `T1=x T2=<x>`;
260
+ jumping once and typing `y` results in `T1=x T2=y`.
261
+
262
+ - There can be several tabstops with same identifier. They are linked and
263
+ updated in sync during text editing. Can also have different placeholders;
264
+ they are forced to be the same as in the first (from left to right) tabstop.
265
+
266
+ Example: `T1=${1:text} T1=$1` is expanded as `T1=text T1=text`;
267
+ typing `x` at first placeholder results in `T1=x T1=x`.
268
+
269
+ - Tabstop can also have choices: suggestions about tabstop text. It is denoted
270
+ as `${1|a,b,c|}`. First choice is used as placeholder.
271
+
272
+ Example: `T1=${1|left,right|}` is expanded as `T1=left`.
273
+
274
+ - Variables can be used to automatically insert text without user interaction.
275
+ As tabstops, each one can have a placeholder which is used if variable is
276
+ not defined. There is a special set of variables describing editor state.
277
+
278
+ Example: `V1=$TM_FILENAME V2=${NOTDEFINED:placeholder}` is expanded as
279
+ `V1=current-file-basename V2=placeholder`.
280
+
281
+ What's different from LSP specification:
282
+ - Special set of variables is wider and is taken from VSCode specification:
283
+ https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables
284
+ Exceptions are `BLOCK_COMMENT_START` and `BLOCK_COMMENT_END` as Neovim doesn't
285
+ provide this information.
286
+ - Variable `TM_SELECTED_TEXT` is resolved as contents of |quote_quote| register.
287
+ It assumes that text is put there prior to expanding. For example, visually
288
+ select, press |c|, type prefix, and expand.
289
+ See |MiniSnippets-examples| for how to adjust this.
290
+ - Environment variables are recognized and supported: `V1=$VIMRUNTIME` will
291
+ use an actual value of |$VIMRUNTIME|.
292
+ - Variable transformations are not supported during snippet session. It would
293
+ require interacting with ECMAScript-like regular expressions for which there
294
+ is no easy way in Neovim. It may change in the future.
295
+ Transformations are recognized during parsing, though, with some exceptions:
296
+ - The `}` inside `if` of `${1:?if:else}` needs escaping (for technical reasons).
297
+
298
+ There is a |MiniSnippets.parse()| function for programmatically parsing
299
+ snippet body into a comprehensible data structure.
300
+
301
+ # Expand ~
302
+
303
+ Using snippets is done via what is called "expanding". It goes like this:
304
+ - Type snippet prefix or its recognizable part.
305
+ - Press <C-j> to expand. It will perform the following steps:
306
+ - Prepare available snippets in current context (buffer + local language).
307
+ This allows snippet setup to have general function loaders which return
308
+ different snippets in different contexts.
309
+ - Match text to the left of cursor with available prefixes. It first tries
310
+ to do exact match and falls back to fuzzy matching.
311
+ - If there are several matches, use `vim.ui.select()` to choose one.
312
+ - Insert single matching snippet. If snippet contains tabstops, start
313
+ snippet session.
314
+
315
+ For more details about each step see:
316
+ - |MiniSnippets.default_prepare()|
317
+ - |MiniSnippets.default_match()|
318
+ - |MiniSnippets.default_select()|
319
+ - |MiniSnippets.default_insert()|
320
+
321
+ Snippet session allows interactive editing at tabstop locations:
322
+
323
+ - All tabstop locations are visualized depending on tabstop "state" (whether
324
+ it is current/visited/unvisited/final and whether it was already edited).
325
+ Empty tabstops are visualized with inline virtual text ("•"/"∎" for
326
+ regular/final tabstops). It is removed after session is stopped.
327
+
328
+ - Start session at first tabstop. Type text to replace placeholder.
329
+ When finished with current tabstop, jump to next with <C-l>. Repeat.
330
+ If changed mind about some previous tabstop, jump back with <C-h>.
331
+ Jumping also wraps around the edge (first tabstop is next after final).
332
+
333
+ - If tabstop has choices, use <C-n> / <C-p> to select next / previous item.
334
+
335
+ - Starting another snippet session while there is an active one is allowed.
336
+ This creates nested sessions: suspend current, start the new one.
337
+ After newly created is stopped, resume the suspended one.
338
+
339
+ - Stop session manually by pressing <C-c> or make it stop automatically:
340
+ if final tabstop is current either make a text edit or exit to Normal mode.
341
+ If snippet doesn't explicitly define final tabstop, it is added at the end
342
+ of the snippet.
343
+
344
+ For more details about snippet session see |MiniSnippets-session|.
345
+
346
+ To select and insert snippets via completion engine (that supports LSP
347
+ completion; like |mini.completion| or |lsp-autocompletion|),
348
+ call |MiniSnippets.start_lsp_server()| after |MiniSnippets.setup()|. This sets up
349
+ an LSP server that matches and provides snippets loaded with |mini.snippets|.
350
+ To match with completion engine, use `start_lsp_server({ match = false })`.
351
+
352
+ # Management ~
353
+
354
+ Out of the box |mini.snippets| doesn't load any snippets, it should be done
355
+ explicitly inside |MiniSnippets.setup()| following |MiniSnippets.config|.
356
+
357
+ The suggested approach to snippet management is to create dedicated files with
358
+ snippet data and load them through function loaders in `config.snippets`.
359
+ See |MiniSnippets-examples| for basic (yet capable) snippet management config.
360
+
361
+ ## File specification ~
362
+ *MiniSnippets-file-specification*
363
+
364
+ General idea of supported files is to have at least out of the box experience
365
+ with common snippet collections. Namely "rafamadriz/friendly-snippets".
366
+ The following files are supported:
367
+
368
+ - Extensions:
369
+ - Read/decoded as JSON object (|vim.json.decode()|): `*.json`, `*.code-snippets`
370
+ - Executed as Lua file (|dofile()|) and uses returned value: `*.lua`
371
+
372
+ - Content:
373
+ - Dict-like: object in JSON; returned table in Lua; no order guarantees.
374
+ - Array-like: array in JSON; returned array table in Lua; preserves order.
375
+
376
+ Example of file content with a single snippet:
377
+ - Lua dict-like: `return { name = { prefix = 't', body = 'Text' } }`
378
+ - Lua array-like: `return { { prefix = 't', body = 'Text', desc = 'name' } }`
379
+ - JSON dict-like: `{ "name": { "prefix": "t", "body": "Text" } }`
380
+ - JSON array-like: `[ { "prefix": "t", "body": "Text", "desc": "name" } ]`
381
+
382
+ Notes:
383
+ - There is no built-in support for VSCode-like "package.json" files. Define
384
+ structure manually in |MiniSnippets.setup()| via built-in or custom loaders.
385
+ - There is no built-in support for `scope` field of snippet data. Snippets are
386
+ expected to be manually separated into smaller files and loaded on demand.
387
+
388
+ For supported snippet syntax see |MiniSnippets-syntax-specification|.
389
+
390
+ ## General advice ~
391
+
392
+ - Put files in "snippets" subdirectory of any path in |'runtimepath'| (like
393
+ `$XDG_CONFIG_HOME/nvim/snippets/global.json`).
394
+ This is compatible with |MiniSnippets.gen_loader.from_runtime()| and
395
+ example from |MiniSnippets-examples|.
396
+ - Prefer `*.json` files with dict-like content if you want more cross platform
397
+ setup. Otherwise use `*.lua` files with array-like content.
398
+ - To implement "dynamic snippet" that changes data (usually <body>) depending
399
+ on the context, use `*.lua` file with function returning snippet data.
400
+ It should be an element in the output table (dict or array like).
401
+
402
+ # Demo ~
403
+
404
+ The best way to grasp the design of snippet management and expansion is to
405
+ try them out yourself. Here are steps for a basic demo:
406
+ - Create `snippets/global.json` file in the config directory with the content: >json
407
+
408
+ {
409
+ "Basic": { "prefix": "ba", "body": "T1=$1 T2=$2 T0=$0" },
410
+ "Placeholders": { "prefix": "pl", "body": "T1=${1:aa}\nT2=${2:<$1>}" },
411
+ "Choices": { "prefix": "ch", "body": "T1=${1|a,b|} T2=${2|c,d|}" },
412
+ "Linked": { "prefix": "li", "body": "T1=$1\n\tT1=$1" },
413
+ "Variables": { "prefix": "va", "body": "Runtime: $VIMRUNTIME\n" },
414
+ "Complex": {
415
+ "prefix": "co",
416
+ "body": [ "T1=${1:$RANDOM}", "T3=${3:$1_${2:$1}}", "T2=$2" ]
417
+ }
418
+ }
419
+ <
420
+ - Set up |mini.snippets| as recommended in |MiniSnippets-examples|.
421
+ - Open Neovim. Type each snippet prefix and press <C-j> (even if there is
422
+ still active session). Explore from there.
423
+
424
+ ------------------------------------------------------------------------------
425
+ *MiniSnippets-examples*
426
+ # Basic snippet management config ~
427
+
428
+ Example of snippet management setup that should cover most cases: >lua
429
+
430
+ -- Setup
431
+ local gen_loader = require('mini.snippets').gen_loader
432
+ require('mini.snippets').setup({
433
+ snippets = {
434
+ -- Load custom file with global snippets first
435
+ gen_loader.from_file('~/.config/nvim/snippets/global.json'),
436
+
437
+ -- Load snippets based on current language by reading files from
438
+ -- `snippets/` subdirectories from 'runtimepath' directories.
439
+ gen_loader.from_lang(),
440
+ },
441
+ })
442
+ <
443
+ This setup allows having single file with custom "global" snippets (will be
444
+ present in every buffer) and snippets which will be loaded based on the local
445
+ language (see |MiniSnippets.gen_loader.from_lang()|).
446
+
447
+ Create language snippets manually (by creating and populating
448
+ `$XDG_CONFIG_HOME/nvim/snippets/lua.json` file) or by installing dedicated
449
+ snippet collection plugin (like `rafamadriz/friendly-snippets`).
450
+
451
+ Note: all built-in loaders and |MiniSnippets.read_file()| cache their output
452
+ by default. It means that after a file is first read, changing it won't have
453
+ effect during current Neovim session. See |MiniSnippets.gen_loader| about how
454
+ to reset cache if necessary.
455
+
456
+ # Select from all available snippets in current context ~
457
+
458
+ With |MiniSnippets.default_match()|, expand snippets (<C-j> by default) at line
459
+ start or after whitespace. To be able to always select from all current
460
+ context snippets, make mapping similar to the following: >lua
461
+
462
+ local rhs = function() MiniSnippets.expand({ match = false }) end
463
+ vim.keymap.set('i', '<C-g><C-j>', rhs, { desc = 'Expand all' })
464
+ <
465
+ # "Supertab"-like <Tab> / <S-Tab> mappings ~
466
+
467
+ This module intentionally by default uses separate keys to expand and jump as
468
+ it enables cleaner use of nested sessions. Here is an example of setting up
469
+ custom <Tab> to "expand or jump" and <S-Tab> to "jump to previous": >lua
470
+
471
+ local snippets = require('mini.snippets')
472
+ local match_strict = function(snips)
473
+ -- Do not match with whitespace to cursor's left
474
+ return snippets.default_match(snips, { pattern_fuzzy = '%S+' })
475
+ end
476
+ snippets.setup({
477
+ -- ... Set up snippets ...
478
+ mappings = { expand = '', jump_next = '', jump_prev = '' },
479
+ expand = { match = match_strict },
480
+ })
481
+ local expand_or_jump = function()
482
+ local can_expand = #MiniSnippets.expand({ insert = false }) > 0
483
+ if can_expand then vim.schedule(MiniSnippets.expand); return '' end
484
+ local is_active = MiniSnippets.session.get() ~= nil
485
+ if is_active then MiniSnippets.session.jump('next'); return '' end
486
+ return '\t'
487
+ end
488
+ local jump_prev = function() MiniSnippets.session.jump('prev') end
489
+ vim.keymap.set('i', '<Tab>', expand_or_jump, { expr = true })
490
+ vim.keymap.set('i', '<S-Tab>', jump_prev)
491
+ <
492
+ # Stop session immediately after jumping to final tabstop ~
493
+
494
+ Utilize a dedicated |MiniSnippets-events|: >lua
495
+
496
+ local fin_stop = function(args)
497
+ if args.data.tabstop_to == '0' then MiniSnippets.session.stop() end
498
+ end
499
+ local au_opts = { pattern = 'MiniSnippetsSessionJump', callback = fin_stop }
500
+ vim.api.nvim_create_autocmd('User', au_opts)
501
+ <
502
+ # Stop all sessions on Normal mode exit ~
503
+
504
+ Use |ModeChanged| and |MiniSnippets-events| events: >lua
505
+
506
+ local make_stop = function()
507
+ local au_opts = { pattern = '*:n', once = true }
508
+ au_opts.callback = function()
509
+ while MiniSnippets.session.get() do
510
+ MiniSnippets.session.stop()
511
+ end
512
+ end
513
+ vim.api.nvim_create_autocmd('ModeChanged', au_opts)
514
+ end
515
+ local opts = { pattern = 'MiniSnippetsSessionStart', callback = make_stop }
516
+ vim.api.nvim_create_autocmd('User', opts)
517
+ <
518
+ # Customize variable evaluation ~
519
+
520
+ Create environment variables and `config.expand.insert` wrapper: >lua
521
+
522
+ -- Use evnironment variables with value is same for all snippet sessions
523
+ vim.loop.os_setenv('USERNAME', 'user')
524
+
525
+ -- Compute custom lookup for variables with dynamic values
526
+ local insert_with_lookup = function(snippet)
527
+ local lookup = {
528
+ TM_SELECTED_TEXT = table.concat(vim.fn.getreg('a', true, true), '\n'),
529
+ }
530
+ return MiniSnippets.default_insert(snippet, { lookup = lookup })
531
+ end
532
+
533
+ require('mini.snippets').setup({
534
+ -- ... Set up snippets ...
535
+ expand = { insert = insert_with_lookup },
536
+ })
537
+ <
538
+ # Using Neovim's built-ins to insert snippet ~
539
+
540
+ Define custom `expand.insert` in |MiniSnippets.config| and mappings: >lua
541
+
542
+ require('mini.snippets').setup({
543
+ -- ... Set up snippets ...
544
+ expand = {
545
+ insert = function(snippet, _) vim.snippet.expand(snippet.body) end
546
+ }
547
+ })
548
+ -- Make jump mappings or skip to use built-in <Tab>/<S-Tab> in Neovim>=0.11
549
+ local jump_next = function()
550
+ if vim.snippet.active({direction = 1}) then return vim.snippet.jump(1) end
551
+ end
552
+ local jump_prev = function()
553
+ if vim.snippet.active({direction = -1}) then vim.snippet.jump(-1) end
554
+ end
555
+ vim.keymap.set({ 'i', 's' }, '<C-l>', jump_next)
556
+ vim.keymap.set({ 'i', 's' }, '<C-h>', jump_prev)
557
+ <
558
+ ------------------------------------------------------------------------------
559
+ *MiniSnippets.setup()*
560
+ `MiniSnippets.setup`({config})
561
+ Module setup
562
+
563
+ Parameters ~
564
+ {config} `(table|nil)` Module config table. See |MiniSnippets.config|.
565
+
566
+ Usage ~
567
+ >lua
568
+ require('mini.snippets').setup({}) -- replace {} with your config table
569
+ -- needs `snippets` field present
570
+ <
571
+ ------------------------------------------------------------------------------
572
+ *MiniSnippets.config*
573
+ `MiniSnippets.config`
574
+ Defaults ~
575
+ >lua
576
+ MiniSnippets.config = {
577
+ -- Array of snippets and loaders (see |MiniSnippets.config| for details).
578
+ -- Nothing is defined by default. Add manually to have snippets to match.
579
+ snippets = {},
580
+
581
+ -- Module mappings. Use `''` (empty string) to disable one.
582
+ mappings = {
583
+ -- Expand snippet at cursor position. Created globally in Insert mode.
584
+ expand = '<C-j>',
585
+
586
+ -- Interact with default `expand.insert` session.
587
+ -- Created for the duration of active session(s)
588
+ jump_next = '<C-l>',
589
+ jump_prev = '<C-h>',
590
+ stop = '<C-c>',
591
+ },
592
+
593
+ -- Functions describing snippet expansion. If `nil`, default values
594
+ -- are `MiniSnippets.default_<field>()`.
595
+ expand = {
596
+ -- Resolve raw config snippets at context
597
+ prepare = nil,
598
+ -- Match resolved snippets at cursor position
599
+ match = nil,
600
+ -- Possibly choose among matched snippets
601
+ select = nil,
602
+ -- Insert selected snippet
603
+ insert = nil,
604
+ },
605
+ }
606
+ <
607
+ # Loaded snippets ~
608
+
609
+ `config.snippets` is an array containing snippet data which can be: snippet
610
+ table, function loader, or (however deeply nested) array of snippet data.
611
+
612
+ Snippet is a table with the following fields:
613
+
614
+ - <prefix> `(string|table|nil)` - string used to match against current text.
615
+ If array, all strings should be used as separate prefixes.
616
+ - <body> `(string|table|nil)` - content of a snippet which should follow
617
+ the |MiniSnippets-syntax-specification|. Array is concatenated with `"\n"`.
618
+ - <desc> `(string|table|nil)` - description of snippet. Can be used to display
619
+ snippets in a more human readable form. Array is concatenated with `"\n"`.
620
+
621
+ Function loaders are expected to be called with single `context` table argument
622
+ (containing any data about current context) and return same as `config.snippets`
623
+ data structure.
624
+
625
+ `config.snippets` is resolved with `config.prepare` on every expand.
626
+ See |MiniSnippets.default_prepare()| for how it is done by default.
627
+
628
+ For a practical example see |MiniSnippets-examples|.
629
+ Here is an illustration of `config.snippets` customization capabilities: >lua
630
+
631
+ local gen_loader = require('mini.snippets').gen_loader
632
+ require('mini.snippets').setup({
633
+ snippets = {
634
+ -- Load custom file with global snippets first (order matters)
635
+ gen_loader.from_file('~/.config/nvim/snippets/global.json'),
636
+
637
+ -- Or add them here explicitly
638
+ { prefix='cdate', body='$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE' },
639
+
640
+ -- Load snippets based on current language by reading files from
641
+ -- `snippets/` subdirectories from 'runtimepath' directories.
642
+ gen_loader.from_lang(),
643
+
644
+ -- Load project-local snippets with `gen_loader.from_file()`
645
+ -- and relative path (file doesn't have to be present)
646
+ gen_loader.from_file('.vscode/project.code-snippets'),
647
+
648
+ -- Custom loader for language-specific project-local snippets
649
+ function(context)
650
+ local rel_path = '.vscode/' .. context.lang .. '.code-snippets'
651
+ if vim.fn.filereadable(rel_path) == 0 then return end
652
+ return MiniSnippets.read_file(rel_path)
653
+ end,
654
+
655
+ -- Ensure that some prefixes are not used (as there is no `body`)
656
+ { prefix = { 'bad', 'prefix' } },
657
+ }
658
+ })
659
+ <
660
+ # Mappings ~
661
+
662
+ `config.mappings` describes which mappings are automatically created.
663
+
664
+ `mappings.expand` is created globally in Insert mode and is used to expand
665
+ snippet at cursor. Use |MiniSnippets.expand()| for custom mappings.
666
+
667
+ `mappings.jump_next`, `mappings.jump_prev`, and `mappings.stop` are created for
668
+ the duration of active snippet session(s) from |MiniSnippets.default_insert()|.
669
+ Used to jump to next/previous tabstop and stop active session respectively.
670
+ Use |MiniSnippets.session.jump()| and |MiniSnippets.session.stop()| for custom
671
+ Insert mode mappings.
672
+ Note: do not use `"<C-n>"` or `"<C-p>"` for any action as they conflict with
673
+ built-in completion: it forces them to mean "change focus to next/previous
674
+ completion item". This matters more frequently than when there is a tabstop
675
+ with choices due to how this module handles built-in completion during jumps.
676
+
677
+ # Expand ~
678
+
679
+ `config.expand` defines expand steps (see |MiniSnippets-glossary|), either after
680
+ pressing `mappings.expand` or starting manually via |MiniSnippets.expand()|.
681
+
682
+ `expand.prepare` is a function that takes `raw_snippets` in the form of
683
+ `config.snippets` and should return a plain array of snippets (as described
684
+ in |MiniSnippets-glossary|). Will be called on every |MiniSnippets.expand()| call.
685
+ If returns second value, it will be used as context for warning messages.
686
+ Default: |MiniSnippets.default_prepare()|.
687
+
688
+ `expand.match` is a function that takes `expand.prepare` output and returns
689
+ an array of matched snippets: one or several snippets user might intend to
690
+ eventually insert. Should sort matches in output from best to worst.
691
+ Entries can contain `region` field with current buffer region used to do
692
+ the match; usually it needs to be removed (similar to how |ins-completion|
693
+ and |abbreviations| work).
694
+ Default: |MiniSnippets.default_match()|
695
+
696
+ `expand.select` is a function that takes output of `expand.match` and function
697
+ that inserts snippet (and also ensures Insert mode and removes snippet's match
698
+ region). Should allow user to perform interactive snippet selection and
699
+ insert the chosen one. Designed to be compatible with |vim.ui.select()|.
700
+ Called for any non-empty `expand.match` output (even with single entry).
701
+ Default: |MiniSnippets.default_select()|
702
+
703
+ `expand.insert` is a function that takes single snippet table as input and
704
+ inserts snippet at cursor position. This is a main entry point for adding
705
+ text template to buffer and starting a snippet session.
706
+ If called inside |MiniSnippets.expand()| (which is a usual interactive case),
707
+ all it has to do is insert snippet at cursor position. Ensuring Insert mode
708
+ and removing matched snippet region is done beforehand.
709
+ Default: |MiniSnippets.default_insert()|
710
+
711
+ Illustration of `config.expand` customization: >lua
712
+
713
+ -- Supply extra data as context
714
+ local my_p = function(raw_snippets)
715
+ local _, cont = MiniSnippets.default_prepare({})
716
+ cont.cursor = vim.api.nvim_win_get_cursor()
717
+ return MiniSnippets.default_prepare(raw_snippets, { context = cont })
718
+ end
719
+ -- Perform fuzzy match based only on alphanumeric characters
720
+ local my_m = function(snippets)
721
+ return MiniSnippets.default_match(snippets, { pattern_fuzzy = '%w*' })
722
+ end
723
+ -- Always insert the best matched snippet
724
+ local my_s = function(snippets, insert) return insert(snippets[1]) end
725
+ -- Use different string to show empty tabstop as inline virtual text
726
+ local my_i = function(snippet)
727
+ return MiniSnippets.default_insert(snippet, { empty_tabstop = '$' })
728
+ end
729
+
730
+ require('mini.snippets').setup({
731
+ -- ... Set up snippets ...
732
+ expand = { prepare = my_p, match = my_m, select = my_s, insert = my_i }
733
+ })
734
+ <
735
+ ------------------------------------------------------------------------------
736
+ *MiniSnippets.expand()*
737
+ `MiniSnippets.expand`({opts})
738
+ Expand snippet at cursor position
739
+
740
+ Perform expand steps (see |MiniSnippets-glossary|).
741
+ Initial raw snippets are taken from `config.snippets` in current buffer.
742
+ Snippets from `vim.b.minisnippets_config` are appended to global snippet array.
743
+
744
+ Parameters ~
745
+ {opts} `(table|nil)` Options. Same structure as `expand` in |MiniSnippets.config|
746
+ and uses its values as default. There are differences in allowed values:
747
+ - Use `match = false` to have all buffer snippets as matches.
748
+ - Use `select = false` to always expand the best match (if any).
749
+ - Use `insert = false` to return all matches without inserting.
750
+
751
+ Note: `opts.insert` is called after ensuring Insert mode, removing snippet's
752
+ match region, and positioning cursor.
753
+
754
+ Return ~
755
+ `(table|nil)` If `insert` is `false`, an array of matched snippets (`expand.match`
756
+ output). Otherwise `nil`.
757
+
758
+ Usage ~
759
+ >lua
760
+ -- Match, maybe select, and insert
761
+ MiniSnippets.expand()
762
+
763
+ -- Match and force expand the best match (if any)
764
+ MiniSnippets.expand({ select = false })
765
+
766
+ -- Use all current context snippets as matches
767
+ MiniSnippets.expand({ match = false })
768
+
769
+ -- Get all matched snippets
770
+ local matches = MiniSnippets.expand({ insert = false })
771
+
772
+ -- Get all current context snippets
773
+ local all = MiniSnippets.expand({ match = false, insert = false })
774
+ <
775
+
776
+ See also ~
777
+ |MiniSnippets.start_lsp_server()| to instead show loaded snippets
778
+ in (auto)completion engines (like |mini.completion|).
779
+
780
+ ------------------------------------------------------------------------------
781
+ *MiniSnippets.gen_loader*
782
+ `MiniSnippets.gen_loader`
783
+ Generate snippet loader
784
+
785
+ This is a table with function elements. Call to actually get a loader.
786
+
787
+ Common features for all produced loaders:
788
+ - Designed to work with |MiniSnippets-file-specification|.
789
+ - Cache output by default, i.e. second and later calls with same input value
790
+ don't read file system. Different loaders from same generator share cache.
791
+ Disable by setting `opts.cache` to `false`.
792
+ To clear all cache, call |MiniSnippets.setup()|. For example:
793
+ `MiniSnippets.setup(MiniSnippets.config)`
794
+ - Use |vim.notify()| to show problems during loading while trying to load as
795
+ much correctly defined snippet data as possible.
796
+ Disable by setting `opts.silent` to `true`.
797
+
798
+ ------------------------------------------------------------------------------
799
+ *MiniSnippets.gen_loader.from_lang()*
800
+ `MiniSnippets.gen_loader.from_lang`({opts})
801
+ Generate language loader
802
+
803
+ Output loads files from `snippets/` subdirectories of |'runtimepath'| matching
804
+ configured language patterns.
805
+ See |MiniSnippets.gen_loader.from_runtime()| for runtime loading details.
806
+
807
+ Language is taken from <lang> field (if present with string value) of `context`
808
+ argument used in loader calls during "prepare" stage.
809
+ This is compatible with |MiniSnippets.default_prepare()| and most snippet
810
+ collection plugins.
811
+
812
+ Parameters ~
813
+ {opts} `(table|nil)` Options. Possible values:
814
+ - <lang_patterns> `(table)` - map from language to array of runtime patterns
815
+ used to find snippet files, as in |MiniSnippets.gen_loader.from_runtime()|.
816
+ Patterns will be processed in order. With |MiniSnippets.default_prepare()|
817
+ it means if snippets have same prefix, data from later patterns is used.
818
+ To interactively check the current language with default context, execute
819
+ `:=MiniSnippets.default_prepare({})` and see data in the second table.
820
+
821
+ Default pattern array (for non-empty language) is constructed as to read
822
+ `*.json` and `*.lua` files that are:
823
+ - Inside `snippets/` subdirectory named as language (files can be however
824
+ deeply nested).
825
+ - Named as language and is in `snippets/` directory (however deep).
826
+ Example for "lua" language: >lua
827
+ { 'lua/**/*.json', 'lua/**/*.lua', '**/lua.json', '**/lua.lua' }
828
+ <
829
+ Add entry for `""` (empty string) as language to be sourced when `lang`
830
+ context is empty string (which is usually temporary scratch buffers).
831
+
832
+ - <cache> `(boolean)` - whether to use cached output. Default: `true`.
833
+ Note: caching is done per used runtime pattern, not `lang` value to allow
834
+ different `from_lang()` loaders to share cache.
835
+ - <silent> `(boolean)` - whether to hide non-error messages. Default: `false`.
836
+
837
+ Return ~
838
+ `(function)` Snippet loader.
839
+
840
+ Usage ~
841
+ >lua
842
+ -- Adjust language patterns
843
+ local latex_patterns = { 'latex/**/*.json', '**/latex.json' }
844
+ local lang_patterns = {
845
+ tex = latex_patterns, plaintex = latex_patterns,
846
+ -- Recognize special injected language of markdown tree-sitter parser
847
+ markdown_inline = { 'markdown.json' },
848
+ }
849
+ local gen_loader = require('mini.snippets').gen_loader
850
+ require('mini.snippets').setup({
851
+ snippets = {
852
+ gen_loader.from_lang({ lang_patterns = lang_patterns }),
853
+ },
854
+ })
855
+ <
856
+ ------------------------------------------------------------------------------
857
+ *MiniSnippets.gen_loader.from_runtime()*
858
+ `MiniSnippets.gen_loader.from_runtime`({pattern}, {opts})
859
+ Generate runtime loader
860
+
861
+ Output loads files which match `pattern` inside `snippets/` directories from
862
+ |'runtimepath'|. This is useful to simultaneously read several similarly
863
+ named files from different sources. Order from |'runtimepath'| is preserved.
864
+
865
+ Typical case is loading snippets for a language from files like `xxx.{json,lua}`
866
+ but located in different `snippets/` directories inside |'runtimepath'|.
867
+ - `<config>`/snippets/lua.json - manually curated snippets in user config.
868
+ - `<path/to/installed/plugin>`/snippets/lua.json - from installed plugin.
869
+ - `<config>`/after/snippets/lua.json - used to adjust snippets from plugins.
870
+ For example, remove some snippets by using prefixes and no body.
871
+
872
+ Parameters ~
873
+ {pattern} `(string)` Pattern of files to read. Can have wildcards as described
874
+ in |nvim_get_runtime_file()|. Example for "lua" language: `'lua.{json,lua}'`.
875
+ {opts} `(table|nil)` Options. Possible fields:
876
+ - <all> `(boolean)` - whether to load from all matching runtime files.
877
+ Default: `true`.
878
+ - <cache> `(boolean)` - whether to use cached output. Default: `true`.
879
+ Note: caching is done per `pattern` value, which assumes that both
880
+ |'runtimepath'| value and snippet files do not change during Neovim session.
881
+ Caching this way gives significant speed improvement by reducing the need
882
+ to traverse file system on every snippet expand.
883
+ - <silent> `(boolean)` - whether to hide non-error messages. Default: `false`.
884
+
885
+ Return ~
886
+ `(function)` Snippet loader.
887
+
888
+ ------------------------------------------------------------------------------
889
+ *MiniSnippets.gen_loader.from_file()*
890
+ `MiniSnippets.gen_loader.from_file`({path}, {opts})
891
+ Generate single file loader
892
+
893
+ Output is a thin wrapper around |MiniSnippets.read_file()| which will skip
894
+ warning if file is absent (other messages are still shown). Use it to load
895
+ file which is not guaranteed to exist (like project-local snippets).
896
+
897
+ Parameters ~
898
+ {path} `(string)` Same as in |MiniSnippets.read_file()|.
899
+ {opts} `(table|nil)` Same as in |MiniSnippets.read_file()|.
900
+
901
+ Return ~
902
+ `(function)` Snippet loader.
903
+
904
+ ------------------------------------------------------------------------------
905
+ *MiniSnippets.read_file()*
906
+ `MiniSnippets.read_file`({path}, {opts})
907
+ Read file with snippet data
908
+
909
+ Parameters ~
910
+ {path} `(string)` Path to file with snippets. Can be relative.
911
+ See |MiniSnippets-file-specification| for supported file formats.
912
+ {opts} `(table|nil)` Options. Possible fields:
913
+ - <cache> `(boolean)` - whether to use cached output. Default: `true`.
914
+ Note: Caching is done per full path only after successful reading.
915
+ - <silent> `(boolean)` - whether to hide non-error messages. Default: `false`.
916
+
917
+ Return ~
918
+ `(table|nil)` Array of snippets or `nil` if failed (also warn with |vim.notify()|
919
+ about the reason).
920
+
921
+ ------------------------------------------------------------------------------
922
+ *MiniSnippets.default_prepare()*
923
+ `MiniSnippets.default_prepare`({raw_snippets}, {opts})
924
+ Default prepare
925
+
926
+ Normalize raw snippets (as in `snippets` from |MiniSnippets.config|) based on
927
+ supplied context:
928
+ - Traverse and flatten nested arrays. Function loaders are executed with
929
+ `opts.context` as argument and output is processed recursively.
930
+ - Ensure unique non-empty prefixes: later ones completely override earlier
931
+ ones (similar to how |ftplugin| and similar runtime design behave).
932
+ Empty string prefixes are all added (to allow inserting without matching).
933
+ - Transform and infer fields:
934
+ - Multiply array `prefix` into several snippets with same body/description.
935
+ Infer absent `prefix` as empty string.
936
+ - Concatenate array `body` with `"\n"`. Do not infer absent `body` to have
937
+ it remove previously added snippet with the same prefix.
938
+ - Concatenate array `desc` with `"\n"`. Infer `desc` field from `description`
939
+ (for compatibility) or `body` fields, in that order.
940
+ - Sort output by prefix.
941
+
942
+ Unlike |MiniSnippets.gen_loader| entries, there is no output caching. This
943
+ avoids duplicating data from `gen_loader` cache and reduces memory usage.
944
+ It also means that every |MiniSnippets.expand()| call prepares snippets, which
945
+ is usually fast enough. If not, consider manual caching: >lua
946
+
947
+ local cache = {}
948
+ local prepare_cached = function(raw_snippets)
949
+ local _, cont = MiniSnippets.default_prepare({})
950
+ local id = 'buf=' .. cont.buf_id .. ',lang=' .. cont.lang
951
+ if cache[id] then return unpack(vim.deepcopy(cache[id])) end
952
+ local snippets = MiniSnippets.default_prepare(raw_snippets)
953
+ cache[id] = vim.deepcopy({ snippets, cont })
954
+ return snippets, cont
955
+ end
956
+ <
957
+ Parameters ~
958
+ {raw_snippets} `(table)` Array of snippet data as from |MiniSnippets.config|.
959
+ {opts} `(table|nil)` Options. Possible fields:
960
+ - <context> `(any)` - Context used as an argument for callable snippet data.
961
+ Default: table with <buf_id> (current buffer identifier) and <lang> (local
962
+ language) fields. Language is computed from tree-sitter parser at cursor
963
+ (allows different snippets in injected languages), |'filetype'| otherwise.
964
+
965
+ Return ~
966
+ `(...)` Array of snippets and supplied context (default if none was supplied).
967
+
968
+ ------------------------------------------------------------------------------
969
+ *MiniSnippets.default_match()*
970
+ `MiniSnippets.default_match`({snippets}, {opts})
971
+ Default match
972
+
973
+ Match snippets based on the line before cursor.
974
+
975
+ Tries two matching approaches consecutively:
976
+ - Find exact snippet prefix (if present and non-empty) to the left of cursor.
977
+ It should also be preceded with a byte that matches `pattern_exact_boundary`.
978
+ In case of any match, return the one with the longest prefix.
979
+ - Match fuzzily snippet prefixes against the base (text to the left of cursor
980
+ extracted via `opts.pattern_fuzzy`). Matching is done via |matchfuzzy()|.
981
+ Empty base results in all snippets being matched. Return all fuzzy matches.
982
+
983
+ Parameters ~
984
+ {snippets} `(table)` Array of snippets which can be matched.
985
+ {opts} `(table|nil)` Options. Possible fields:
986
+ - <pattern_exact_boundary> `(string)` - Lua pattern for the byte to the left
987
+ of exact match to accept it. Line start is matched against empty string;
988
+ use `?` quantifier to allow it as boundary.
989
+ Default: `[%s%p]?` (accept only whitespace and punctuation as boundary,
990
+ allow match at line start).
991
+ Example: prefix "l" matches in lines `l`, `_l`, `x l`; but not `1l`, `ll`.
992
+ - <pattern_fuzzy> `(string)` - Lua pattern to extract base to the left of
993
+ cursor for fuzzy matching. Supply empty string to skip this step.
994
+ Default: `'%S*'` (as many as possible non-whitespace; allow empty string).
995
+
996
+ Return ~
997
+ `(table)` Array of matched snippets ordered from best to worst match.
998
+
999
+ Usage ~
1000
+ >lua
1001
+ -- Accept any exact match
1002
+ MiniSnippets.default_match(snippets, { pattern_exact_boundary = '.?' })
1003
+
1004
+ -- Perform fuzzy match based only on alphanumeric characters
1005
+ MiniSnippets.default_match(snippets, { pattern_fuzzy = '%w*' })
1006
+ <
1007
+ ------------------------------------------------------------------------------
1008
+ *MiniSnippets.default_select()*
1009
+ `MiniSnippets.default_select`({snippets}, {insert}, {opts})
1010
+ Default select
1011
+
1012
+ Show snippets as |vim.ui.select()| items and insert the chosen one.
1013
+ For best interactive experience requires `vim.ui.select()` to work from Insert
1014
+ mode (be properly called and restore Insert mode after choice).
1015
+ This is the case for at least |MiniPick.ui_select()| and Neovim's default.
1016
+
1017
+ Parameters ~
1018
+ {snippets} `(table)` Array of snippets (as an output of `config.expand.match`).
1019
+ {insert} `(function|nil)` Function to insert chosen snippet (passed as the only
1020
+ argument). Expected to remove snippet's match region (if present as a field)
1021
+ and ensure proper cursor position in Insert mode.
1022
+ Default: |MiniSnippets.default_insert()|.
1023
+ {opts} `(table|nil)` Options. Possible fields:
1024
+ - <insert_single> `(boolean)` - whether to skip |vim.ui.select()| for `snippets`
1025
+ with a single entry and insert it directly. Default: `true`.
1026
+
1027
+ ------------------------------------------------------------------------------
1028
+ *MiniSnippets.default_insert()*
1029
+ `MiniSnippets.default_insert`({snippet}, {opts})
1030
+ Default insert
1031
+
1032
+ Prepare for snippet insert and do it:
1033
+ - Ensure Insert mode.
1034
+ - Delete snippet's match region (if present as <region> field). Ensure cursor.
1035
+ - Parse snippet body with |MiniSnippets.parse()| and enabled `normalize`.
1036
+ In particular, evaluate variables, ensure final node presence and same
1037
+ text for nodes with same tabstops. Stop if not able to.
1038
+ - Insert snippet at cursor:
1039
+ - Add snippet's text. Lines are split at "\n".
1040
+ Indent and left comment leaders (inferred from |'commentstring'| and
1041
+ |'comments'|) of current line are repeated on the next.
1042
+ Tabs ("\t") are expanded according to |'expandtab'| and |'shiftwidth'|.
1043
+ - If there is an actionable tabstop (not final), start snippet session.
1044
+
1045
+ # Session life cycle ~
1046
+ *MiniSnippets-session*
1047
+
1048
+ - Start with cursor at first tabstop. If there are linked tabstops, cursor
1049
+ is placed at start of reference node (see |MiniSnippets-glossary|).
1050
+ All tabstops are visualized with dedicated highlight groups (see "Highlight
1051
+ groups" section in |mini.snippets|).
1052
+ Empty tabstops are visualized with inline virtual text ("•"/"∎" for
1053
+ regular/final tabstops) meaning that it is not an actual text in the
1054
+ buffer and will be removed after session is stopped.
1055
+
1056
+ - Decide whether you want to replace the placeholder. If not, jump to next or
1057
+ previous tabstop. If yes, edit it: add new and/or delete already added text.
1058
+ While doing so, several things happen in all linked tabstops (if any):
1059
+
1060
+ - After first typed character the placeholder is removed and highlighting
1061
+ changes from `MiniSnippetsCurrentReplace` to `MiniSnippetsCurrent`.
1062
+ - Text in all tabstop nodes is synchronized with the reference one.
1063
+ Relative indent of reference tabstop's text is preserved: all but first
1064
+ lines in linked tabstops are reindented based on the first line indent.
1065
+ Note: text sync is forced only for current tabstop (for performance).
1066
+
1067
+ - Jump with <C-l> / <C-h> to next / previous tabstop. Exact keys can be
1068
+ adjusted in |MiniSnippets.config| `mappings`.
1069
+ See |MiniSnippets.session.jump()| for jumping details.
1070
+
1071
+ - If tabstop has choices, all of them are shown after each jump and deleting
1072
+ tabstop text. It is done with |complete()|, so use <C-n> / <C-p> to select
1073
+ next / previous choice. Type text to narrow down the list.
1074
+ Works best when |'completeopt'| option contains `menuone` and `noselect` flags.
1075
+ Note: deleting character hides the list due to how |complete()| works;
1076
+ delete whole tabstop text (for example with one or more |i_CTRL-W|) for
1077
+ full list to reappear.
1078
+
1079
+ - Nest another session by expanding snippet in the same way as without
1080
+ active session (can be even done in another buffer). If snippet has no
1081
+ actionable tabstop, text is just inserted. Otherwise start nested session:
1082
+
1083
+ - Suspend current session: hide highlights, keep text change tracking.
1084
+ - Start new session and act as if it is the only one (edit/jump/nest).
1085
+ - When ready (possibly after even more nested sessions), stop the session.
1086
+ This will resume previous one: sync text for its current tabstop and
1087
+ show highlighting.
1088
+ The experience of text synchronization only after resuming session is
1089
+ similar to how editing in |visual-block| mode works.
1090
+ Nothing else (like cursor/mode/buffer) is changed for a smoother
1091
+ automated session stop.
1092
+
1093
+ Notes about the choice of the "session stack" approach to nesting over more
1094
+ common "merge into single session" approach:
1095
+ - Does not overload with highlighting.
1096
+ - Allows nested sessions in different buffers.
1097
+ - Doesn't need a complex logic of injecting one session into another.
1098
+
1099
+ - Repeat edit/jump/nest steps any number of times.
1100
+
1101
+ - Stop. It can be done in two ways:
1102
+
1103
+ - Manually by pressing <C-c> or calling |MiniSnippets.session.stop()|.
1104
+ Exact key can be adjusted in |MiniSnippets.config| `mappings`.
1105
+ - Automatically: any text edit or switching to Normal mode stops session
1106
+ if final tabstop (`$0`) is current. Its presence is ensured after insert.
1107
+ Not stopping session right away after jumping to final mode (as most
1108
+ other snippet plugins do) allows going back to other tabstops in case
1109
+ of a late missed typo. Wrapping around the edge during jumping also
1110
+ helps with that.
1111
+ If current tabstop is not final, exiting into Normal mode for quick edit
1112
+ outside of snippets range (or carefully inside) is fine. Later get back
1113
+ into Insert mode and jump to next tabstop or manually stop session.
1114
+ See |MiniSnippets-examples| for how to set up custom stopping rules.
1115
+
1116
+ Use |MiniSnippets.session.get()| to get data about active/nested session(s).
1117
+ Use |MiniSnippets.session.jump()| / |MiniSnippets.session.stop()| in mappings.
1118
+
1119
+ What is allowed but not officially supported/recommended:
1120
+
1121
+ - Editing text within snippet range but outside of session life cycle. Mostly
1122
+ behaves as expected, but may harm tracking metadata (|extmarks|).
1123
+ In general anything but deleting tabstop range should be OK.
1124
+ Text synchronization of current tabstop would still be active.
1125
+
1126
+ # Events ~
1127
+ *MiniSnippets-events*
1128
+
1129
+ General session activity (autocommand data contains <session> field):
1130
+ - `MiniSnippetsSessionStart` - after a session is started.
1131
+ - `MiniSnippetsSessionStop` - before a session is stopped.
1132
+
1133
+ Nesting session activity (autocommand data contains <session> field):
1134
+ - `MiniSnippetsSessionSuspend` - before a session is suspended.
1135
+ - `MiniSnippetsSessionResume` - after a session is resumed.
1136
+
1137
+ Jumping between tabstops (autocommand data contains <tabstop_from> and
1138
+ <tabstop_new> fields):
1139
+ - `MiniSnippetsSessionJumpPre` - before jumping to a new tabstop.
1140
+ - `MiniSnippetsSessionJump` - after jumping to a new tabstop.
1141
+
1142
+ Parameters ~
1143
+ {snippet} `(table)` Snippet table. Field <body> is mandatory.
1144
+ {opts} `(table|nil)` Options. Possible fields:
1145
+ - <empty_tabstop> `(string)` - used to visualize empty regular tabstops.
1146
+ Default: "•".
1147
+ - <empty_tabstop_final> `(string)` - used to visualize empty final tabstop(s).
1148
+ Default: "∎".
1149
+ - <lookup> `(table)` - passed to |MiniSnippets.parse()|. Use it to adjust
1150
+ how variables are evaluated. Default: `{}`.
1151
+
1152
+ ------------------------------------------------------------------------------
1153
+ *MiniSnippets.session*
1154
+ `MiniSnippets.session`
1155
+ Work with snippet session from |MiniSnippets.default_insert()|
1156
+
1157
+ ------------------------------------------------------------------------------
1158
+ *MiniSnippets.session.get()*
1159
+ `MiniSnippets.session.get`({all})
1160
+ Get data about active session
1161
+
1162
+ Parameters ~
1163
+ {all} `(boolean|nil)` Whether to return array with the whole session stack.
1164
+ Default: `false`.
1165
+
1166
+ Return ~
1167
+ `(table)` Single table with session data (if `all` is `false`) or array of them.
1168
+ Session data contains the following fields:
1169
+ - <buf_id> `(number)` - identifier of session's buffer.
1170
+ - <cur_tabstop> `(string)` - identifier of session's current tabstop.
1171
+ - <extmark_id> `(number)` - |extmark| identifier which track session range.
1172
+ - <insert_args> `(table)` - |MiniSnippets.default_insert()| arguments used to
1173
+ create the session. A table with <snippet> and <opts> fields.
1174
+ - <nodes> `(table)` - parsed array of snippet nodes which is kept up to date
1175
+ during session. Has the structure of a normalized |MiniSnippets.parse()|
1176
+ output, plus every node contains `extmark_id` field with |extmark| identifier
1177
+ which can be used to get data about the current node state.
1178
+ - <ns_id> `(number)` - |namespace| identifier for all session's extmarks.
1179
+ - <tabstops> `(table)` - data about session's tabstops. Fields are string
1180
+ tabstop identifiers and values are tables with the following fields:
1181
+ - <is_visited> `(boolean)` - whether tabstop was visited.
1182
+ - <next> `(string)` - identifier of the next tabstop.
1183
+ - <prev> `(string)` - identifier of the previous tabstop.
1184
+
1185
+ ------------------------------------------------------------------------------
1186
+ *MiniSnippets.session.jump()*
1187
+ `MiniSnippets.session.jump`({direction})
1188
+ Jump to next/previous tabstop
1189
+
1190
+ Make next/previous tabstop be current. Executes the following steps:
1191
+ - Mark current tabstop as visited.
1192
+ - Find the next/previous tabstop id assuming they are sorted as numbers.
1193
+ Tabstop "0" is always last. Search is wrapped around the edges: first and
1194
+ final tabstops are next/previous for one another.
1195
+ - Focus on target tabstop:
1196
+ - Ensure session's buffer is current.
1197
+ - Adjust highlighting of affected nodes.
1198
+ - Set cursor at tabstop's reference node (first node among linked).
1199
+ Cursor is placed on left edge if tabstop has not been edited yet (so
1200
+ typing text replaces placeholder), on right edge otherwise (to update
1201
+ already edited text).
1202
+ - Show all choices for tabstop with choices. Navigating through choices
1203
+ will update tabstop's text.
1204
+
1205
+ Parameters ~
1206
+ {direction} `(string)` One of "next" or "prev".
1207
+
1208
+ ------------------------------------------------------------------------------
1209
+ *MiniSnippets.session.stop()*
1210
+ `MiniSnippets.session.stop`()
1211
+ Stop (only) active session
1212
+
1213
+ To stop all nested sessions use the following code: >lua
1214
+
1215
+ while MiniSnippets.session.get() do
1216
+ MiniSnippets.session.stop()
1217
+ end
1218
+ <
1219
+ ------------------------------------------------------------------------------
1220
+ *MiniSnippets.parse()*
1221
+ `MiniSnippets.parse`({snippet_body}, {opts})
1222
+ Parse snippet
1223
+
1224
+ Parameters ~
1225
+ {snippet_body} `(string|table)` Snippet body as string or array of strings.
1226
+ Should follow |MiniSnippets-syntax-specification|.
1227
+ {opts} `(table|nil)` Options. Possible fields:
1228
+ - <normalize> `(boolean)` - whether to normalize nodes:
1229
+ - Evaluate variable nodes and add output as a `text` field.
1230
+ If variable is not set, `text` field is `nil`.
1231
+ Values from `opts.lookup` are preferred over evaluation output.
1232
+ See |MiniSnippets-syntax-specification| for more info about variables.
1233
+ - Add `text` field for tabstops present in `opts.lookup`.
1234
+ - Ensure every node contains exactly one of `text` or `placeholder` fields.
1235
+ If there are none, add default `placeholder` (one text node with first
1236
+ choice or empty string). If there are both, remove `placeholder` field.
1237
+ - Ensure present final tabstop: append to end if absent.
1238
+ - Ensure that nodes for same tabstop have same placeholder. Use the one
1239
+ from the first node.
1240
+ Default: `false`.
1241
+ - <lookup> `(table)` - map from variable/tabstop (string) name to its value.
1242
+ Default: `{}`.
1243
+
1244
+ Return ~
1245
+ `(table)` Array of nodes. Node is a table with fields depending on node type:
1246
+ - Text node:
1247
+ - <text> `(string)` - node's text.
1248
+ - Tabstop node:
1249
+ - <tabstop> `(string)` - tabstop identifier.
1250
+ - <text> `(string|nil)` - tabstop value (if present in <lookup>).
1251
+ - <placeholder> `(table|nil)` - array of nodes to be used as placeholder.
1252
+ - <choices> `(table|nil)` - array of string choices.
1253
+ - <transform> `(table|nil)` - array of transformation string parts.
1254
+ - Variable node:
1255
+ - <var> `(string)` - variable name.
1256
+ - <text> `(string|nil)` - variable value.
1257
+ - <placeholder> `(table|nil)` - array of nodes to be used as placeholder.
1258
+ - <transform> `(table|nil)` - array of transformation string parts.
1259
+
1260
+ ------------------------------------------------------------------------------
1261
+ *MiniSnippets.start_lsp_server()*
1262
+ `MiniSnippets.start_lsp_server`({opts})
1263
+ Start completion LSP server
1264
+
1265
+ This starts (|vim.lsp.start()|) an LSP server with the purpose of displaying
1266
+ snippets in (auto)completion engines (|mini.completion| in particular).
1267
+ The server:
1268
+ - Only implements `textDocument/completion` method which prepares and matches
1269
+ snippets at cursor (via |MiniSnippets.expand()|).
1270
+ - Auto-attaches to all loaded buffers by default.
1271
+
1272
+ Parameters ~
1273
+ {opts} `(table|nil)` Options. Possible fields:
1274
+ - <before_attach> `(function)` - function executed before every attach to
1275
+ the buffer. Takes buffer id as input and can return `false` (not `nil`) to
1276
+ cancel attaching to the buffer. Default: attach to loaded normal buffers.
1277
+ - <match> `(false|function)` - value of `opts.match` forwarded to
1278
+ the |MiniSnippets.expand()| when computing completion candidates.
1279
+ Supply `false` to not do matching at cursor, return all available snippets
1280
+ in cursor context, and rely on completion engine to match and sort items.
1281
+ Default: `nil` (equivalent to |MiniSnippets.default_match()|).
1282
+ - <server_config> `(table)` - server config to be used as basis for first
1283
+ argument to |vim.lsp.start()| (`cmd` will be overridden). Default: `{}`.
1284
+ - <triggers> `(table)` - array of trigger characters to be used as
1285
+ `completionProvider.triggerCharacters` server capability. Default: `{}`.
1286
+
1287
+ Return ~
1288
+ `(integer|nil)` Identifier of started LSP server.
1289
+
1290
+
1291
+ vim:tw=78:ts=8:noet:ft=help:norl: