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,689 @@
1
+ --- *mini.sessions* Session management
2
+ ---
3
+ --- MIT License Copyright (c) 2021 Evgeni Chasnovski
4
+
5
+ --- Read, write, and delete sessions. Uses |:mksession| (meaning |'sessionoptions'|
6
+ --- is fully respected). This is intended as a drop-in Lua replacement for
7
+ --- [mhinz/vim-startify](https://github.com/mhinz/vim-startify) session management
8
+ --- (works out of the box with sessions created by it). Implements both global
9
+ --- (from configured directory) and local (from current directory) sessions.
10
+ ---
11
+ --- Key design ideas:
12
+ --- - Sessions are represented by readable files (results of applying |:mksession|).
13
+ --- There are two kinds of sessions:
14
+ --- - Global: any file inside a configurable directory.
15
+ --- - Local: configurable file inside current working directory (|getcwd()|).
16
+ ---
17
+ --- - All session files are detected during `MiniSessions.setup()` and during
18
+ --- relevant actions (`read`, `delete`, `select`) with file names as session
19
+ --- names (including possible extension).
20
+ ---
21
+ --- - No automated new session creation. Use |MiniSessions.write()| manually.
22
+ ---
23
+ --- - Store information about detected sessions in separate table
24
+ --- (|MiniSessions.detected|) and operate only on it. Meaning if this information
25
+ --- changes, there will be no effect until next detection. To avoid confusion,
26
+ --- don't directly use |:mksession| / |:source| for writing / reading session files.
27
+ ---
28
+ --- Features:
29
+ --- - Autoread default session (local if detected, else latest written global) if
30
+ --- Neovim was called without intention to show something else.
31
+ ---
32
+ --- - Autowrite currently read session before leaving it (quit Neovim or read
33
+ --- another session).
34
+ ---
35
+ --- - Restart Neovim preserving current session (requires Neovim>=0.12).
36
+ ---
37
+ --- - Configurable severity level of all actions.
38
+ ---
39
+ --- # Setup ~
40
+ ---
41
+ --- This module needs a setup with `require('mini.sessions').setup({})`
42
+ --- (replace `{}` with your `config` table). It will create global Lua table
43
+ --- `MiniSessions` which you can use for scripting or manually (with
44
+ --- `:lua MiniSessions.*`).
45
+ ---
46
+ --- See |MiniSessions.config| for `config` structure and default values.
47
+ ---
48
+ --- This module doesn't benefit from buffer local configuration, so using
49
+ --- `vim.b.minisessions_config` will have no effect here.
50
+ ---
51
+ --- # Disabling ~
52
+ ---
53
+ --- To disable core functionality, set `vim.g.minisessions_disable` (globally) or
54
+ --- `vim.b.minisessions_disable` (for a buffer) to `true`. Considering high
55
+ --- number of different scenarios and customization intentions, writing exact
56
+ --- rules for disabling module's functionality is left to user. See
57
+ --- |mini.nvim-disabling-recipes| for common recipes.
58
+ ---@tag MiniSessions
59
+
60
+ -- Module definition ==========================================================
61
+ local MiniSessions = {}
62
+ local H = {}
63
+
64
+ --- Module setup
65
+ ---
66
+ ---@param config table|nil Module config table. See |MiniSessions.config|.
67
+ ---
68
+ ---@usage >lua
69
+ --- require('mini.sessions').setup() -- use default config
70
+ --- -- OR
71
+ --- require('mini.sessions').setup({}) -- replace {} with your config table
72
+ --- <
73
+ MiniSessions.setup = function(config)
74
+ -- TODO: Remove after Neovim=0.9 support is dropped
75
+ if vim.fn.has('nvim-0.10') == 0 then
76
+ vim.notify(
77
+ '(mini.sessions) Neovim<0.10 is soft deprecated (module works but is not supported).'
78
+ .. " It will be deprecated after the next 'mini.nvim' release (module might not work)."
79
+ .. ' Please update your Neovim version.'
80
+ )
81
+ end
82
+
83
+ -- Export module
84
+ _G.MiniSessions = MiniSessions
85
+
86
+ -- Setup config
87
+ config = H.setup_config(config)
88
+
89
+ -- Apply config
90
+ H.apply_config(config)
91
+
92
+ -- Define behavior
93
+ H.create_autocommands(config)
94
+ end
95
+
96
+ --- Defaults ~
97
+ ---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
98
+ MiniSessions.config = {
99
+ -- Whether to read default session if Neovim opened without file arguments
100
+ autoread = false,
101
+
102
+ -- Whether to write currently read session before leaving it
103
+ autowrite = true,
104
+
105
+ -- Directory where global sessions are stored (use `''` to disable)
106
+ --minidoc_replace_start directory = --<"session" subdir of user data directory from |stdpath()|>,
107
+ directory = vim.fn.stdpath('data') .. '/session',
108
+ --minidoc_replace_end
109
+
110
+ -- File for local session (use `''` to disable)
111
+ file = 'Session.vim',
112
+
113
+ -- Whether to force possibly harmful actions (meaning depends on function)
114
+ force = { read = false, write = true, delete = false },
115
+
116
+ -- Hook functions for actions. Default `nil` means 'do nothing'.
117
+ -- Takes table with active session data as argument.
118
+ hooks = {
119
+ -- Before successful action
120
+ pre = { read = nil, write = nil, delete = nil },
121
+ -- After successful action
122
+ post = { read = nil, write = nil, delete = nil },
123
+ },
124
+
125
+ -- Whether to print session path after action
126
+ verbose = { read = false, write = true, delete = true },
127
+ }
128
+ --minidoc_afterlines_end
129
+
130
+ -- Module data ================================================================
131
+ --- Table of detected sessions. Keys represent session name. Values are tables
132
+ --- with session information that currently has these fields (but subject to
133
+ --- change):
134
+ --- - <modify_time> `(number)` modification time (see |getftime()|) of session file.
135
+ --- - <name> `(string)` name of session (should be equal to table key).
136
+ --- - <path> `(string)` full path to session file.
137
+ --- - <type> `(string)` type of session (`'global'` or `'local'`).
138
+ MiniSessions.detected = {}
139
+
140
+ -- Module functionality =======================================================
141
+ --- Read detected session
142
+ ---
143
+ --- What it does:
144
+ --- - If there is an active session and `autowrite` is `true` in |MiniSessions.config|,
145
+ --- write it with |MiniSessions.write()|.
146
+ --- - Delete all current buffers with |:bwipeout|. This is needed to correctly
147
+ --- restore buffers from target session. If `force` is not `true`, checks
148
+ --- beforehand for unsaved listed buffers and stops if there are any.
149
+ --- - Source session with supplied name.
150
+ ---
151
+ ---@param session_name string|nil Name of detected session file to read. Default:
152
+ --- `nil` for default session: local (if detected) or latest session (see
153
+ --- |MiniSessions.get_latest()|).
154
+ ---@param opts table|nil Table with options. Current allowed keys:
155
+ --- - <force> (whether to delete unsaved buffers; default:
156
+ --- `MiniSessions.config.force.read`).
157
+ --- - <verbose> (whether to print session path after action; default
158
+ --- `MiniSessions.config.verbose.read`).
159
+ --- - <hooks> (a table with <pre> and <post> function hooks to be executed
160
+ --- with session data argument before and after successful read; overrides
161
+ --- `MiniSessions.config.hooks.pre.read` and
162
+ --- `MiniSessions.config.hooks.post.read`).
163
+ MiniSessions.read = function(session_name, opts)
164
+ if H.is_disabled() then return end
165
+
166
+ -- Make sessions up to date
167
+ H.detect_sessions()
168
+ if vim.tbl_count(MiniSessions.detected) == 0 then
169
+ return H.message('There are no detected sessions. Change configuration and rerun `MiniSessions.setup()`.')
170
+ end
171
+
172
+ -- Get session data
173
+ if session_name == nil then
174
+ if MiniSessions.detected[MiniSessions.config.file] ~= nil then
175
+ session_name = MiniSessions.config.file
176
+ else
177
+ session_name = MiniSessions.get_latest()
178
+ end
179
+ end
180
+
181
+ opts = vim.tbl_deep_extend('force', H.default_opts('read'), opts or {})
182
+
183
+ if not H.validate_detected(session_name) then return end
184
+
185
+ local data = MiniSessions.detected[session_name]
186
+
187
+ -- Possibly check for unsaved listed buffers and do nothing if present
188
+ if not opts.force then
189
+ local unsaved_listed_buffers = H.get_unsaved_listed_buffers()
190
+
191
+ if #unsaved_listed_buffers > 0 then
192
+ local buf_list = table.concat(unsaved_listed_buffers, ', ')
193
+ H.error(('There are unsaved listed buffers: %s.'):format(buf_list))
194
+ end
195
+ end
196
+
197
+ -- Write current session to allow proper switching between sessions
198
+ if H.get_this_session() ~= '' and MiniSessions.config.autowrite then
199
+ MiniSessions.write(nil, { force = true, verbose = false })
200
+ end
201
+
202
+ -- Execute 'pre' hook
203
+ H.possibly_execute(opts.hooks.pre, data)
204
+
205
+ -- Wipeout all buffers
206
+ vim.cmd('silent! %bwipeout!')
207
+
208
+ -- Read session file
209
+ local session_path = data.path
210
+ vim.cmd(('silent! source %s'):format(vim.fn.fnameescape(session_path)))
211
+ vim.v.this_session = session_path
212
+
213
+ -- Possibly notify
214
+ if opts.verbose then H.message(('Read session %s'):format(session_path)) end
215
+
216
+ -- Ensure correct detected local session
217
+ H.detect_sessions()
218
+
219
+ -- Execute 'post' hook
220
+ H.possibly_execute(opts.hooks.post, data)
221
+ end
222
+
223
+ --- Write session
224
+ ---
225
+ --- What it does:
226
+ --- - Check if file for supplied session name already exists. If it does and
227
+ --- `force` is not `true`, then stop.
228
+ --- - Write session with |:mksession| to a file named `session_name`. Its
229
+ --- directory is determined based on type of session:
230
+ --- - It is at location |v:this_session| if `session_name` is `nil` and
231
+ --- there is currently read session.
232
+ --- - It is current working directory (|getcwd()|) if `session_name` is equal
233
+ --- to `MiniSessions.config.file` (represents local session).
234
+ --- - It is `MiniSessions.config.directory` otherwise (represents global
235
+ --- session).
236
+ --- - Update |MiniSessions.detected|.
237
+ ---
238
+ ---@param session_name string|nil Name of session file to write. Default: `nil` for
239
+ --- currently read session (|v:this_session|).
240
+ ---@param opts table|nil Table with options. Current allowed keys:
241
+ --- - <force> (whether to ignore existence of session file; default:
242
+ --- `MiniSessions.config.force.write`).
243
+ --- - <verbose> (whether to print session path after action; default
244
+ --- `MiniSessions.config.verbose.write`).
245
+ --- - <hooks> (a table with <pre> and <post> function hooks to be executed
246
+ --- with session data argument before and after successful write; overrides
247
+ --- `MiniSessions.config.hooks.pre.write` and
248
+ --- `MiniSessions.config.hooks.post.write`).
249
+ MiniSessions.write = function(session_name, opts)
250
+ if H.is_disabled() then return end
251
+
252
+ opts = vim.tbl_deep_extend('force', H.default_opts('write'), opts or {})
253
+
254
+ local session_path = H.name_to_path(session_name)
255
+
256
+ if not opts.force and H.is_readable_file(session_path) then
257
+ H.error([[Can't write to existing session when `opts.force` is not `true`.]])
258
+ end
259
+
260
+ local data = H.new_session(session_path)
261
+
262
+ -- Execute 'pre' hook
263
+ H.possibly_execute(opts.hooks.pre, data)
264
+
265
+ -- Make session file
266
+ local command = string.format('mksession%s %s', opts.force and '!' or '', vim.fn.fnameescape(session_path))
267
+ vim.cmd(command)
268
+ data.modify_time = vim.fn.getftime(session_path)
269
+
270
+ -- Update detected sessions
271
+ MiniSessions.detected[data.name] = data
272
+
273
+ -- Update current session
274
+ vim.v.this_session = session_path
275
+
276
+ -- Possibly notify
277
+ if opts.verbose then H.message(('Written session %s'):format(session_path)) end
278
+
279
+ -- Execute 'post' hook
280
+ H.possibly_execute(opts.hooks.post, data)
281
+ end
282
+
283
+ --- Delete detected session
284
+ ---
285
+ --- What it does:
286
+ --- - Check if session name is a current one. If yes and `force` is not `true`,
287
+ --- then stop.
288
+ --- - Delete session.
289
+ --- - Update |MiniSessions.detected|.
290
+ ---
291
+ ---@param session_name string|nil Name of detected session file to delete. Default:
292
+ --- `nil` for name of currently read session (taken from |v:this_session|).
293
+ ---@param opts table|nil Table with options. Current allowed keys:
294
+ --- - <force> (whether to allow deletion of current session; default:
295
+ --- `MiniSessions.config.force.delete`).
296
+ --- - <verbose> (whether to print session path after action; default
297
+ --- `MiniSessions.config.verbose.delete`).
298
+ --- - <hooks> (a table with <pre> and <post> function hooks to be executed
299
+ --- with session data argument before and after successful delete; overrides
300
+ --- `MiniSessions.config.hooks.pre.delete` and
301
+ --- `MiniSessions.config.hooks.post.delete`).
302
+ MiniSessions.delete = function(session_name, opts)
303
+ if H.is_disabled() then return end
304
+ if vim.tbl_count(MiniSessions.detected) == 0 then
305
+ H.error('There are no detected sessions. Change configuration and rerun `MiniSessions.setup()`.')
306
+ end
307
+
308
+ opts = vim.tbl_deep_extend('force', H.default_opts('delete'), opts or {})
309
+
310
+ local session_path = H.name_to_path(session_name)
311
+
312
+ -- Make sessions up to date
313
+ H.detect_sessions()
314
+
315
+ -- Make sure to delete only detected session (matters for local session)
316
+ session_name = vim.fn.fnamemodify(session_path, ':t')
317
+ if not H.validate_detected(session_name) then return end
318
+ session_path = MiniSessions.detected[session_name].path
319
+
320
+ local is_current_session = session_path == H.get_this_session()
321
+ if not opts.force and is_current_session then
322
+ H.error([[Can't delete current session when `opts.force` is not `true`.]])
323
+ end
324
+
325
+ local data = MiniSessions.detected[session_name]
326
+
327
+ -- Execute 'pre' hook
328
+ H.possibly_execute(opts.hooks.pre, data)
329
+
330
+ -- Delete and update detected sessions
331
+ vim.fn.delete(session_path)
332
+ MiniSessions.detected[session_name] = nil
333
+ if is_current_session then vim.v.this_session = '' end
334
+
335
+ -- Possibly notify
336
+ if opts.verbose then H.message(('Deleted session %s'):format(session_path)) end
337
+
338
+ -- Execute 'pre' hook
339
+ H.possibly_execute(opts.hooks.post, data)
340
+ end
341
+
342
+ --- Restart Neovim preserving current session
343
+ ---
344
+ --- Write (active or new temporary) session, |:restart|, source the session.
345
+ ---
346
+ --- Notes:
347
+ --- - Requires Neovim>=0.12 for |:restart| command.
348
+ --- - If there is no active session (|v:this_session|), |argument-list| is cleared
349
+ --- for temporary session to not preserve it.
350
+ MiniSessions.restart = function()
351
+ if vim.fn.has('nvim-0.12') == 0 then return H.message('`restart()` requires Neovim>=0.12') end
352
+
353
+ -- Return early if `:restart +qall` is impossible
354
+ for _, buf_id in ipairs(vim.api.nvim_list_bufs()) do
355
+ if vim.bo[buf_id].modified then
356
+ H.error('No write since last change in buffer ' .. buf_id .. '. `:restart` will fail.')
357
+ end
358
+ end
359
+
360
+ -- Compute session to write and restore
361
+ local this_session, del_session = H.get_this_session(), nil
362
+ if this_session == '' then
363
+ local _, filename = vim.loop.fs_mkstemp('restart_session_XXXXXX')
364
+ this_session = vim.fs.abspath(filename)
365
+ del_session = this_session
366
+ vim.cmd('%argdelete')
367
+ end
368
+
369
+ -- Write session
370
+ local session_arg = vim.fn.fnameescape(this_session)
371
+ vim.cmd('mksession! ' .. session_arg)
372
+
373
+ -- Restart Neovim and execute Lua commands to restore necessary session
374
+ local after = { 'vim.cmd("source ' .. session_arg:gsub('\\', '\\\\') .. '")' }
375
+ if del_session ~= nil then
376
+ table.insert(after, 'pcall(vim.fs.rm, ' .. vim.inspect(del_session) .. ')')
377
+ table.insert(after, 'vim.v.this_session = ""')
378
+ end
379
+
380
+ -- - Ensure proper 'termguicolors' (problems on Neovim<0.12.1 and in tests)
381
+ table.insert(after, 'vim.o.termguicolors = ' .. tostring(vim.o.termguicolors))
382
+ table.insert(after, 'vim.notify("(mini.sessions) Restarted")')
383
+
384
+ local ok, msg = pcall(vim.cmd, 'restart lua ' .. table.concat(after, ';'))
385
+ if not ok then H.error(msg) end
386
+ end
387
+
388
+ --- Select session interactively and perform action
389
+ ---
390
+ --- Note: this uses |vim.ui.select()| function. For more user-friendly
391
+ --- experience, override it (for example, see |MiniPick.ui_select()|).
392
+ ---
393
+ ---@param action string|nil Action to perform. Should be one of "read" (default),
394
+ --- "write", or "delete".
395
+ ---@param opts table|nil Options for specified action.
396
+ MiniSessions.select = function(action, opts)
397
+ if not (type(vim.ui) == 'table' and type(vim.ui.select) == 'function') then
398
+ H.error('`MiniSessions.select()` requires `vim.ui.select()` function.')
399
+ end
400
+
401
+ action = action or 'read'
402
+ if not vim.tbl_contains({ 'read', 'write', 'delete' }, action) then
403
+ H.error("`action` should be one of 'read', 'write', or 'delete'.")
404
+ end
405
+
406
+ -- Make sessions up to date
407
+ H.detect_sessions()
408
+
409
+ -- Ensure consistent order of items
410
+ local detected = {}
411
+ for _, session in pairs(MiniSessions.detected) do
412
+ table.insert(detected, session)
413
+ end
414
+ local sort_fun = function(a, b)
415
+ -- Put local session first, others - increasing alphabetically
416
+ local a_name = a.type == 'local' and '' or a.name
417
+ local b_name = b.type == 'local' and '' or b.name
418
+ return a_name < b_name
419
+ end
420
+ table.sort(detected, sort_fun)
421
+ local detected_names = vim.tbl_map(function(x) return x.name end, detected)
422
+
423
+ vim.ui.select(detected_names, {
424
+ prompt = 'Select session to ' .. action,
425
+ format_item = function(x) return ('%s (%s)'):format(x, MiniSessions.detected[x].type) end,
426
+ }, function(item, idx)
427
+ if item == nil then return end
428
+ MiniSessions[action](item, opts)
429
+ end)
430
+ end
431
+
432
+ --- Get name of latest detected session
433
+ ---
434
+ --- Latest session is the session with the latest modification time determined
435
+ --- by |getftime()|.
436
+ ---
437
+ ---@return string|nil Name of latest session or `nil` if there is no sessions.
438
+ MiniSessions.get_latest = function()
439
+ if vim.tbl_count(MiniSessions.detected) == 0 then return end
440
+
441
+ local latest_time, latest_name = -1, nil
442
+ for name, data in pairs(MiniSessions.detected) do
443
+ if data.modify_time > latest_time then
444
+ latest_time, latest_name = data.modify_time, name
445
+ end
446
+ end
447
+
448
+ return latest_name
449
+ end
450
+
451
+ -- Helper data ================================================================
452
+ -- Module default config
453
+ H.default_config = vim.deepcopy(MiniSessions.config)
454
+
455
+ -- Helper functionality =======================================================
456
+ -- Settings -------------------------------------------------------------------
457
+ H.setup_config = function(config)
458
+ H.check_type('config', config, 'table', true)
459
+ config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {})
460
+
461
+ H.check_type('autoread', config.autoread, 'boolean')
462
+ H.check_type('autowrite', config.autowrite, 'boolean')
463
+ H.check_type('directory', config.directory, 'string')
464
+ H.check_type('file', config.file, 'string')
465
+
466
+ H.check_type('force', config.force, 'table')
467
+ H.check_type('force.read', config.force.read, 'boolean')
468
+ H.check_type('force.write', config.force.write, 'boolean')
469
+ H.check_type('force.delete', config.force.delete, 'boolean')
470
+
471
+ H.check_type('hooks', config.hooks, 'table')
472
+ H.check_type('hooks.pre', config.hooks.pre, 'table')
473
+ H.check_type('hooks.pre.read', config.hooks.pre.read, 'function', true)
474
+ H.check_type('hooks.pre.write', config.hooks.pre.write, 'function', true)
475
+ H.check_type('hooks.pre.delete', config.hooks.pre.delete, 'function', true)
476
+ H.check_type('hooks.post', config.hooks.post, 'table')
477
+ H.check_type('hooks.post.read', config.hooks.post.read, 'function', true)
478
+ H.check_type('hooks.post.write', config.hooks.post.write, 'function', true)
479
+ H.check_type('hooks.post.delete', config.hooks.post.delete, 'function', true)
480
+
481
+ H.check_type('verbose', config.verbose, 'table')
482
+ H.check_type('verbose.read', config.verbose.read, 'boolean')
483
+ H.check_type('verbose.write', config.verbose.write, 'boolean')
484
+ H.check_type('verbose.delete', config.verbose.delete, 'boolean')
485
+
486
+ return config
487
+ end
488
+
489
+ H.apply_config = function(config)
490
+ MiniSessions.config = config
491
+
492
+ H.detect_sessions(config)
493
+ end
494
+
495
+ H.create_autocommands = function(config)
496
+ local gr = vim.api.nvim_create_augroup('MiniSessions', {})
497
+
498
+ if config.autoread then
499
+ local autoread = function()
500
+ if not H.is_something_shown() then MiniSessions.read() end
501
+ end
502
+ local opts = { group = gr, nested = true, once = true, callback = autoread, desc = 'Autoread latest session' }
503
+ vim.api.nvim_create_autocmd('VimEnter', opts)
504
+ end
505
+
506
+ if config.autowrite then
507
+ local autowrite = function()
508
+ if H.get_this_session() ~= '' then MiniSessions.write(nil, { force = true }) end
509
+ end
510
+ local opts = { group = gr, callback = autowrite, desc = 'Autowrite current session' }
511
+ vim.api.nvim_create_autocmd('VimLeavePre', opts)
512
+ end
513
+ end
514
+
515
+ H.is_disabled = function() return vim.g.minisessions_disable == true or vim.b.minisessions_disable == true end
516
+
517
+ H.get_config = function(config)
518
+ return vim.tbl_deep_extend('force', MiniSessions.config, vim.b.minisessions_config or {}, config or {})
519
+ end
520
+
521
+ -- Work with sessions ---------------------------------------------------------
522
+ H.detect_sessions = function(config)
523
+ config = H.get_config(config)
524
+
525
+ local res_global = config.directory == '' and {} or H.detect_sessions_global(config.directory)
526
+ local res_local = config.file == '' and {} or H.detect_sessions_local(config.file)
527
+
528
+ -- If there are both local and global session with same name, prefer local
529
+ MiniSessions.detected = vim.tbl_deep_extend('force', res_global, res_local)
530
+ end
531
+
532
+ H.detect_sessions_global = function(global_dir)
533
+ -- Ensure correct directory path: create if doesn't exist
534
+ global_dir = H.full_path(global_dir)
535
+ if vim.fn.isdirectory(global_dir) ~= 1 then
536
+ local ok, _ = pcall(vim.fn.mkdir, global_dir, 'p')
537
+
538
+ if not ok then
539
+ H.message(('%s is not a directory path.'):format(vim.inspect(global_dir)))
540
+ return {}
541
+ end
542
+ end
543
+
544
+ -- Find global sessions
545
+ local res = {}
546
+ for name in vim.fs.dir(global_dir) do
547
+ local f = global_dir .. '/' .. name
548
+ if H.is_readable_file(f) then
549
+ local s = H.new_session(f, 'global')
550
+ res[s.name] = s
551
+ end
552
+ end
553
+ return res
554
+ end
555
+
556
+ H.detect_sessions_local = function(local_file)
557
+ local f = vim.fn.getcwd() .. '/' .. local_file
558
+ if not H.is_readable_file(f) then return {} end
559
+
560
+ local s = H.new_session(f, 'local')
561
+ return { [s.name] = s }
562
+ end
563
+
564
+ H.new_session = function(session_path, session_type)
565
+ return {
566
+ modify_time = vim.fn.getftime(session_path),
567
+ name = vim.fn.fnamemodify(session_path, ':t'),
568
+ path = H.full_path(session_path),
569
+ type = session_type or H.get_session_type(session_path),
570
+ }
571
+ end
572
+
573
+ H.get_session_type = function(session_path)
574
+ if MiniSessions.config.directory == '' then return 'local' end
575
+
576
+ local session_dir = H.full_path(session_path)
577
+ local global_dir = H.full_path(MiniSessions.config.directory)
578
+ return session_dir == global_dir and 'global' or 'local'
579
+ end
580
+
581
+ H.validate_detected = function(session_name)
582
+ local is_detected = vim.tbl_contains(vim.tbl_keys(MiniSessions.detected), session_name)
583
+ if is_detected then return true end
584
+
585
+ H.error(('%s is not a name for detected session.'):format(vim.inspect(session_name)))
586
+ end
587
+
588
+ H.get_unsaved_listed_buffers = function()
589
+ return vim.tbl_filter(
590
+ function(buf_id) return vim.bo[buf_id].modified and vim.bo[buf_id].buflisted end,
591
+ vim.api.nvim_list_bufs()
592
+ )
593
+ end
594
+
595
+ H.get_this_session = function() return vim.fs.normalize(vim.v.this_session) end
596
+
597
+ H.name_to_path = function(session_name)
598
+ if session_name == nil then
599
+ local this_session = H.get_this_session()
600
+ if this_session == '' then H.error('There is no active session. Supply non-nil session name.') end
601
+ return this_session
602
+ end
603
+
604
+ session_name = tostring(session_name)
605
+ if session_name == '' then H.error('Supply non-empty session name.') end
606
+
607
+ local session_dir = (session_name == MiniSessions.config.file) and vim.fn.getcwd() or MiniSessions.config.directory
608
+ return H.full_path(session_dir .. '/' .. session_name)
609
+ end
610
+
611
+ -- Utilities ------------------------------------------------------------------
612
+ H.error = function(msg) error('(mini.sessions) ' .. msg, 0) end
613
+
614
+ H.check_type = function(name, val, ref, allow_nil)
615
+ if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
616
+ H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
617
+ end
618
+
619
+ H.echo = function(msg, is_important)
620
+ -- Construct message chunks
621
+ msg = type(msg) == 'string' and { { msg } } or msg
622
+ table.insert(msg, 1, { '(mini.sessions) ', 'WarningMsg' })
623
+
624
+ -- Avoid hit-enter-prompt
625
+ local max_width = vim.o.columns * math.max(vim.o.cmdheight - 1, 0) + vim.v.echospace
626
+ local chunks, tot_width = {}, 0
627
+ for _, ch in ipairs(msg) do
628
+ local new_ch = { vim.fn.strcharpart(ch[1], 0, max_width - tot_width), ch[2] }
629
+ table.insert(chunks, new_ch)
630
+ tot_width = tot_width + vim.fn.strdisplaywidth(new_ch[1])
631
+ if tot_width >= max_width then break end
632
+ end
633
+
634
+ -- Echo. Force redraw to ensure that it is effective (`:h echo-redraw`)
635
+ vim.cmd([[echo '' | redraw]])
636
+ vim.api.nvim_echo(chunks, is_important, {})
637
+ end
638
+
639
+ H.message = function(msg) H.echo(msg, true) end
640
+
641
+ H.default_opts = function(action)
642
+ local config = MiniSessions.config
643
+ return {
644
+ force = config.force[action],
645
+ verbose = config.verbose[action],
646
+ hooks = { pre = config.hooks.pre[action], post = config.hooks.post[action] },
647
+ }
648
+ end
649
+
650
+ H.is_readable_file = function(path) return vim.fn.isdirectory(path) ~= 1 and vim.fn.getfperm(path):sub(1, 1) == 'r' end
651
+
652
+ H.full_path = function(path) return vim.fs.normalize(vim.fn.resolve(vim.fn.fnamemodify(path, ':p'))) end
653
+
654
+ H.is_something_shown = function()
655
+ -- Don't autoread session if Neovim is opened to show something. That is
656
+ -- when at least one of the following is true:
657
+ -- - There are files in arguments (like `nvim foo.txt` with new file).
658
+ if vim.fn.argc() > 0 then return true end
659
+
660
+ -- - Several buffers are listed (like session with placeholder buffers). That
661
+ -- means unlisted buffers (like from `nvim-tree`) don't affect decision.
662
+ local listed_buffers = vim.tbl_filter(
663
+ function(buf_id) return vim.fn.buflisted(buf_id) == 1 end,
664
+ vim.api.nvim_list_bufs()
665
+ )
666
+ if #listed_buffers > 1 then return true end
667
+
668
+ -- - Current buffer is meant to show something else
669
+ if vim.bo.filetype ~= '' then return true end
670
+
671
+ -- - Current buffer has any lines (something opened explicitly).
672
+ -- NOTE: Usage of `line2byte(line('$') + 1) < 0` seemed to be fine, but it
673
+ -- doesn't work if some automated changed was made to buffer while leaving it
674
+ -- empty (returns 2 instead of -1). This was also the reason of not being
675
+ -- able to test with child Neovim process from 'tests/helpers'.
676
+ local n_lines = vim.api.nvim_buf_line_count(0)
677
+ if n_lines > 1 then return true end
678
+ local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, true)[1]
679
+ if string.len(first_line) > 0 then return true end
680
+
681
+ return false
682
+ end
683
+
684
+ H.possibly_execute = function(f, ...)
685
+ if f == nil then return end
686
+ return f(...)
687
+ end
688
+
689
+ return MiniSessions