aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-12-25 10:21:13 +0800
committerGitHub <noreply@github.com>2023-12-25 10:21:13 +0800
commit2877672d70e76f71ae1190090b8aea7044d458be (patch)
treec078af69d7a394a8e83f2316cf707548d70368f4
parent2ff2785c396e66c285fecf5b151d8f8863f9d4e6 (diff)
downloadrneovim-2877672d70e76f71ae1190090b8aea7044d458be.tar.gz
rneovim-2877672d70e76f71ae1190090b8aea7044d458be.tar.bz2
rneovim-2877672d70e76f71ae1190090b8aea7044d458be.zip
feat(health): make :checkhealth support more split modifiers (#26731)
-rw-r--r--runtime/doc/news.txt3
-rw-r--r--runtime/doc/windows.txt7
-rw-r--r--runtime/lua/vim/health.lua29
-rw-r--r--src/nvim/eval.c33
-rw-r--r--src/nvim/ex_docmd.c44
-rw-r--r--test/functional/plugin/health_spec.lua147
6 files changed, 125 insertions, 138 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 9b40c4a596..454c9becc5 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -366,7 +366,8 @@ The following changes to existing APIs or features add new behavior.
• Attempting to set an invalid keycode option (e.g. `set t_foo=123`) no longer
gives an error.
-• |:checkhealth| buffer can now be opened in a split window using |:vertical| or |:horizontal|.
+• |:checkhealth| buffer can now be opened in a split window using modifiers like
+ |:vertical|, |:horizontal| and |:botright|.
==============================================================================
REMOVED FEATURES *news-removed*
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index d6fce89f23..b71e7c80ab 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -242,9 +242,10 @@ and 'winminwidth' are relevant.
*:hor* *:horizontal*
:hor[izontal] {cmd}
Execute {cmd}. Currently only makes a difference for
- `horizontal wincmd =`, which will equalize windows only
- horizontally, and |:terminal|, which will open a |terminal|
- buffer in a split window.
+ the following commands:
+ - `:wincmd =`: equalize windows only horizontally.
+ - |:terminal|: open a |terminal| buffer in a split window.
+ - |:checkhealth|: open a healthcheck buffer in a split window.
:lefta[bove] {cmd} *:lefta* *:leftabove*
:abo[veleft] {cmd} *:abo* *:aboveleft*
diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua
index 4659ab1694..6c96a703bb 100644
--- a/runtime/lua/vim/health.lua
+++ b/runtime/lua/vim/health.lua
@@ -266,29 +266,22 @@ M._complete = function()
return vim.tbl_keys(unique)
end
--- Runs the specified healthchecks.
--- Runs all discovered healthchecks if plugin_names is empty.
--- splitmod controls how the healthcheck window opens: "vertical", "horizontal" or "tab"
-function M._check(splitmod, plugin_names)
+--- Runs the specified healthchecks.
+--- Runs all discovered healthchecks if plugin_names is empty.
+---
+--- @param mods string command modifiers that affect splitting a window.
+function M._check(mods, plugin_names)
local healthchecks = plugin_names == '' and get_healthcheck('*') or get_healthcheck(plugin_names)
local emptybuf = vim.fn.bufnr('$') == 1 and vim.fn.getline(1) == '' and 1 == vim.fn.line('$')
- local mod = function()
- if splitmod == 'vertical' then
- return 'vertical sbuffer'
- elseif splitmod == 'horizontal' then
- return 'horizontal sbuffer'
- elseif emptybuf then
- -- if this is the default buffer when Nvim starts, open healthcheck directly
- return 'buffer'
- else
- -- if not specified otherwise open healthcheck in a tab
- return 'tab sbuffer'
- end
- end
+
+ -- When no command modifiers are used:
+ -- - If the current buffer is empty, open healthcheck directly.
+ -- - If not specified otherwise open healthcheck in a tab.
+ local buf_cmd = #mods > 0 and (mods .. ' sbuffer') or emptybuf and 'buffer' or 'tab sbuffer'
local bufnr = vim.api.nvim_create_buf(true, true)
- vim.cmd(mod() .. ' ' .. bufnr)
+ vim.cmd(buf_cmd .. ' ' .. bufnr)
if vim.fn.bufexists('health://') == 1 then
vim.cmd.bwipe('health://')
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index a1ac1de1df..540c10e494 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8810,39 +8810,6 @@ void eval_fmt_source_name_line(char *buf, size_t bufsize)
}
}
-/// ":checkhealth [plugins]"
-void ex_checkhealth(exarg_T *eap)
-{
- Error err = ERROR_INIT;
- MAXSIZE_TEMP_ARRAY(args, 2);
- if (cmdmod.cmod_split & WSP_VERT) {
- ADD_C(args, CSTR_AS_OBJ("vertical"));
- } else if (cmdmod.cmod_split & WSP_HOR) {
- ADD_C(args, CSTR_AS_OBJ("horizontal"));
- } else {
- ADD_C(args, CSTR_AS_OBJ("tab"));
- }
- ADD_C(args, CSTR_AS_OBJ(eap->arg));
- NLUA_EXEC_STATIC("return vim.health._check(...)", args, &err);
- if (!ERROR_SET(&err)) {
- return;
- }
-
- const char *vimruntime_env = os_getenv("VIMRUNTIME");
- if (vimruntime_env == NULL) {
- emsg(_("E5009: $VIMRUNTIME is empty or unset"));
- } else {
- bool rtp_ok = NULL != strstr(p_rtp, vimruntime_env);
- if (rtp_ok) {
- semsg(_("E5009: Invalid $VIMRUNTIME: %s"), vimruntime_env);
- } else {
- emsg(_("E5009: Invalid 'runtimepath'"));
- }
- }
- semsg_multiline(err.msg);
- api_clear_error(&err);
-}
-
void invoke_prompt_callback(void)
{
typval_T rettv;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 70c8dc9019..964ddca887 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7386,6 +7386,44 @@ void set_pressedreturn(bool val)
ex_pressedreturn = val;
}
+/// ":checkhealth [plugins]"
+static void ex_checkhealth(exarg_T *eap)
+{
+ Error err = ERROR_INIT;
+ MAXSIZE_TEMP_ARRAY(args, 2);
+
+ char mods[1024];
+ size_t mods_len = 0;
+ mods[0] = NUL;
+
+ if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) {
+ bool multi_mods = false;
+ mods_len = add_win_cmd_modifiers(mods, &cmdmod, &multi_mods);
+ assert(mods_len < sizeof(mods));
+ }
+ ADD_C(args, STRING_OBJ(((String){ .data = mods, .size = mods_len })));
+ ADD_C(args, CSTR_AS_OBJ(eap->arg));
+
+ NLUA_EXEC_STATIC("return vim.health._check(...)", args, &err);
+ if (!ERROR_SET(&err)) {
+ return;
+ }
+
+ const char *vimruntime_env = os_getenv("VIMRUNTIME");
+ if (vimruntime_env == NULL) {
+ emsg(_("E5009: $VIMRUNTIME is empty or unset"));
+ } else {
+ bool rtp_ok = NULL != strstr(p_rtp, vimruntime_env);
+ if (rtp_ok) {
+ semsg(_("E5009: Invalid $VIMRUNTIME: %s"), vimruntime_env);
+ } else {
+ emsg(_("E5009: Invalid 'runtimepath'"));
+ }
+ }
+ semsg_multiline(err.msg);
+ api_clear_error(&err);
+}
+
static void ex_terminal(exarg_T *eap)
{
char ex_cmd[1024];
@@ -7393,10 +7431,8 @@ static void ex_terminal(exarg_T *eap)
if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) {
bool multi_mods = false;
-
- // ex_cmd must be a null terminated string before passing to add_win_cmd_modifiers
- ex_cmd[0] = '\0';
-
+ // ex_cmd must be a null-terminated string before passing to add_win_cmd_modifiers
+ ex_cmd[0] = NUL;
len = add_win_cmd_modifiers(ex_cmd, &cmdmod, &multi_mods);
assert(len < sizeof(ex_cmd));
int result = snprintf(ex_cmd + len, sizeof(ex_cmd) - len, " new");
diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua
index 7f23c3e7db..9120655724 100644
--- a/test/functional/plugin/health_spec.lua
+++ b/test/functional/plugin/health_spec.lua
@@ -6,7 +6,7 @@ local curbuf_contents = helpers.curbuf_contents
local command = helpers.command
local eq, neq, matches = helpers.eq, helpers.neq, helpers.matches
local getcompletion = helpers.funcs.getcompletion
-local feed = helpers.feed
+local insert = helpers.insert
local source = helpers.source
local exec_lua = helpers.exec_lua
@@ -237,16 +237,19 @@ describe(':checkhealth window', function()
]]}
end)
- it("opens in vsplit window when no buffer created", function()
+ local function test_health_vsplit(left, emptybuf, mods)
local screen = Screen.new(50, 20)
screen:attach({ext_multigrid=true})
- command("vertical checkhealth success1")
- screen:expect{grid=[[
+ if not emptybuf then
+ insert('hello')
+ end
+ command(mods .. ' checkhealth success1')
+ screen:expect(([[
## grid 1
- [4:-------------------------]│[2:------------------------]|*19
+ %s
[3:--------------------------------------------------]|
## grid 2
- |
+ %s |
~ |*18
## grid 3
|
@@ -265,21 +268,44 @@ describe(':checkhealth window', function()
- OK nothing to see here |
|
~ |*4
- ]]}
- end)
+ ]]):format(left
+ and '[4:-------------------------]│[2:------------------------]|*19'
+ or '[2:------------------------]│[4:-------------------------]|*19',
+ emptybuf and ' ' or 'hello')
+ )
+ end
+
+ for _, mods in ipairs({ 'vertical', 'leftabove vertical', 'topleft vertical' }) do
+ it(('opens in left vsplit window with :%s and no buffer created'):format(mods), function()
+ test_health_vsplit(true, true, mods)
+ end)
+ it(('opens in left vsplit window with :%s and non-empty buffer'):format(mods), function()
+ test_health_vsplit(true, false, mods)
+ end)
+ end
- it("opens in split window when no buffer created", function()
+ for _, mods in ipairs({ 'rightbelow vertical', 'botright vertical' }) do
+ it(('opens in right vsplit window with :%s and no buffer created'):format(mods), function()
+ test_health_vsplit(false, true, mods)
+ end)
+ it(('opens in right vsplit window with :%s and non-empty buffer'):format(mods), function()
+ test_health_vsplit(false, false, mods)
+ end)
+ end
+
+ local function test_health_split(top, emptybuf, mods)
local screen = Screen.new(50, 25)
screen:attach({ext_multigrid=true})
- command("horizontal checkhealth success1")
- screen:expect{grid=[[
+ if not emptybuf then
+ insert('hello')
+ end
+ command(mods .. ' checkhealth success1')
+ screen:expect(([[
## grid 1
- [4:--------------------------------------------------]|*12
- health:// |
- [2:--------------------------------------------------]|*11
+%s
[3:--------------------------------------------------]|
## grid 2
- |
+ %s |
~ |*10
## grid 3
|
@@ -296,74 +322,37 @@ describe(':checkhealth window', function()
report 2 |
- OK nothing to see here |
|
- ]]}
- end)
-
- it("opens in split window", function()
- local screen = Screen.new(50, 25)
- screen:attach({ext_multigrid=true})
- feed('ihello')
- feed('<esc>')
- command("horizontal checkhealth success1")
- screen:expect{grid=[[
- ## grid 1
+ ]]):format(top
+ and [[
[4:--------------------------------------------------]|*12
health:// |
+ [2:--------------------------------------------------]|*11]]
+ or ([[
[2:--------------------------------------------------]|*11
- [3:--------------------------------------------------]|
- ## grid 2
- hello |
- ~ |*10
- ## grid 3
- |
- ## grid 4
- ^ |
- ──────────────────────────────────────────────────|
- ──────────────────────────── |
- test_plug.success1: require("test_plug.success1. |
- health").check() |
- |
- report 1 |
- - OK everything is fine |
- |
- report 2 |
- - OK nothing to see here |
- |
- ]]}
- end)
+ [No Name] %s |
+ [4:--------------------------------------------------]|*12]]
+ ):format(emptybuf and ' ' or '[+]'),
+ emptybuf and ' ' or 'hello')
+ )
+ end
+
+ for _, mods in ipairs({ 'horizontal', 'leftabove', 'topleft' }) do
+ it(('opens in top split window with :%s and no buffer created'):format(mods), function()
+ test_health_split(true, true, mods)
+ end)
+ it(('opens in top split window with :%s and non-empty buffer'):format(mods), function()
+ test_health_split(true, false, mods)
+ end)
+ end
- it("opens in vsplit window", function()
- local screen = Screen.new(50, 25)
- screen:attach({ext_multigrid=true})
- feed('ihello')
- feed('<esc>')
- command("vertical checkhealth success1")
- screen:expect{grid=[[
- ## grid 1
- [4:-------------------------]│[2:------------------------]|*24
- [3:--------------------------------------------------]|
- ## grid 2
- hello |
- ~ |*23
- ## grid 3
- |
- ## grid 4
- ^ |
- ─────────────────────────|*3
- ─── |
- test_plug.success1: |
- require("test_plug. |
- success1.health").check()|
- |
- report 1 |
- - OK everything is fine |
- |
- report 2 |
- - OK nothing to see here |
- |
- ~ |*9
- ]]}
- end)
+ for _, mods in ipairs({ 'rightbelow', 'botright' }) do
+ it(('opens in bottom split window with :%s and no buffer created'):format(mods), function()
+ test_health_split(false, true, mods)
+ end)
+ it(('opens in bottom split window with :%s and non-empty buffer'):format(mods), function()
+ test_health_split(false, false, mods)
+ end)
+ end
it("opens in tab", function()
-- create an empty buffer called "my_buff"