retrovim 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.conda/retrovim.yaml +259 -0
- package/.conda/terax.icns +0 -0
- package/.conda/terax.ico +0 -0
- package/.conda/terax.png +0 -0
- package/.github/workflows/release.yml +95 -0
- package/.gitmodules +3 -0
- package/.npm/kanata_touchcursor.js +28 -0
- package/.npm/nvim.js +26 -0
- package/.npm/yazi.js +26 -0
- package/.npm/zsh.js +17 -0
- package/.pip/kanata_touchcursor/__init__.py +28 -0
- package/.pip/nvim/__init__.py +31 -0
- package/.pip/yazi/__init__.py +31 -0
- package/.pip/zsh/__init__.py +22 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +674 -0
- package/README.md +336 -0
- package/kanata/touchcursor.kbd +164 -0
- package/nvim/init.lua +813 -0
- package/nvim/plugins/mini.nvim/.github/DISCUSSION_TEMPLATE/q-a.yml +72 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/bug-report.yml +136 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/nvim/plugins/mini.nvim/.github/ISSUE_TEMPLATE/feature-request.yml +75 -0
- package/nvim/plugins/mini.nvim/.github/PULL_REQUEST_TEMPLATE.md +2 -0
- package/nvim/plugins/mini.nvim/.github/workflows/quality-control.yml +150 -0
- package/nvim/plugins/mini.nvim/.pre-commit-config.yaml +20 -0
- package/nvim/plugins/mini.nvim/.stylua.toml +7 -0
- package/nvim/plugins/mini.nvim/.styluaignore +1 -0
- package/nvim/plugins/mini.nvim/CHANGELOG.md +1894 -0
- package/nvim/plugins/mini.nvim/CODE_OF_CONDUCT.md +132 -0
- package/nvim/plugins/mini.nvim/CONTRIBUTING.md +331 -0
- package/nvim/plugins/mini.nvim/LICENSE +21 -0
- package/nvim/plugins/mini.nvim/MAINTAINING.md +330 -0
- package/nvim/plugins/mini.nvim/Makefile +51 -0
- package/nvim/plugins/mini.nvim/README.md +261 -0
- package/nvim/plugins/mini.nvim/TESTING.md +1011 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/README.md +35 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/benchmark.sh +56 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-alpha.lua +21 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-original.lua +17 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_dashboard-starter.lua +18 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_empty.lua +4 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_starter-default.lua +7 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-alpha.lua +10 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-original.lua +7 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/init-files/init_startify-starter.lua +20 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/install.sh +10 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/make_summary.py +68 -0
- package/nvim/plugins/mini.nvim/benchmarks/starter/startup-summary.md +10 -0
- package/nvim/plugins/mini.nvim/colors/miniautumn.lua +55 -0
- package/nvim/plugins/mini.nvim/colors/minicyan.lua +95 -0
- package/nvim/plugins/mini.nvim/colors/minischeme.lua +95 -0
- package/nvim/plugins/mini.nvim/colors/minispring.lua +53 -0
- package/nvim/plugins/mini.nvim/colors/minisummer.lua +49 -0
- package/nvim/plugins/mini.nvim/colors/miniwinter.lua +51 -0
- package/nvim/plugins/mini.nvim/colors/randomhue.lua +16 -0
- package/nvim/plugins/mini.nvim/doc/mini-ai.txt +889 -0
- package/nvim/plugins/mini.nvim/doc/mini-align.txt +923 -0
- package/nvim/plugins/mini.nvim/doc/mini-animate.txt +937 -0
- package/nvim/plugins/mini.nvim/doc/mini-base16.txt +285 -0
- package/nvim/plugins/mini.nvim/doc/mini-basics.txt +359 -0
- package/nvim/plugins/mini.nvim/doc/mini-bracketed.txt +622 -0
- package/nvim/plugins/mini.nvim/doc/mini-bufremove.txt +123 -0
- package/nvim/plugins/mini.nvim/doc/mini-clue.txt +760 -0
- package/nvim/plugins/mini.nvim/doc/mini-cmdline.txt +392 -0
- package/nvim/plugins/mini.nvim/doc/mini-colors.txt +880 -0
- package/nvim/plugins/mini.nvim/doc/mini-comment.txt +230 -0
- package/nvim/plugins/mini.nvim/doc/mini-completion.txt +477 -0
- package/nvim/plugins/mini.nvim/doc/mini-cursorword.txt +105 -0
- package/nvim/plugins/mini.nvim/doc/mini-deps.txt +590 -0
- package/nvim/plugins/mini.nvim/doc/mini-diff.txt +661 -0
- package/nvim/plugins/mini.nvim/doc/mini-doc.txt +434 -0
- package/nvim/plugins/mini.nvim/doc/mini-extra.txt +856 -0
- package/nvim/plugins/mini.nvim/doc/mini-files.txt +1018 -0
- package/nvim/plugins/mini.nvim/doc/mini-fuzzy.txt +160 -0
- package/nvim/plugins/mini.nvim/doc/mini-git.txt +425 -0
- package/nvim/plugins/mini.nvim/doc/mini-hipatterns.txt +489 -0
- package/nvim/plugins/mini.nvim/doc/mini-hues.txt +420 -0
- package/nvim/plugins/mini.nvim/doc/mini-icons.txt +508 -0
- package/nvim/plugins/mini.nvim/doc/mini-indentscope.txt +485 -0
- package/nvim/plugins/mini.nvim/doc/mini-input.txt +932 -0
- package/nvim/plugins/mini.nvim/doc/mini-jump.txt +202 -0
- package/nvim/plugins/mini.nvim/doc/mini-jump2d.txt +525 -0
- package/nvim/plugins/mini.nvim/doc/mini-keymap.txt +449 -0
- package/nvim/plugins/mini.nvim/doc/mini-map.txt +717 -0
- package/nvim/plugins/mini.nvim/doc/mini-misc.txt +431 -0
- package/nvim/plugins/mini.nvim/doc/mini-move.txt +181 -0
- package/nvim/plugins/mini.nvim/doc/mini-notify.txt +434 -0
- package/nvim/plugins/mini.nvim/doc/mini-nvim.txt +431 -0
- package/nvim/plugins/mini.nvim/doc/mini-operators.txt +472 -0
- package/nvim/plugins/mini.nvim/doc/mini-pairs.txt +346 -0
- package/nvim/plugins/mini.nvim/doc/mini-pick.txt +1535 -0
- package/nvim/plugins/mini.nvim/doc/mini-sessions.txt +239 -0
- package/nvim/plugins/mini.nvim/doc/mini-snippets.txt +1291 -0
- package/nvim/plugins/mini.nvim/doc/mini-splitjoin.txt +536 -0
- package/nvim/plugins/mini.nvim/doc/mini-starter.txt +618 -0
- package/nvim/plugins/mini.nvim/doc/mini-statusline.txt +361 -0
- package/nvim/plugins/mini.nvim/doc/mini-surround.txt +863 -0
- package/nvim/plugins/mini.nvim/doc/mini-tabline.txt +151 -0
- package/nvim/plugins/mini.nvim/doc/mini-test.txt +966 -0
- package/nvim/plugins/mini.nvim/doc/mini-trailspace.txt +91 -0
- package/nvim/plugins/mini.nvim/doc/mini-visits.txt +937 -0
- package/nvim/plugins/mini.nvim/logo.png +0 -0
- package/nvim/plugins/mini.nvim/lua/mini/ai.lua +2244 -0
- package/nvim/plugins/mini.nvim/lua/mini/align.lua +2076 -0
- package/nvim/plugins/mini.nvim/lua/mini/animate.lua +2127 -0
- package/nvim/plugins/mini.nvim/lua/mini/base16.lua +1752 -0
- package/nvim/plugins/mini.nvim/lua/mini/basics.lua +772 -0
- package/nvim/plugins/mini.nvim/lua/mini/bracketed.lua +2013 -0
- package/nvim/plugins/mini.nvim/lua/mini/bufremove.lua +283 -0
- package/nvim/plugins/mini.nvim/lua/mini/clue.lua +2096 -0
- package/nvim/plugins/mini.nvim/lua/mini/cmdline.lua +1182 -0
- package/nvim/plugins/mini.nvim/lua/mini/colors.lua +2483 -0
- package/nvim/plugins/mini.nvim/lua/mini/comment.lua +586 -0
- package/nvim/plugins/mini.nvim/lua/mini/completion.lua +2094 -0
- package/nvim/plugins/mini.nvim/lua/mini/cursorword.lua +311 -0
- package/nvim/plugins/mini.nvim/lua/mini/deps.lua +1660 -0
- package/nvim/plugins/mini.nvim/lua/mini/diff.lua +1938 -0
- package/nvim/plugins/mini.nvim/lua/mini/doc.lua +1371 -0
- package/nvim/plugins/mini.nvim/lua/mini/extra.lua +2290 -0
- package/nvim/plugins/mini.nvim/lua/mini/files.lua +3145 -0
- package/nvim/plugins/mini.nvim/lua/mini/fuzzy.lua +356 -0
- package/nvim/plugins/mini.nvim/lua/mini/git.lua +1737 -0
- package/nvim/plugins/mini.nvim/lua/mini/hipatterns.lua +1042 -0
- package/nvim/plugins/mini.nvim/lua/mini/hues.lua +2088 -0
- package/nvim/plugins/mini.nvim/lua/mini/icons.lua +2254 -0
- package/nvim/plugins/mini.nvim/lua/mini/indentscope.lua +1158 -0
- package/nvim/plugins/mini.nvim/lua/mini/init.lua +427 -0
- package/nvim/plugins/mini.nvim/lua/mini/input.lua +2183 -0
- package/nvim/plugins/mini.nvim/lua/mini/jump.lua +609 -0
- package/nvim/plugins/mini.nvim/lua/mini/jump2d.lua +1244 -0
- package/nvim/plugins/mini.nvim/lua/mini/keymap.lua +880 -0
- package/nvim/plugins/mini.nvim/lua/mini/map.lua +1709 -0
- package/nvim/plugins/mini.nvim/lua/mini/misc.lua +969 -0
- package/nvim/plugins/mini.nvim/lua/mini/move.lua +509 -0
- package/nvim/plugins/mini.nvim/lua/mini/notify.lua +938 -0
- package/nvim/plugins/mini.nvim/lua/mini/operators.lua +1349 -0
- package/nvim/plugins/mini.nvim/lua/mini/pairs.lua +657 -0
- package/nvim/plugins/mini.nvim/lua/mini/pick.lua +3876 -0
- package/nvim/plugins/mini.nvim/lua/mini/sessions.lua +689 -0
- package/nvim/plugins/mini.nvim/lua/mini/snippets.lua +2828 -0
- package/nvim/plugins/mini.nvim/lua/mini/splitjoin.lua +1132 -0
- package/nvim/plugins/mini.nvim/lua/mini/starter.lua +1599 -0
- package/nvim/plugins/mini.nvim/lua/mini/statusline.lua +686 -0
- package/nvim/plugins/mini.nvim/lua/mini/surround.lua +2388 -0
- package/nvim/plugins/mini.nvim/lua/mini/tabline.lua +564 -0
- package/nvim/plugins/mini.nvim/lua/mini/test.lua +2516 -0
- package/nvim/plugins/mini.nvim/lua/mini/trailspace.lua +215 -0
- package/nvim/plugins/mini.nvim/lua/mini/visits.lua +1577 -0
- package/nvim/plugins/mini.nvim/readmes/mini-ai.md +190 -0
- package/nvim/plugins/mini.nvim/readmes/mini-align.md +203 -0
- package/nvim/plugins/mini.nvim/readmes/mini-animate.md +214 -0
- package/nvim/plugins/mini.nvim/readmes/mini-base16.md +198 -0
- package/nvim/plugins/mini.nvim/readmes/mini-basics.md +184 -0
- package/nvim/plugins/mini.nvim/readmes/mini-bracketed.md +193 -0
- package/nvim/plugins/mini.nvim/readmes/mini-bufremove.md +139 -0
- package/nvim/plugins/mini.nvim/readmes/mini-clue.md +260 -0
- package/nvim/plugins/mini.nvim/readmes/mini-cmdline.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-colors.md +169 -0
- package/nvim/plugins/mini.nvim/readmes/mini-comment.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-completion.md +217 -0
- package/nvim/plugins/mini.nvim/readmes/mini-cursorword.md +137 -0
- package/nvim/plugins/mini.nvim/readmes/mini-deps.md +271 -0
- package/nvim/plugins/mini.nvim/readmes/mini-diff.md +289 -0
- package/nvim/plugins/mini.nvim/readmes/mini-doc.md +198 -0
- package/nvim/plugins/mini.nvim/readmes/mini-extra.md +158 -0
- package/nvim/plugins/mini.nvim/readmes/mini-files.md +247 -0
- package/nvim/plugins/mini.nvim/readmes/mini-fuzzy.md +134 -0
- package/nvim/plugins/mini.nvim/readmes/mini-git.md +168 -0
- package/nvim/plugins/mini.nvim/readmes/mini-hipatterns.md +176 -0
- package/nvim/plugins/mini.nvim/readmes/mini-hues.md +285 -0
- package/nvim/plugins/mini.nvim/readmes/mini-icons.md +183 -0
- package/nvim/plugins/mini.nvim/readmes/mini-indentscope.md +191 -0
- package/nvim/plugins/mini.nvim/readmes/mini-input.md +163 -0
- package/nvim/plugins/mini.nvim/readmes/mini-jump.md +161 -0
- package/nvim/plugins/mini.nvim/readmes/mini-jump2d.md +197 -0
- package/nvim/plugins/mini.nvim/readmes/mini-keymap.md +205 -0
- package/nvim/plugins/mini.nvim/readmes/mini-map.md +191 -0
- package/nvim/plugins/mini.nvim/readmes/mini-misc.md +145 -0
- package/nvim/plugins/mini.nvim/readmes/mini-move.md +163 -0
- package/nvim/plugins/mini.nvim/readmes/mini-notify.md +175 -0
- package/nvim/plugins/mini.nvim/readmes/mini-operators.md +193 -0
- package/nvim/plugins/mini.nvim/readmes/mini-pairs.md +158 -0
- package/nvim/plugins/mini.nvim/readmes/mini-pick.md +340 -0
- package/nvim/plugins/mini.nvim/readmes/mini-sessions.md +164 -0
- package/nvim/plugins/mini.nvim/readmes/mini-snippets.md +373 -0
- package/nvim/plugins/mini.nvim/readmes/mini-splitjoin.md +194 -0
- package/nvim/plugins/mini.nvim/readmes/mini-starter.md +176 -0
- package/nvim/plugins/mini.nvim/readmes/mini-statusline.md +155 -0
- package/nvim/plugins/mini.nvim/readmes/mini-surround.md +190 -0
- package/nvim/plugins/mini.nvim/readmes/mini-tabline.md +156 -0
- package/nvim/plugins/mini.nvim/readmes/mini-test.md +175 -0
- package/nvim/plugins/mini.nvim/readmes/mini-trailspace.md +137 -0
- package/nvim/plugins/mini.nvim/readmes/mini-visits.md +243 -0
- package/nvim/plugins/mini.nvim/scripts/dual_log.sh +13 -0
- package/nvim/plugins/mini.nvim/scripts/dual_push.sh +15 -0
- package/nvim/plugins/mini.nvim/scripts/dual_release.sh +102 -0
- package/nvim/plugins/mini.nvim/scripts/dual_sync.sh +115 -0
- package/nvim/plugins/mini.nvim/scripts/init-deps-example.lua +59 -0
- package/nvim/plugins/mini.nvim/scripts/lint-filename-length.sh +16 -0
- package/nvim/plugins/mini.nvim/scripts/lintcommit-ci.sh +18 -0
- package/nvim/plugins/mini.nvim/scripts/lintcommit.lua +393 -0
- package/nvim/plugins/mini.nvim/scripts/minidoc.lua +57 -0
- package/nvim/plugins/mini.nvim/scripts/minimal_init.lua +28 -0
- package/nvim/plugins/mini.nvim/scripts/minitest.lua +4 -0
- package/package.json +16 -0
- package/pyproject.toml +43 -0
- package/yazi/init.lua +12 -0
- package/yazi/keymap.toml +114 -0
- package/yazi/lesskey +5 -0
- package/yazi/plugins/bookmarks.yazi/main.lua +86 -0
- package/yazi/plugins/cd-git-root.yazi/main.lua +31 -0
- package/yazi/plugins/smart-enter.yazi/main.lua +11 -0
- package/yazi/theme.toml +26 -0
- package/yazi/yazi.toml +15 -0
- package/zsh/.zshrc +145 -0
- package/zsh/starship.toml +20 -0
- package/zsh/zsh-patina.toml +2 -0
|
@@ -0,0 +1,969 @@
|
|
|
1
|
+
--- *mini.misc* Miscellaneous functions
|
|
2
|
+
---
|
|
3
|
+
--- MIT License Copyright (c) 2021 Evgeni Chasnovski
|
|
4
|
+
|
|
5
|
+
--- Features the following functions:
|
|
6
|
+
--- - |MiniMisc.bench_time()| to benchmark function execution time.
|
|
7
|
+
--- Useful in combination with `stat_summary()`.
|
|
8
|
+
---
|
|
9
|
+
--- - |MiniMisc.log_add()|, |MiniMisc.log_show()| and other helper functions to work
|
|
10
|
+
--- with a special in-memory log array. Useful when debugging Lua code.
|
|
11
|
+
---
|
|
12
|
+
--- - |MiniMisc.put()| and |MiniMisc.put_text()| to pretty print its arguments
|
|
13
|
+
--- into command line and current buffer respectively.
|
|
14
|
+
---
|
|
15
|
+
--- - |MiniMisc.resize_window()| to resize current window to its editable width.
|
|
16
|
+
---
|
|
17
|
+
--- - |MiniMisc.safely()| to execute a function on a condition and warn on error.
|
|
18
|
+
--- Useful to organize |init.lua| in fail-safe sections with simple lazy loading.
|
|
19
|
+
---
|
|
20
|
+
--- - |MiniMisc.setup_auto_root()| to set up automated change of current directory.
|
|
21
|
+
---
|
|
22
|
+
--- - |MiniMisc.setup_termbg_sync()| to set up terminal background synchronization
|
|
23
|
+
--- (removes possible "frame" around current Neovim instance).
|
|
24
|
+
---
|
|
25
|
+
--- - |MiniMisc.setup_restore_cursor()| to set up automated restoration of
|
|
26
|
+
--- cursor position on file reopen.
|
|
27
|
+
---
|
|
28
|
+
--- - |MiniMisc.stat_summary()| to compute summary statistics of numerical array.
|
|
29
|
+
--- Useful in combination with `bench_time()`.
|
|
30
|
+
---
|
|
31
|
+
--- - |MiniMisc.tbl_head()| and |MiniMisc.tbl_tail()| to return "first" and "last"
|
|
32
|
+
--- elements of table.
|
|
33
|
+
---
|
|
34
|
+
--- - |MiniMisc.zoom()| to zoom in and out of a buffer, making it full screen
|
|
35
|
+
--- in a floating window.
|
|
36
|
+
---
|
|
37
|
+
--- - And more.
|
|
38
|
+
---
|
|
39
|
+
--- # Setup ~
|
|
40
|
+
---
|
|
41
|
+
--- This module doesn't need setup, but it can be done to improve usability.
|
|
42
|
+
--- Setup with `require('mini.misc').setup({})` (replace `{}` with your
|
|
43
|
+
--- `config` table). It will create global Lua table `MiniMisc` which you can
|
|
44
|
+
--- use for scripting or manually (with `:lua MiniMisc.*`).
|
|
45
|
+
---
|
|
46
|
+
--- See |MiniMisc.config| for `config` structure and default values.
|
|
47
|
+
---
|
|
48
|
+
--- This module doesn't have runtime options, so using `vim.b.minimisc_config`
|
|
49
|
+
--- will have no effect here.
|
|
50
|
+
---@tag MiniMisc
|
|
51
|
+
|
|
52
|
+
-- Module definition ==========================================================
|
|
53
|
+
local MiniMisc = {}
|
|
54
|
+
local H = {}
|
|
55
|
+
|
|
56
|
+
--- Module setup
|
|
57
|
+
---
|
|
58
|
+
---@param config table|nil Module config table. See |MiniMisc.config|.
|
|
59
|
+
---
|
|
60
|
+
---@usage >lua
|
|
61
|
+
--- require('mini.misc').setup() -- use default config
|
|
62
|
+
--- -- OR
|
|
63
|
+
--- require('mini.misc').setup({}) -- replace {} with your config table
|
|
64
|
+
--- <
|
|
65
|
+
MiniMisc.setup = function(config)
|
|
66
|
+
-- TODO: Remove after Neovim=0.9 support is dropped
|
|
67
|
+
if vim.fn.has('nvim-0.10') == 0 then
|
|
68
|
+
vim.notify(
|
|
69
|
+
'(mini.misc) Neovim<0.10 is soft deprecated (module works but is not supported).'
|
|
70
|
+
.. " It will be deprecated after the next 'mini.nvim' release (module might not work)."
|
|
71
|
+
.. ' Please update your Neovim version.'
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
-- Export module
|
|
76
|
+
_G.MiniMisc = MiniMisc
|
|
77
|
+
|
|
78
|
+
-- Setup config
|
|
79
|
+
config = H.setup_config(config)
|
|
80
|
+
|
|
81
|
+
-- Apply config
|
|
82
|
+
H.apply_config(config)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
--- Defaults ~
|
|
86
|
+
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
|
|
87
|
+
MiniMisc.config = {
|
|
88
|
+
-- Array of fields to make global (to be used as independent variables)
|
|
89
|
+
make_global = { 'put', 'put_text' },
|
|
90
|
+
}
|
|
91
|
+
--minidoc_afterlines_end
|
|
92
|
+
|
|
93
|
+
-- Module functionality =======================================================
|
|
94
|
+
--- Execute `f` several times and time how long it took
|
|
95
|
+
---
|
|
96
|
+
---@param f function Function which execution to benchmark.
|
|
97
|
+
---@param n number|nil Number of times to execute `f(...)`. Default: 1.
|
|
98
|
+
---@param ... any Arguments when calling `f`.
|
|
99
|
+
---
|
|
100
|
+
---@return ... Table with durations (in seconds; up to nanoseconds) and
|
|
101
|
+
--- output of (last) function execution.
|
|
102
|
+
MiniMisc.bench_time = function(f, n, ...)
|
|
103
|
+
n = n or 1
|
|
104
|
+
local durations, output = {}, nil
|
|
105
|
+
for _ = 1, n do
|
|
106
|
+
local start_time = vim.loop.hrtime()
|
|
107
|
+
output = f(...)
|
|
108
|
+
local end_time = vim.loop.hrtime()
|
|
109
|
+
table.insert(durations, 0.000000001 * (end_time - start_time))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
return durations, output
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
--- Compute width of gutter (info column on the left of the window)
|
|
116
|
+
---
|
|
117
|
+
---@param win_id number|nil Window identifier (see |win_getid()|) for which gutter
|
|
118
|
+
--- width is computed. Default: 0 for current.
|
|
119
|
+
MiniMisc.get_gutter_width = function(win_id)
|
|
120
|
+
win_id = (win_id == nil or win_id == 0) and vim.api.nvim_get_current_win() or win_id
|
|
121
|
+
return vim.fn.getwininfo(win_id)[1].textoff
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
--- Add an entry to the in-memory log array
|
|
125
|
+
---
|
|
126
|
+
--- Useful when trying to debug a Lua code (like Neovim config or plugin).
|
|
127
|
+
--- Use this instead of ad-hoc `print()` statements.
|
|
128
|
+
---
|
|
129
|
+
--- Each entry is a table with the following fields:
|
|
130
|
+
--- - <desc> `(any)` - entry description. Usually a string describing a place
|
|
131
|
+
--- in the code.
|
|
132
|
+
--- - <state> `(any)` - data about current state. Usually a table.
|
|
133
|
+
--- - <timestamp> `(number)` - a timestamp of when the entry was added. A number of
|
|
134
|
+
--- milliseconds since the in-memory log was initiated (after |MiniMisc.setup()|
|
|
135
|
+
--- or |MiniMisc.log_clear()|). Useful during profiling.
|
|
136
|
+
---
|
|
137
|
+
---@param desc any Entry description.
|
|
138
|
+
---@param state any Data about current state.
|
|
139
|
+
---@param opts table|nil Options. Possible fields:
|
|
140
|
+
--- - <deepcopy> - (boolean) Whether to create a copy of tables in {state}.
|
|
141
|
+
--- Usually helpful to record the exact state during code execution and avoid
|
|
142
|
+
--- side effects of tables being changed in-place. Default `true`.
|
|
143
|
+
---
|
|
144
|
+
---@usage >lua
|
|
145
|
+
--- local t = { a = 1 }
|
|
146
|
+
--- MiniMisc.log_add('before', { t = t }) -- Will show `t = { a = 1 }` state
|
|
147
|
+
--- t.a = t.a + 1
|
|
148
|
+
--- MiniMisc.log_add('after', { t = t }) -- Will show `t = { a = 2 }` state
|
|
149
|
+
---
|
|
150
|
+
--- -- Use `:lua MiniMisc.log_show()` or `:=MiniMisc.log_get()` to see the log
|
|
151
|
+
--- <
|
|
152
|
+
---@seealso - |MiniMisc.log_get()| to get log array
|
|
153
|
+
--- - |MiniMisc.log_show()| to show log array in the dedicated buffer
|
|
154
|
+
--- - |MiniMisc.log_clear()| to clear the log array
|
|
155
|
+
MiniMisc.log_add = function(desc, state, opts)
|
|
156
|
+
opts = vim.tbl_extend('force', { deepcopy = true }, opts or {})
|
|
157
|
+
local entry = {
|
|
158
|
+
desc = desc,
|
|
159
|
+
state = opts.deepcopy and H.copy_tables(state) or state,
|
|
160
|
+
timestamp = 0.000001 * (vim.loop.hrtime() - H.log_cache.start_htime),
|
|
161
|
+
}
|
|
162
|
+
table.insert(H.log_cache.log, entry)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
--- Get log array
|
|
166
|
+
---
|
|
167
|
+
---@return table[] Log array. Returned as is, without |vim.deepcopy()|.
|
|
168
|
+
---
|
|
169
|
+
---@seealso - |MiniMisc.log_add()| to add to the log array
|
|
170
|
+
MiniMisc.log_get = function() return H.log_cache.log end
|
|
171
|
+
|
|
172
|
+
--- Show log array in a scratch buffer
|
|
173
|
+
---
|
|
174
|
+
---@seealso - |MiniMisc.log_add()| to add to the log array
|
|
175
|
+
MiniMisc.log_show = function()
|
|
176
|
+
local buf_id = H.log_cache.buf_id
|
|
177
|
+
if buf_id == nil or not vim.api.nvim_buf_is_valid(buf_id) then
|
|
178
|
+
buf_id = vim.api.nvim_create_buf(true, true)
|
|
179
|
+
vim.api.nvim_buf_set_name(buf_id, 'minimisc://' .. buf_id .. '/log')
|
|
180
|
+
H.log_cache.buf_id = buf_id
|
|
181
|
+
end
|
|
182
|
+
local lines = vim.split(vim.inspect(H.log_cache.log), '\n')
|
|
183
|
+
vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines)
|
|
184
|
+
|
|
185
|
+
local buf_wins = vim.fn.win_findbuf(buf_id)
|
|
186
|
+
if buf_wins[1] == nil then return vim.api.nvim_win_set_buf(0, buf_id) end
|
|
187
|
+
vim.api.nvim_set_current_win(buf_wins[1])
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
--- Clear log array
|
|
191
|
+
---
|
|
192
|
+
--- This also sets a new starting point for entry timestamps.
|
|
193
|
+
---
|
|
194
|
+
---@seealso - |MiniMisc.log_add()| to add to the log array
|
|
195
|
+
MiniMisc.log_clear = function()
|
|
196
|
+
H.log_cache.log = {}
|
|
197
|
+
H.log_cache.start_htime = vim.loop.hrtime()
|
|
198
|
+
H.notify('Cleared log')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
H.log_cache = { log = {}, start_htime = vim.loop.hrtime(), buf_id = nil }
|
|
202
|
+
|
|
203
|
+
--- Print Lua objects in command line
|
|
204
|
+
---
|
|
205
|
+
---@param ... any Any number of objects to be printed each on separate line.
|
|
206
|
+
MiniMisc.put = function(...)
|
|
207
|
+
local objects = {}
|
|
208
|
+
-- Not using `{...}` because it removes `nil` input
|
|
209
|
+
for i = 1, select('#', ...) do
|
|
210
|
+
local v = select(i, ...)
|
|
211
|
+
table.insert(objects, vim.inspect(v))
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
print(table.concat(objects, '\n'))
|
|
215
|
+
|
|
216
|
+
return ...
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
--- Print Lua objects in current buffer
|
|
220
|
+
---
|
|
221
|
+
---@param ... any Any number of objects to be printed each on separate line.
|
|
222
|
+
MiniMisc.put_text = function(...)
|
|
223
|
+
local objects = {}
|
|
224
|
+
-- Not using `{...}` because it removes `nil` input
|
|
225
|
+
for i = 1, select('#', ...) do
|
|
226
|
+
local v = select(i, ...)
|
|
227
|
+
table.insert(objects, vim.inspect(v))
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
local lines = vim.split(table.concat(objects, '\n'), '\n')
|
|
231
|
+
local lnum = vim.api.nvim_win_get_cursor(0)[1]
|
|
232
|
+
vim.fn.append(lnum, lines)
|
|
233
|
+
|
|
234
|
+
return ...
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
--- Resize window to have exact number of editable columns
|
|
238
|
+
---
|
|
239
|
+
---@param win_id number|nil Window identifier (see |win_getid()|) to be resized.
|
|
240
|
+
--- Default: 0 for current.
|
|
241
|
+
---@param text_width number|nil Number of editable columns resized window will
|
|
242
|
+
--- display. Default: first element of |'colorcolumn'| or otherwise |'textwidth'|
|
|
243
|
+
--- (using screen width as its default but not more than 79).
|
|
244
|
+
MiniMisc.resize_window = function(win_id, text_width)
|
|
245
|
+
win_id = win_id or 0
|
|
246
|
+
text_width = text_width or H.default_text_width(win_id)
|
|
247
|
+
|
|
248
|
+
vim.api.nvim_win_set_width(win_id, text_width + MiniMisc.get_gutter_width(win_id))
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
H.default_text_width = function(win_id)
|
|
252
|
+
local buf = vim.api.nvim_win_get_buf(win_id)
|
|
253
|
+
local textwidth = vim.bo[buf].textwidth
|
|
254
|
+
textwidth = (textwidth == 0) and math.min(vim.o.columns, 79) or textwidth
|
|
255
|
+
|
|
256
|
+
local colorcolumn = vim.wo[win_id].colorcolumn
|
|
257
|
+
if colorcolumn ~= '' then
|
|
258
|
+
local cc = vim.split(colorcolumn, ',')[1]
|
|
259
|
+
local is_cc_relative = vim.tbl_contains({ '-', '+' }, cc:sub(1, 1))
|
|
260
|
+
|
|
261
|
+
if is_cc_relative then
|
|
262
|
+
return textwidth + tonumber(cc)
|
|
263
|
+
else
|
|
264
|
+
return tonumber(cc)
|
|
265
|
+
end
|
|
266
|
+
else
|
|
267
|
+
return textwidth
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
--- Execute a function on a condition and warn on error
|
|
272
|
+
---
|
|
273
|
+
--- Input function is executed exactly once. Its possible error is captured and is
|
|
274
|
+
--- shown as a |vim.notify()| warning.
|
|
275
|
+
---
|
|
276
|
+
--- Useful to organize |init.lua| in fail-safe sections with simple lazy loading.
|
|
277
|
+
---
|
|
278
|
+
---@param when string When to execute a function. One of:
|
|
279
|
+
--- - `'now'` - immediately.
|
|
280
|
+
--- - `'later'` - queue to be executed soon without blocking the execution of next
|
|
281
|
+
--- code in file. Queued functions are executed in order they are added.
|
|
282
|
+
--- - `'delay:<number>'` - after a specified delay with |vim.defer_fn()|.
|
|
283
|
+
--- - `'event:<events>'` - on whichever specified event is triggered first.
|
|
284
|
+
--- - `'event:<events>~<patterns>` - same as above, but events must match
|
|
285
|
+
--- specified |autocmd-pattern|.
|
|
286
|
+
--- - `'filetype:<filetypes>'` - same as `'event:FileType~<filetypes>'`, but follow
|
|
287
|
+
--- successful function execution with |filetype-detect| for all normal buffers
|
|
288
|
+
--- (if new |ftdetect| scripts were added) and sourcing |ftplugin| (for buffers
|
|
289
|
+
--- matching `<filetypes>`). Intended to be used for loading "language plugins".
|
|
290
|
+
---@param f function Function to execute (without arguments).
|
|
291
|
+
---
|
|
292
|
+
---@usage >lua
|
|
293
|
+
--- MiniMisc.safely('later', function()
|
|
294
|
+
--- vim.notify('This will be executed after the next "now" call')
|
|
295
|
+
--- end)
|
|
296
|
+
--- MiniMisc.safely('now', function() error('This will be a warning') end)
|
|
297
|
+
---
|
|
298
|
+
--- MiniMisc.safely('event:InsertEnter', function()
|
|
299
|
+
--- require('mini.completion').setup()
|
|
300
|
+
--- end)
|
|
301
|
+
--- MiniMisc.safely('event:CmdlineEnter~/', function()
|
|
302
|
+
--- vim.notify('Start searching for the first time')
|
|
303
|
+
--- end)
|
|
304
|
+
---
|
|
305
|
+
--- MiniMisc.safely('filetype:tex,plaintex', function()
|
|
306
|
+
--- -- Load plugin to improve writing LaTeX
|
|
307
|
+
--- end)
|
|
308
|
+
--- <
|
|
309
|
+
MiniMisc.safely = function(when, f)
|
|
310
|
+
H.check_type('when', when, 'string', false)
|
|
311
|
+
H.check_type('f', f, 'callable', false)
|
|
312
|
+
|
|
313
|
+
if when == 'now' then
|
|
314
|
+
H.execute_now(f)
|
|
315
|
+
return
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
-- Compute traceback before delaying execution to provide more info
|
|
319
|
+
local trace = debug.traceback('', 2)
|
|
320
|
+
|
|
321
|
+
if when == 'later' then
|
|
322
|
+
if #H.safely_cache.later == 0 then vim.schedule(H.execute_later) end
|
|
323
|
+
table.insert(H.safely_cache.later, { f = f, trace = trace })
|
|
324
|
+
return
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
local delay = tonumber(when:match('^delay:(%d+)$'))
|
|
328
|
+
if delay ~= nil then
|
|
329
|
+
vim.defer_fn(function() H.execute_now(f, trace) end, delay)
|
|
330
|
+
return
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
local events = when:match('^event:(.+)$')
|
|
334
|
+
if events then
|
|
335
|
+
local ev, patt = events:match('^(.+)~(.+)$')
|
|
336
|
+
local event = vim.split(ev or events, ',', { trimempty = true })
|
|
337
|
+
local pattern = vim.split(patt or '', ',', { trimempty = true })
|
|
338
|
+
H.make_defer_autocmd(event, pattern, f, trace)
|
|
339
|
+
return
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
local filetypes = when:match('^filetype:(.+)$')
|
|
343
|
+
if filetypes then
|
|
344
|
+
local ft_arr = vim.split(filetypes, ',')
|
|
345
|
+
-- NOTE: Needs `vim.schedule_wrap()` for a correct redetect. This also
|
|
346
|
+
-- prompts using `H.execute_now` and not rely on `H.make_defer_autocmd`.
|
|
347
|
+
local f_and_redetect = vim.schedule_wrap(function()
|
|
348
|
+
-- Look out for new 'ftdetect' scripts by comparing before and after
|
|
349
|
+
local ftdetect_scripts_before = vim.api.nvim_get_runtime_file('ftdetect/*.{vim,lua}', true)
|
|
350
|
+
|
|
351
|
+
local ok = H.execute_now(f, trace)
|
|
352
|
+
|
|
353
|
+
-- Skip redetect if there was error or detection is disabled
|
|
354
|
+
if not (ok and vim.g.did_load_filetypes == 1) then return end
|
|
355
|
+
|
|
356
|
+
local ftdetect_scripts_after = vim.api.nvim_get_runtime_file('ftdetect/*.{vim,lua}', true)
|
|
357
|
+
local needs_redetect = not vim.deep_equal(ftdetect_scripts_before, ftdetect_scripts_after)
|
|
358
|
+
for _, buf_id in ipairs(vim.api.nvim_list_bufs()) do
|
|
359
|
+
H.redetect_filetypes(buf_id, ft_arr, needs_redetect)
|
|
360
|
+
end
|
|
361
|
+
end)
|
|
362
|
+
return H.make_defer_autocmd('FileType', ft_arr, f_and_redetect)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
H.error('Could not parse `when` in `safely`')
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
H.execute_now = function(f, init_trace)
|
|
369
|
+
local ok, err = xpcall(f, function(e) return debug.traceback(e .. '\n', 2) end)
|
|
370
|
+
if ok then return true end
|
|
371
|
+
init_trace = init_trace == nil and '' or ('\n\nTraceback of `MiniMisc.safely()` call:\n' .. init_trace)
|
|
372
|
+
H.notify('Error during safe execution: ' .. err .. init_trace, 'WARN')
|
|
373
|
+
return false
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
H.safely_cache = { later = {} }
|
|
377
|
+
|
|
378
|
+
H.execute_later = function()
|
|
379
|
+
local timer = assert(vim.loop.new_timer())
|
|
380
|
+
local f
|
|
381
|
+
f = vim.schedule_wrap(function()
|
|
382
|
+
local cb = H.safely_cache.later[1]
|
|
383
|
+
if cb == nil then
|
|
384
|
+
if not timer:is_closing() then timer:close() end
|
|
385
|
+
return
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
table.remove(H.safely_cache.later, 1)
|
|
389
|
+
H.execute_now(cb.f, cb.trace)
|
|
390
|
+
timer:start(1, 0, f)
|
|
391
|
+
end)
|
|
392
|
+
-- Space out "later" executions to be sure that they don't block anything
|
|
393
|
+
timer:start(1, 0, f)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
H.make_defer_autocmd = function(event, pattern, f, trace)
|
|
397
|
+
if type(pattern) == 'table' and #pattern == 0 then pattern = nil end
|
|
398
|
+
|
|
399
|
+
local au_id
|
|
400
|
+
local function cb()
|
|
401
|
+
-- Execute exactly once, not once per event or pattern match
|
|
402
|
+
-- Delete before executing `f` to account for nested events
|
|
403
|
+
vim.api.nvim_del_autocmd(au_id)
|
|
404
|
+
H.execute_now(f, trace)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
local group = vim.api.nvim_create_augroup('MiniMiscSafely', { clear = false })
|
|
408
|
+
local opts = { group = group, pattern = pattern, callback = cb, nested = true }
|
|
409
|
+
au_id = vim.api.nvim_create_autocmd(event, opts)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
H.redetect_filetypes = function(buf_id, ft_arr, needs_redetect)
|
|
413
|
+
if not vim.api.nvim_buf_is_loaded(buf_id) then return end
|
|
414
|
+
|
|
415
|
+
vim.api.nvim_buf_call(buf_id, function()
|
|
416
|
+
-- Try detecting new filetypes
|
|
417
|
+
if needs_redetect and vim.bo.buftype == '' then vim.cmd('filetype detect') end
|
|
418
|
+
|
|
419
|
+
-- Force execution of 'ftplugin' scripts for matched filetypes
|
|
420
|
+
if vim.tbl_contains(ft_arr, vim.bo.filetype) then vim.bo.filetype = vim.bo.filetype end
|
|
421
|
+
end)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
--- Set up automated change of current directory
|
|
425
|
+
---
|
|
426
|
+
--- What it does:
|
|
427
|
+
--- - Creates autocommand which on every |BufEnter| event with |MiniMisc.find_root()|
|
|
428
|
+
--- finds root directory for current buffer file and sets |current-directory|
|
|
429
|
+
--- to it (using |chdir()|).
|
|
430
|
+
--- - Resets |'autochdir'| to `false`.
|
|
431
|
+
---
|
|
432
|
+
---@param names table|function|nil Forwarded to |MiniMisc.find_root()|.
|
|
433
|
+
---@param fallback function|nil Forwarded to |MiniMisc.find_root()|.
|
|
434
|
+
---
|
|
435
|
+
---@usage >lua
|
|
436
|
+
--- require('mini.misc').setup()
|
|
437
|
+
--- MiniMisc.setup_auto_root()
|
|
438
|
+
--- <
|
|
439
|
+
MiniMisc.setup_auto_root = function(names, fallback)
|
|
440
|
+
names = names or { '.git', 'Makefile' }
|
|
441
|
+
if not (H.is_array_of(names, H.is_string) or vim.is_callable(names)) then
|
|
442
|
+
H.error('Argument `names` of `setup_auto_root()` should be array of string file names or a callable.')
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
fallback = fallback or function() return nil end
|
|
446
|
+
if not vim.is_callable(fallback) then H.error('Argument `fallback` of `setup_auto_root()` should be callable.') end
|
|
447
|
+
|
|
448
|
+
-- Disable conflicting option
|
|
449
|
+
vim.o.autochdir = false
|
|
450
|
+
|
|
451
|
+
-- Create autocommand
|
|
452
|
+
local set_root = vim.schedule_wrap(function(data)
|
|
453
|
+
if data.buf ~= vim.api.nvim_get_current_buf() then return end
|
|
454
|
+
local root = MiniMisc.find_root(data.buf, names, fallback)
|
|
455
|
+
if root == nil then return end
|
|
456
|
+
vim.fn.chdir(root)
|
|
457
|
+
end)
|
|
458
|
+
local augroup = vim.api.nvim_create_augroup('MiniMiscAutoRoot', {})
|
|
459
|
+
local opts = { group = augroup, nested = true, callback = set_root, desc = 'Find root and change current directory' }
|
|
460
|
+
vim.api.nvim_create_autocmd('BufEnter', opts)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
--- Find root directory
|
|
464
|
+
---
|
|
465
|
+
--- Based on a buffer name (full path to file opened in a buffer) find a root
|
|
466
|
+
--- directory. If buffer is not associated with file, returns `nil`.
|
|
467
|
+
---
|
|
468
|
+
--- Root directory is a directory containing at least one of pre-defined files.
|
|
469
|
+
--- It is searched using |vim.fs.find()| with `upward = true` starting from
|
|
470
|
+
--- directory of current buffer file until first occurrence of root file(s).
|
|
471
|
+
---
|
|
472
|
+
--- Notes:
|
|
473
|
+
--- - Uses directory path caching to speed up computations. This means that no
|
|
474
|
+
--- changes in root directory will be detected after directory path was already
|
|
475
|
+
--- used in this function. Reload Neovim to account for that.
|
|
476
|
+
---
|
|
477
|
+
---@param buf_id number|nil Buffer identifier (see |bufnr()|) to use.
|
|
478
|
+
--- Default: 0 for current.
|
|
479
|
+
---@param names table|function|nil Array of file names or a callable used to
|
|
480
|
+
--- identify a root directory. Forwarded to |vim.fs.find()|.
|
|
481
|
+
--- Default: `{ '.git', 'Makefile' }`.
|
|
482
|
+
---@param fallback function|nil Callable fallback to use if no root is found
|
|
483
|
+
--- with |vim.fs.find()|. Will be called with a buffer path and should return
|
|
484
|
+
--- a valid directory path.
|
|
485
|
+
MiniMisc.find_root = function(buf_id, names, fallback)
|
|
486
|
+
buf_id = buf_id or 0
|
|
487
|
+
names = names or { '.git', 'Makefile' }
|
|
488
|
+
fallback = fallback or function() return nil end
|
|
489
|
+
|
|
490
|
+
if not H.is_valid_buf(buf_id) then H.error('Argument `buf_id` of `find_root()` should be valid buffer id.') end
|
|
491
|
+
if not (H.is_array_of(names, H.is_string) or vim.is_callable(names)) then
|
|
492
|
+
H.error('Argument `names` of `find_root()` should be array of string file names or a callable.')
|
|
493
|
+
end
|
|
494
|
+
if not vim.is_callable(fallback) then H.error('Argument `fallback` of `find_root()` should be callable.') end
|
|
495
|
+
|
|
496
|
+
-- Compute directory to start search from. NOTEs on why not using file path:
|
|
497
|
+
-- - This has better performance because `vim.fs.find()` is called less.
|
|
498
|
+
-- - *Needs* to be a directory for callable `names` to work.
|
|
499
|
+
-- - Later search is done including initial `path` if directory, so this
|
|
500
|
+
-- should work for detecting buffer directory as root.
|
|
501
|
+
local path = vim.api.nvim_buf_get_name(buf_id)
|
|
502
|
+
if path == '' then return end
|
|
503
|
+
local dir_path = vim.fs.dirname(path)
|
|
504
|
+
|
|
505
|
+
-- Try using cache
|
|
506
|
+
local res = H.root_cache[dir_path]
|
|
507
|
+
if res ~= nil then return res end
|
|
508
|
+
|
|
509
|
+
-- Find root
|
|
510
|
+
local root_file = vim.fs.find(names, { path = dir_path, upward = true })[1]
|
|
511
|
+
if root_file ~= nil then
|
|
512
|
+
res = vim.fs.dirname(root_file)
|
|
513
|
+
else
|
|
514
|
+
res = fallback(path)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
-- Use absolute path to an existing directory
|
|
518
|
+
if type(res) ~= 'string' then return end
|
|
519
|
+
res = vim.fs.normalize(vim.fn.fnamemodify(res, ':p'))
|
|
520
|
+
if vim.fn.isdirectory(res) == 0 then return end
|
|
521
|
+
|
|
522
|
+
-- Cache result per directory path
|
|
523
|
+
H.root_cache[dir_path] = res
|
|
524
|
+
|
|
525
|
+
return res
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
H.root_cache = {}
|
|
529
|
+
|
|
530
|
+
--- Set up terminal background synchronization
|
|
531
|
+
---
|
|
532
|
+
--- What it does:
|
|
533
|
+
--- - Checks if terminal emulator supports OSC 11 control sequence through
|
|
534
|
+
--- appropriate `stdout`. Stops if not.
|
|
535
|
+
--- - Creates autocommands for |ColorScheme| and |VimResume| events, which
|
|
536
|
+
--- change terminal background to have same color as |guibg| of |hl-Normal|.
|
|
537
|
+
--- - Creates autocommands for |VimLeavePre| and |VimSuspend| events which set
|
|
538
|
+
--- terminal background back to its original color.
|
|
539
|
+
--- - Synchronizes background immediately to allow not depend on loading order.
|
|
540
|
+
---
|
|
541
|
+
--- Primary use case is to remove possible "frame" around current Neovim instance
|
|
542
|
+
--- which appears if Neovim's |hl-Normal| background color differs from what is
|
|
543
|
+
--- used by terminal emulator itself.
|
|
544
|
+
---
|
|
545
|
+
--- Works only on Neovim>=0.10.
|
|
546
|
+
---
|
|
547
|
+
---@param opts table|nil Options. Possible fields:
|
|
548
|
+
--- - <explicit_reset> `(boolean)` - whether to reset terminal background by
|
|
549
|
+
--- explicitly setting it to the color it had when this function was called.
|
|
550
|
+
--- Set to `true` if terminal emulator doesn't support OSC 111 control sequence.
|
|
551
|
+
--- Default: `false`.
|
|
552
|
+
MiniMisc.setup_termbg_sync = function(opts)
|
|
553
|
+
-- Handling `'\027]11;?\007'` response was added in Neovim 0.10
|
|
554
|
+
if vim.fn.has('nvim-0.10') == 0 then return H.notify('`setup_termbg_sync()` requires Neovim>=0.10', 'WARN') end
|
|
555
|
+
|
|
556
|
+
-- Proceed only if there is a valid stdout to use
|
|
557
|
+
local has_stdout_tty = false
|
|
558
|
+
for _, ui in ipairs(vim.api.nvim_list_uis()) do
|
|
559
|
+
has_stdout_tty = has_stdout_tty or ui.stdout_tty
|
|
560
|
+
end
|
|
561
|
+
if not has_stdout_tty then return end
|
|
562
|
+
|
|
563
|
+
opts = vim.tbl_extend('force', { explicit_reset = false }, opts or {})
|
|
564
|
+
|
|
565
|
+
-- Choose a method for how terminal emulator background is reset
|
|
566
|
+
local reset = function() io.stdout:write('\027]111\027\\') end
|
|
567
|
+
if opts.explicit_reset then reset = function() io.stdout:write('\027]11;' .. H.termbg_init .. '\007') end end
|
|
568
|
+
|
|
569
|
+
local augroup = vim.api.nvim_create_augroup('MiniMiscTermbgSync', { clear = true })
|
|
570
|
+
local track_au_id, bad_responses, had_proper_response = nil, {}, false
|
|
571
|
+
local f = function(args)
|
|
572
|
+
-- Process proper response only once
|
|
573
|
+
if had_proper_response then return end
|
|
574
|
+
|
|
575
|
+
-- Neovim=0.10 uses string sequence as response, while Neovim>=0.11 sets it
|
|
576
|
+
-- in `sequence` table field
|
|
577
|
+
local seq = type(args.data) == 'table' and args.data.sequence or args.data
|
|
578
|
+
local ok, termbg = pcall(H.parse_osc11, seq)
|
|
579
|
+
if not (ok and type(termbg) == 'string') then return table.insert(bad_responses, seq) end
|
|
580
|
+
had_proper_response = true
|
|
581
|
+
pcall(vim.api.nvim_del_autocmd, track_au_id)
|
|
582
|
+
|
|
583
|
+
-- Set up reset to the color returned from the very first call
|
|
584
|
+
H.termbg_init = H.termbg_init or termbg
|
|
585
|
+
vim.api.nvim_create_autocmd({ 'VimLeavePre', 'VimSuspend' }, { group = augroup, callback = reset })
|
|
586
|
+
|
|
587
|
+
-- Set up sync
|
|
588
|
+
local sync = function()
|
|
589
|
+
local normal = vim.api.nvim_get_hl_by_name('Normal', true)
|
|
590
|
+
if normal.background == nil then return reset() end
|
|
591
|
+
-- NOTE: use `io.stdout` instead of `io.write` to ensure correct target
|
|
592
|
+
-- Otherwise after `io.output(file); file:close()` there is an error
|
|
593
|
+
io.stdout:write(string.format('\027]11;#%06x\007', normal.background))
|
|
594
|
+
end
|
|
595
|
+
vim.api.nvim_create_autocmd({ 'VimResume', 'ColorScheme' }, { group = augroup, callback = sync })
|
|
596
|
+
|
|
597
|
+
-- Sync immediately
|
|
598
|
+
sync()
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
-- Ask about current background color and process the proper response.
|
|
602
|
+
-- NOTE: do not use `once = true` as Neovim itself triggers `TermResponse`
|
|
603
|
+
-- events during startup, so this should wait until the proper one.
|
|
604
|
+
track_au_id = vim.api.nvim_create_autocmd('TermResponse', { group = augroup, callback = f, nested = true })
|
|
605
|
+
io.stdout:write('\027]11;?\007')
|
|
606
|
+
vim.defer_fn(function()
|
|
607
|
+
if had_proper_response then return end
|
|
608
|
+
pcall(vim.api.nvim_del_augroup_by_id, augroup)
|
|
609
|
+
local bad_suffix = #bad_responses == 0 and '' or (', only these: ' .. vim.inspect(bad_responses))
|
|
610
|
+
local msg = '`setup_termbg_sync()` did not get proper response from terminal emulator' .. bad_suffix
|
|
611
|
+
H.notify(msg, 'WARN')
|
|
612
|
+
end, 1000)
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
-- Source: 'runtime/lua/vim/_defaults.lua' in Neovim source
|
|
616
|
+
H.parse_osc11 = function(x)
|
|
617
|
+
local r, g, b = x:match('^\027%]11;rgb:(%x+)/(%x+)/(%x+)$')
|
|
618
|
+
if not (r and g and b) then
|
|
619
|
+
local a
|
|
620
|
+
r, g, b, a = x:match('^\027%]11;rgba:(%x+)/(%x+)/(%x+)/(%x+)$')
|
|
621
|
+
if not (a and a:len() <= 4) then return end
|
|
622
|
+
end
|
|
623
|
+
if not (r and g and b) then return end
|
|
624
|
+
if not (r:len() <= 4 and g:len() <= 4 and b:len() <= 4) then return end
|
|
625
|
+
local parse_osc_hex = function(c) return c:len() == 1 and (c .. c) or c:sub(1, 2) end
|
|
626
|
+
return '#' .. parse_osc_hex(r) .. parse_osc_hex(g) .. parse_osc_hex(b)
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
--- Restore cursor position on file open
|
|
630
|
+
---
|
|
631
|
+
--- When reopening a file this will make sure the cursor is placed back to the
|
|
632
|
+
--- position where you left before. This implements |restore-cursor| in a nicer way.
|
|
633
|
+
--- File should have a recognized file type (see |'filetype'|) and be opened in
|
|
634
|
+
--- a normal buffer (see |'buftype'|).
|
|
635
|
+
---
|
|
636
|
+
--- Note: it relies on file mark data stored in |'shadafile'| (see |shada-f|).
|
|
637
|
+
--- Be sure to enable it.
|
|
638
|
+
---
|
|
639
|
+
---@param opts table|nil Options. Possible fields:
|
|
640
|
+
--- - <center> - (boolean) Center the window after we restored the cursor.
|
|
641
|
+
--- Default: `true`.
|
|
642
|
+
--- - <ignore_filetype> - Array with file types to be ignored (see |'filetype'|).
|
|
643
|
+
--- Default: `{ "gitcommit", "gitrebase" }`.
|
|
644
|
+
---
|
|
645
|
+
---@usage >lua
|
|
646
|
+
--- require('mini.misc').setup_restore_cursor()
|
|
647
|
+
--- <
|
|
648
|
+
MiniMisc.setup_restore_cursor = function(opts)
|
|
649
|
+
opts = opts or {}
|
|
650
|
+
|
|
651
|
+
opts.ignore_filetype = opts.ignore_filetype or { 'gitcommit', 'gitrebase' }
|
|
652
|
+
if not H.is_array_of(opts.ignore_filetype, H.is_string) then
|
|
653
|
+
H.error('In `setup_restore_cursor()` `opts.ignore_filetype` should be an array of strings.')
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
if opts.center == nil then opts.center = true end
|
|
657
|
+
if type(opts.center) ~= 'boolean' then H.error('In `setup_restore_cursor()` `opts.center` should be a boolean.') end
|
|
658
|
+
|
|
659
|
+
-- Create autocommand which runs once on `FileType` for every new buffer
|
|
660
|
+
local augroup = vim.api.nvim_create_augroup('MiniMiscRestoreCursor', {})
|
|
661
|
+
vim.api.nvim_create_autocmd('BufReadPre', {
|
|
662
|
+
group = augroup,
|
|
663
|
+
callback = function(data)
|
|
664
|
+
vim.api.nvim_create_autocmd('FileType', {
|
|
665
|
+
buffer = data.buf,
|
|
666
|
+
once = true,
|
|
667
|
+
callback = function() H.restore_cursor(opts) end,
|
|
668
|
+
})
|
|
669
|
+
end,
|
|
670
|
+
})
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
H.restore_cursor = function(opts)
|
|
674
|
+
-- Stop if not a normal buffer
|
|
675
|
+
if vim.bo.buftype ~= '' then return end
|
|
676
|
+
|
|
677
|
+
-- Stop if filetype is ignored
|
|
678
|
+
if vim.tbl_contains(opts.ignore_filetype, vim.bo.filetype) then return end
|
|
679
|
+
|
|
680
|
+
-- Stop if line is already specified (like during start with `nvim file +num`)
|
|
681
|
+
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
|
|
682
|
+
if cursor_line > 1 then return end
|
|
683
|
+
|
|
684
|
+
-- Stop if can't restore proper line for some reason
|
|
685
|
+
local mark_line = vim.api.nvim_buf_get_mark(0, [["]])[1]
|
|
686
|
+
local n_lines = vim.api.nvim_buf_line_count(0)
|
|
687
|
+
if not (1 <= mark_line and mark_line <= n_lines) then return end
|
|
688
|
+
|
|
689
|
+
-- Restore cursor and open just enough folds
|
|
690
|
+
vim.cmd([[normal! g`"zv]])
|
|
691
|
+
|
|
692
|
+
-- Center window
|
|
693
|
+
if opts.center then vim.cmd('normal! zz') end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
--- Compute summary statistics of numerical array
|
|
697
|
+
---
|
|
698
|
+
--- This might be useful to compute summary of time benchmarking with
|
|
699
|
+
--- |MiniMisc.bench_time()|.
|
|
700
|
+
---
|
|
701
|
+
---@param t table Array (table suitable for `ipairs`) of numbers.
|
|
702
|
+
---
|
|
703
|
+
---@return table Table with summary values under following keys (may be
|
|
704
|
+
--- extended in the future): <maximum>, <mean>, <median>, <minimum>, <n>
|
|
705
|
+
--- (number of elements), <sd> (sample standard deviation).
|
|
706
|
+
MiniMisc.stat_summary = function(t)
|
|
707
|
+
if not H.is_array_of(t, H.is_number) then
|
|
708
|
+
H.error('Input of `MiniMisc.stat_summary()` should be an array of numbers.')
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
-- Welford algorithm of computing variance
|
|
712
|
+
-- Source: https://www.johndcook.com/blog/skewness_kurtosis/
|
|
713
|
+
local n = #t
|
|
714
|
+
local delta, m1, m2 = 0, 0, 0
|
|
715
|
+
local minimum, maximum = math.huge, -math.huge
|
|
716
|
+
for i, x in ipairs(t) do
|
|
717
|
+
delta = x - m1
|
|
718
|
+
m1 = m1 + delta / i
|
|
719
|
+
m2 = m2 + delta * (x - m1)
|
|
720
|
+
|
|
721
|
+
-- Extremums
|
|
722
|
+
minimum = x < minimum and x or minimum
|
|
723
|
+
maximum = x > maximum and x or maximum
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
return {
|
|
727
|
+
maximum = maximum,
|
|
728
|
+
mean = m1,
|
|
729
|
+
median = H.compute_median(t),
|
|
730
|
+
minimum = minimum,
|
|
731
|
+
n = n,
|
|
732
|
+
sd = math.sqrt(n > 1 and m2 / (n - 1) or 0),
|
|
733
|
+
}
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
H.compute_median = function(t)
|
|
737
|
+
local n = #t
|
|
738
|
+
if n == 0 then return 0 end
|
|
739
|
+
|
|
740
|
+
local t_sorted = vim.deepcopy(t)
|
|
741
|
+
table.sort(t_sorted)
|
|
742
|
+
return 0.5 * (t_sorted[math.ceil(0.5 * n)] + t_sorted[math.ceil(0.5 * (n + 1))])
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
--- Return "first" elements of table as decided by `pairs`
|
|
746
|
+
---
|
|
747
|
+
--- Note: order of elements might vary.
|
|
748
|
+
---
|
|
749
|
+
---@param t table Input table.
|
|
750
|
+
---@param n number|nil Maximum number of first elements. Default: 5.
|
|
751
|
+
---
|
|
752
|
+
---@return table Table with at most `n` first elements of `t` (with same keys).
|
|
753
|
+
MiniMisc.tbl_head = function(t, n)
|
|
754
|
+
n = n or 5
|
|
755
|
+
local res, n_res = {}, 0
|
|
756
|
+
for k, val in pairs(t) do
|
|
757
|
+
if n_res >= n then return res end
|
|
758
|
+
res[k] = val
|
|
759
|
+
n_res = n_res + 1
|
|
760
|
+
end
|
|
761
|
+
return res
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
--- Return "last" elements of table as decided by `pairs`
|
|
765
|
+
---
|
|
766
|
+
--- This function makes two passes through elements of `t`:
|
|
767
|
+
--- - First to count number of elements.
|
|
768
|
+
--- - Second to construct result.
|
|
769
|
+
---
|
|
770
|
+
--- Note: order of elements might vary.
|
|
771
|
+
---
|
|
772
|
+
---@param t table Input table.
|
|
773
|
+
---@param n number|nil Maximum number of last elements. Default: 5.
|
|
774
|
+
---
|
|
775
|
+
---@return table Table with at most `n` last elements of `t` (with same keys).
|
|
776
|
+
MiniMisc.tbl_tail = function(t, n)
|
|
777
|
+
n = n or 5
|
|
778
|
+
|
|
779
|
+
-- Count number of elements on first pass
|
|
780
|
+
local n_all = 0
|
|
781
|
+
for _, _ in pairs(t) do
|
|
782
|
+
n_all = n_all + 1
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
-- Construct result on second pass
|
|
786
|
+
local res = {}
|
|
787
|
+
local i, start_i = 0, n_all - n + 1
|
|
788
|
+
for k, val in pairs(t) do
|
|
789
|
+
i = i + 1
|
|
790
|
+
if i >= start_i then res[k] = val end
|
|
791
|
+
end
|
|
792
|
+
return res
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
--- Add possibility of nested comment leader
|
|
796
|
+
---
|
|
797
|
+
--- This works by parsing |'commentstring'| buffer option, extracting
|
|
798
|
+
--- non-whitespace comment leader (symbols on the left of commented line), and
|
|
799
|
+
--- locally modifying |'comments'| option (by prepending `n:<leader>`). Does
|
|
800
|
+
--- nothing if |'commentstring'| is empty or has comment symbols both in front
|
|
801
|
+
--- and back (like `/*%s*/`).
|
|
802
|
+
---
|
|
803
|
+
--- Nested comment leader added with this function is useful for formatting
|
|
804
|
+
--- nested comments. For example, have in Lua "first-level" comments with `--`
|
|
805
|
+
--- and "second-level" comments with `----`. With nested comment leader second
|
|
806
|
+
--- type can be formatted with `gq` in the same way as first one.
|
|
807
|
+
---
|
|
808
|
+
--- Recommended usage is with |autocmd|: >lua
|
|
809
|
+
---
|
|
810
|
+
--- local use_nested_comments = function() MiniMisc.use_nested_comments() end
|
|
811
|
+
--- vim.api.nvim_create_autocmd('BufEnter', { callback = use_nested_comments })
|
|
812
|
+
--- <
|
|
813
|
+
--- Note: for most filetypes |'commentstring'| option is added only when buffer
|
|
814
|
+
--- with this filetype is entered, so using non-current `buf_id` can not lead
|
|
815
|
+
--- to desired effect.
|
|
816
|
+
---
|
|
817
|
+
---@param buf_id number|nil Buffer identifier (see |bufnr()|) in which function
|
|
818
|
+
--- will operate. Default: 0 for current.
|
|
819
|
+
MiniMisc.use_nested_comments = function(buf_id)
|
|
820
|
+
buf_id = buf_id or 0
|
|
821
|
+
|
|
822
|
+
local commentstring = vim.bo[buf_id].commentstring
|
|
823
|
+
if commentstring == '' then return end
|
|
824
|
+
|
|
825
|
+
-- Extract raw comment leader from 'commentstring' option
|
|
826
|
+
local comment_parts = vim.tbl_filter(function(x) return x ~= '' end, vim.split(commentstring, '%s', true))
|
|
827
|
+
|
|
828
|
+
-- Don't do anything if 'commentstring' is like '/*%s*/' (as in 'json')
|
|
829
|
+
if #comment_parts > 1 then return end
|
|
830
|
+
|
|
831
|
+
-- Get comment leader by removing whitespace
|
|
832
|
+
local leader = vim.trim(comment_parts[1])
|
|
833
|
+
|
|
834
|
+
local comments = vim.bo[buf_id].comments
|
|
835
|
+
vim.bo[buf_id].comments = string.format('n:%s,%s', leader, comments)
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
--- Zoom in and out of a buffer, making it full screen in a floating window
|
|
839
|
+
---
|
|
840
|
+
--- This function is useful when working with multiple windows but temporarily
|
|
841
|
+
--- needing to zoom into one to see more of the code from that buffer. Call it
|
|
842
|
+
--- again (without arguments) to zoom out.
|
|
843
|
+
---
|
|
844
|
+
---@param buf_id number|nil Buffer identifier (see |bufnr()|) to be zoomed.
|
|
845
|
+
--- Default: 0 for current.
|
|
846
|
+
---@param config table|nil Optional config for window (as for |nvim_open_win()|).
|
|
847
|
+
---
|
|
848
|
+
---@return boolean Whether current buffer is zoomed in.
|
|
849
|
+
MiniMisc.zoom = function(buf_id, config)
|
|
850
|
+
-- Hide
|
|
851
|
+
if H.zoom_winid and vim.api.nvim_win_is_valid(H.zoom_winid) then
|
|
852
|
+
pcall(vim.api.nvim_del_augroup_by_name, 'MiniMiscZoom')
|
|
853
|
+
vim.api.nvim_win_close(H.zoom_winid, true)
|
|
854
|
+
H.zoom_winid = nil
|
|
855
|
+
return false
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
-- Show
|
|
859
|
+
local compute_config = function()
|
|
860
|
+
-- Use precise dimensions for no Command line interactions (better scroll)
|
|
861
|
+
local max_width, max_height = vim.o.columns, vim.o.lines - vim.o.cmdheight
|
|
862
|
+
local default_border = (vim.fn.exists('+winborder') == 0 or vim.o.winborder == '') and 'none' or nil
|
|
863
|
+
--stylua: ignore
|
|
864
|
+
local default_config = {
|
|
865
|
+
relative = 'editor', row = 0, col = 0,
|
|
866
|
+
width = max_width, height = max_height,
|
|
867
|
+
title = ' Zoom ', border = default_border,
|
|
868
|
+
}
|
|
869
|
+
local res = vim.tbl_deep_extend('force', default_config, config or {})
|
|
870
|
+
|
|
871
|
+
-- Adjust dimensions to fit actually present border parts
|
|
872
|
+
local bor = res.border == 'none' and { '' } or res.border
|
|
873
|
+
local n = type(bor) == 'table' and #bor or 0
|
|
874
|
+
local height_offset = n == 0 and 2 or ((bor[1 % n + 1] == '' and 0 or 1) + (bor[5 % n + 1] == '' and 0 or 1))
|
|
875
|
+
local width_offset = n == 0 and 2 or ((bor[3 % n + 1] == '' and 0 or 1) + (bor[7 % n + 1] == '' and 0 or 1))
|
|
876
|
+
res.height = math.min(res.height, max_height - height_offset)
|
|
877
|
+
res.width = math.min(res.width, max_width - width_offset)
|
|
878
|
+
|
|
879
|
+
-- Ensure proper title
|
|
880
|
+
if type(res.title) == 'string' then res.title = H.fit_to_width(res.title, res.width) end
|
|
881
|
+
|
|
882
|
+
return res
|
|
883
|
+
end
|
|
884
|
+
H.zoom_winid = vim.api.nvim_open_win(buf_id or 0, true, compute_config())
|
|
885
|
+
vim.wo[H.zoom_winid].winblend = 0
|
|
886
|
+
vim.cmd('normal! zz')
|
|
887
|
+
|
|
888
|
+
-- - Make sure zoom window is adjusting to changes in its hyperparameters
|
|
889
|
+
local gr = vim.api.nvim_create_augroup('MiniMiscZoom', { clear = true })
|
|
890
|
+
local adjust_config = function()
|
|
891
|
+
if not (type(H.zoom_winid) == 'number' and vim.api.nvim_win_is_valid(H.zoom_winid)) then
|
|
892
|
+
pcall(vim.api.nvim_del_augroup_by_name, 'MiniMiscZoom')
|
|
893
|
+
return
|
|
894
|
+
end
|
|
895
|
+
vim.api.nvim_win_set_config(H.zoom_winid, compute_config())
|
|
896
|
+
end
|
|
897
|
+
vim.api.nvim_create_autocmd('VimResized', { group = gr, callback = adjust_config })
|
|
898
|
+
vim.api.nvim_create_autocmd('OptionSet', { group = gr, pattern = 'cmdheight', callback = adjust_config })
|
|
899
|
+
return true
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
-- Helper data ================================================================
|
|
903
|
+
-- Module default config
|
|
904
|
+
H.default_config = vim.deepcopy(MiniMisc.config)
|
|
905
|
+
|
|
906
|
+
-- Window identifier of current zoom (for `zoom()`)
|
|
907
|
+
H.zoom_winid = nil
|
|
908
|
+
|
|
909
|
+
-- Helper functionality =======================================================
|
|
910
|
+
-- Settings -------------------------------------------------------------------
|
|
911
|
+
H.setup_config = function(config)
|
|
912
|
+
H.check_type('config', config, 'table', true)
|
|
913
|
+
-- NOTE: Don't use `tbl_deep_extend` to prefer full input `make_global` array
|
|
914
|
+
-- Needs adjusting if there is a new setting with nested tables
|
|
915
|
+
config = vim.tbl_extend('force', vim.deepcopy(H.default_config), config or {})
|
|
916
|
+
|
|
917
|
+
H.check_type('make_global', config.make_global, 'table')
|
|
918
|
+
for _, v in pairs(config.make_global) do
|
|
919
|
+
if MiniMisc[v] == nil then H.error("`make_global` should be a table with exported 'mini.misc' methods") end
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
return config
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
H.apply_config = function(config)
|
|
926
|
+
MiniMisc.config = config
|
|
927
|
+
|
|
928
|
+
for _, v in pairs(config.make_global) do
|
|
929
|
+
_G[v] = MiniMisc[v]
|
|
930
|
+
end
|
|
931
|
+
end
|
|
932
|
+
|
|
933
|
+
-- Utilities ------------------------------------------------------------------
|
|
934
|
+
H.error = function(msg) error('(mini.misc) ' .. msg) end
|
|
935
|
+
|
|
936
|
+
H.check_type = function(name, val, ref, allow_nil)
|
|
937
|
+
if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
|
|
938
|
+
H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
H.notify = function(msg, level) vim.notify('(mini.misc) ' .. msg, vim.log.levels[level]) end
|
|
942
|
+
|
|
943
|
+
H.is_valid_buf = function(buf_id) return type(buf_id) == 'number' and vim.api.nvim_buf_is_valid(buf_id) end
|
|
944
|
+
|
|
945
|
+
H.is_array_of = function(x, predicate)
|
|
946
|
+
if not H.islist(x) then return false end
|
|
947
|
+
for _, v in ipairs(x) do
|
|
948
|
+
if not predicate(v) then return false end
|
|
949
|
+
end
|
|
950
|
+
return true
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
H.is_number = function(x) return type(x) == 'number' end
|
|
954
|
+
|
|
955
|
+
H.is_string = function(x) return type(x) == 'string' end
|
|
956
|
+
|
|
957
|
+
H.fit_to_width = function(text, width)
|
|
958
|
+
local t_width = vim.fn.strchars(text)
|
|
959
|
+
return t_width <= width and text or ('…' .. vim.fn.strcharpart(text, t_width - width + 1, width - 1))
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
H.copy_tables = function(x)
|
|
963
|
+
return type(x) == 'table' and setmetatable(vim.tbl_map(H.copy_tables, x), getmetatable(x)) or x
|
|
964
|
+
end
|
|
965
|
+
|
|
966
|
+
-- TODO: Remove after compatibility with Neovim=0.9 is dropped
|
|
967
|
+
H.islist = vim.fn.has('nvim-0.10') == 1 and vim.islist or vim.tbl_islist
|
|
968
|
+
|
|
969
|
+
return MiniMisc
|