commit 12fe197cffc687cedc65259d9fd8351a25aa7792
parent db2e5f46f5aa5a6300395eaa9c4923835683c770
Author: zeertzjq <zeertzjq@outlook.com>
Date: Thu, 1 Sep 2022 21:31:38 +0800
Merge pull request #20040 from zeertzjq/vim-9.0.0342
vim-patch:9.0.{0342,0346}: :horizontal modifier
Diffstat:
17 files changed, 142 insertions(+), 22 deletions(-)
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
@@ -1839,6 +1839,7 @@ nvim_parse_cmd({str}, {opts}) *nvim_parse_cmd()*
• browse: (boolean) |:browse|.
• confirm: (boolean) |:confirm|.
• hide: (boolean) |:hide|.
+ • horizontal: (boolean) |:horizontal|.
• keepalt: (boolean) |:keepalt|.
• keepjumps: (boolean) |:keepjumps|.
• keepmarks: (boolean) |:keepmarks|.
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
@@ -1623,11 +1623,11 @@ The valid escape sequences are
*<mods>* *<q-mods>* *:command-modifiers*
<mods> The command modifiers, if specified. Otherwise, expands to
nothing. Supported modifiers are |:aboveleft|, |:belowright|,
- |:botright|, |:browse|, |:confirm|, |:hide|, |:keepalt|,
- |:keepjumps|, |:keepmarks|, |:keeppatterns|, |:leftabove|,
- |:lockmarks|, |:noautocmd|, |:noswapfile| |:rightbelow|,
- |:sandbox|, |:silent|, |:tab|, |:topleft|, |:unsilent|,
- |:verbose|, and |:vertical|.
+ |:botright|, |:browse|, |:confirm|, |:hide|, |:horizontal|,
+ |:keepalt|, |:keepjumps|, |:keepmarks|, |:keeppatterns|,
+ |:leftabove|, |:lockmarks|, |:noautocmd|, |:noswapfile|
+ |:rightbelow|, |:sandbox|, |:silent|, |:tab|, |:topleft|,
+ |:unsilent|, |:verbose|, and |:vertical|.
Note that |:filter| is not supported.
Examples: >
command! -nargs=+ -complete=file MyEdit
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
@@ -235,9 +235,16 @@ and 'winminwidth' are relevant.
*:vert* *:vertical*
:vert[ical] {cmd}
Execute {cmd}. If it contains a command that splits a window,
- it will be split vertically.
+ it will be split vertically. For `vertical wincmd =` windows
+ will be equialized only vertically.
Doesn't work for |:execute| and |:normal|.
+ *:hor* *:horizontal*
+:hor[izontal] {cmd}
+ Execute {cmd}. Currently only makes a difference for
+ `horizontal wincmd =`, which will equal windows only
+ horizontally.
+
:lefta[bove] {cmd} *:lefta* *:leftabove*
:abo[veleft] {cmd} *:abo* *:aboveleft*
Execute {cmd}. If it contains a command that splits a window,
@@ -530,6 +537,10 @@ CTRL-W = Make all windows (almost) equally high and wide, but use
'winheight' and 'winwidth' for the current window.
Windows with 'winfixheight' set keep their height and windows
with 'winfixwidth' set keep their width.
+ To equalize only vertically (make window equally high) use
+ `vertical wincmd =`
+ To equalize only horizontally (make window equally wide) use
+ `horizontal wincmd =`
:res[ize] -N *:res* *:resize* *CTRL-W_-*
CTRL-W - Decrease current window height by N (default 1).
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
@@ -62,6 +62,7 @@
/// - browse: (boolean) |:browse|.
/// - confirm: (boolean) |:confirm|.
/// - hide: (boolean) |:hide|.
+/// - horizontal: (boolean) |:horizontal|.
/// - keepalt: (boolean) |:keepalt|.
/// - keepjumps: (boolean) |:keepjumps|.
/// - keepmarks: (boolean) |:keepmarks|.
@@ -250,6 +251,7 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err)
PUT(mods, "lockmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_LOCKMARKS));
PUT(mods, "noswapfile", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOSWAPFILE));
PUT(mods, "vertical", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_VERT));
+ PUT(mods, "horizontal", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_HOR));
const char *split;
if (cmdinfo.cmdmod.cmod_split & WSP_BOT) {
@@ -576,6 +578,10 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
OBJ_TO_BOOL(vertical, mods.vertical, false, "'mods.vertical'");
cmdinfo.cmdmod.cmod_split |= (vertical ? WSP_VERT : 0);
+ bool horizontal;
+ OBJ_TO_BOOL(horizontal, mods.horizontal, false, "'mods.horizontal'");
+ cmdinfo.cmdmod.cmod_split |= (horizontal ? WSP_HOR : 0);
+
if (HAS_KEY(mods.split)) {
if (mods.split.type != kObjectTypeString) {
VALIDATION_ERROR("'mods.split' must be a String");
@@ -753,6 +759,7 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
} while (0)
CMDLINE_APPEND_IF(cmdinfo->cmdmod.cmod_split & WSP_VERT, "vertical ");
+ CMDLINE_APPEND_IF(cmdinfo->cmdmod.cmod_split & WSP_HOR, "horizontal ");
CMDLINE_APPEND_IF(cmdinfo->cmdmod.cmod_flags & CMOD_SANDBOX, "sandbox ");
CMDLINE_APPEND_IF(cmdinfo->cmdmod.cmod_flags & CMOD_NOAUTOCMD, "noautocmd ");
CMDLINE_APPEND_IF(cmdinfo->cmdmod.cmod_flags & CMOD_BROWSE, "browse ");
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
@@ -188,6 +188,7 @@ return {
"browse";
"confirm";
"hide";
+ "horizontal";
"keepalt";
"keepjumps";
"keepmarks";
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
@@ -1203,6 +1203,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, cons
case CMD_folddoclosed:
case CMD_folddoopen:
case CMD_hide:
+ case CMD_horizontal:
case CMD_keepalt:
case CMD_keepjumps:
case CMD_keepmarks:
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
@@ -1141,6 +1141,12 @@ module.cmds = {
func='ex_history',
},
{
+ command='horizontal',
+ flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),
+ addr_type='ADDR_NONE',
+ func='ex_wrongmodifier',
+ },
+ {
command='insert',
flags=bit.bor(BANG, RANGE, TRLBAR, CMDWIN, LOCK_OK, MODIFY),
addr_type='ADDR_LINES',
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
@@ -1757,6 +1757,7 @@ static bool skip_cmd(const exarg_T *eap)
case CMD_filter:
case CMD_help:
case CMD_hide:
+ case CMD_horizontal:
case CMD_ijump:
case CMD_ilist:
case CMD_isearch:
@@ -2438,8 +2439,12 @@ int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod, bool
continue;
}
- // ":hide" and ":hide | cmd" are not modifiers
case 'h':
+ if (checkforcmd(&eap->cmd, "horizontal", 3)) {
+ cmod->cmod_split |= WSP_HOR;
+ continue;
+ }
+ // ":hide" and ":hide | cmd" are not modifiers
if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p)) {
break;
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
@@ -2103,6 +2103,8 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview)
lua_pushboolean(lstate, cmdmod.cmod_split & WSP_VERT);
lua_setfield(lstate, -2, "vertical");
+ lua_pushboolean(lstate, cmdmod.cmod_split & WSP_HOR);
+ lua_setfield(lstate, -2, "horizontal");
lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_SILENT);
lua_setfield(lstate, -2, "silent");
lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_ERRSILENT);
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
@@ -926,6 +926,10 @@ func Test_cmdline_complete_various()
call feedkeys(":all abc\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"all abc\<C-A>", @:)
+ " completion for :wincmd with :horizontal modifier
+ call feedkeys(":horizontal wincm\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal("\"horizontal wincmd", @:)
+
" completion for a command with a command modifier
call feedkeys(":topleft new\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"topleft new", @:)
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
@@ -101,6 +101,10 @@ function Test_cmdmods()
call assert_equal('vertical', g:mods)
vert MyCmd
call assert_equal('vertical', g:mods)
+ horizontal MyCmd
+ call assert_equal('horizontal', g:mods)
+ hor MyCmd
+ call assert_equal('horizontal', g:mods)
aboveleft belowright botright browse confirm hide keepalt keepjumps
\ keepmarks keeppatterns lockmarks noautocmd noswapfile silent
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
@@ -343,6 +343,46 @@ func Test_window_height()
bw Xa Xb Xc
endfunc
+func Test_wincmd_equal()
+ edit Xone
+ below split Xtwo
+ rightbelow vsplit Xthree
+ call assert_equal('Xone', bufname(winbufnr(1)))
+ call assert_equal('Xtwo', bufname(winbufnr(2)))
+ call assert_equal('Xthree', bufname(winbufnr(3)))
+
+ " Xone and Xtwo should be about the same height
+ let [wh1, wh2] = [winheight(1), winheight(2)]
+ call assert_inrange(wh1 - 1, wh1 + 1, wh2)
+ " Xtwo and Xthree should be about the same width
+ let [ww2, ww3] = [winwidth(2), winwidth(3)]
+ call assert_inrange(ww2 - 1, ww2 + 1, ww3)
+
+ 1wincmd w
+ 10wincmd _
+ 2wincmd w
+ 20wincmd |
+ call assert_equal(10, winheight(1))
+ call assert_equal(20, winwidth(2))
+
+ " equalizing horizontally doesn't change the heights
+ hor wincmd =
+ call assert_equal(10, winheight(1))
+ let [ww2, ww3] = [winwidth(2), winwidth(3)]
+ call assert_inrange(ww2 - 1, ww2 + 1, ww3)
+
+ 2wincmd w
+ 20wincmd |
+ call assert_equal(20, winwidth(2))
+ " equalizing vertically doesn't change the widths
+ vert wincmd =
+ call assert_equal(20, winwidth(2))
+ let [wh1, wh2] = [winheight(1), winheight(2)]
+ call assert_inrange(wh1 - 1, wh1 + 1, wh2)
+
+ bwipe Xone Xtwo Xthree
+endfunc
+
func Test_window_width()
e Xa
vsplit Xb
diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c
@@ -1247,6 +1247,10 @@ size_t add_win_cmd_modifers(char *buf, const cmdmod_T *cmod, bool *multi_mods)
if (cmod->cmod_split & WSP_VERT) {
result += add_cmd_modifier(buf, "vertical", multi_mods);
}
+ // :horizontal
+ if (cmod->cmod_split & WSP_HOR) {
+ result += add_cmd_modifier(buf, "horizontal", multi_mods);
+ }
return result;
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
@@ -417,10 +417,12 @@ newwindow:
| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
break;
- // make all windows the same height
- case '=':
- win_equal(NULL, false, 'b');
+ // make all windows the same width and/or height
+ case '=': {
+ int mod = cmdmod.cmod_split & (WSP_VERT | WSP_HOR);
+ win_equal(NULL, false, mod == WSP_VERT ? 'v' : mod == WSP_HOR ? 'h' : 'b');
break;
+ }
// increase current window height
case '+':
diff --git a/src/nvim/window.h b/src/nvim/window.h
@@ -17,14 +17,15 @@
#define FNAME_UNESC 32 // remove backslashes used for escaping
// arguments for win_split()
-#define WSP_ROOM 1 // require enough room
-#define WSP_VERT 2 // split vertically
-#define WSP_TOP 4 // window at top-left of shell
-#define WSP_BOT 8 // window at bottom-right of shell
-#define WSP_HELP 16 // creating the help window
-#define WSP_BELOW 32 // put new window below/right
-#define WSP_ABOVE 64 // put new window above/left
-#define WSP_NEWLOC 128 // don't copy location list
+#define WSP_ROOM 0x01 // require enough room
+#define WSP_VERT 0x02 // split/equalize vertically
+#define WSP_HOR 0x04 // equalize horizontally
+#define WSP_TOP 0x08 // window at top-left of shell
+#define WSP_BOT 0x10 // window at bottom-right of shell
+#define WSP_HELP 0x20 // creating the help window
+#define WSP_BELOW 0x40 // put new window below/right
+#define WSP_ABOVE 0x80 // put new window above/left
+#define WSP_NEWLOC 0x100 // don't copy location list
// Minimum screen size
#define MIN_COLUMNS 12 // minimal columns for screen
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
@@ -125,6 +125,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -160,6 +161,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -195,6 +197,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -224,12 +227,13 @@ describe('nvim_create_user_command', function()
bang = true,
line1 = 10,
line2 = 10,
- mods = "confirm unsilent botright",
+ mods = "confirm unsilent botright horizontal",
smods = {
browse = false,
confirm = true,
emsg_silent = false,
hide = false,
+ horizontal = true,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -249,7 +253,7 @@ describe('nvim_create_user_command', function()
count = 10,
reg = "",
}, exec_lua [=[
- vim.api.nvim_command('unsilent botright confirm 10CommandWithLuaCallback! h\tey ')
+ vim.api.nvim_command('unsilent horizontal botright confirm 10CommandWithLuaCallback! h\tey ')
return result
]=])
@@ -265,6 +269,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -300,6 +305,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -347,6 +353,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -383,6 +390,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -429,6 +437,7 @@ describe('nvim_create_user_command', function()
confirm = false,
emsg_silent = false,
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
@@ -3195,6 +3195,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3236,6 +3237,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3277,6 +3279,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3318,6 +3321,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3359,6 +3363,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3400,6 +3405,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3441,6 +3447,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = true,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3456,7 +3463,7 @@ describe('API', function()
verbose = 15,
vertical = false,
},
- }, meths.parse_cmd('15verbose silent! aboveleft topleft tab filter /foo/ split foo.txt', {}))
+ }, meths.parse_cmd('15verbose silent! horizontal topleft tab filter /foo/ split foo.txt', {}))
eq({
cmd = 'split',
args = { 'foo.txt' },
@@ -3480,6 +3487,7 @@ describe('API', function()
force = true
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3522,6 +3530,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3563,6 +3572,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3605,6 +3615,7 @@ describe('API', function()
force = false
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3697,6 +3708,7 @@ describe('API', function()
force = false,
},
hide = false,
+ horizontal = false,
keepalt = false,
keepjumps = false,
keepmarks = false,
@@ -3798,10 +3810,20 @@ describe('API', function()
eq('1',
meths.cmd({ cmd = 'echomsg', args = { '1' }, mods = { silent = true } },
{ output = true }))
- -- with :silent message isn't added to message history
+ -- but message isn't added to message history
eq('', meths.cmd({ cmd = 'messages' }, { output = true }))
meths.create_user_command("Foo", 'set verbose', {})
eq(" verbose=1", meths.cmd({ cmd = "Foo", mods = { verbose = 1 } }, { output = true }))
+ meths.create_user_command("Mods", "echo '<mods>'", {})
+ eq('keepmarks keeppatterns silent 3verbose aboveleft horizontal',
+ meths.cmd({ cmd = "Mods", mods = {
+ horizontal = true,
+ keepmarks = true,
+ keeppatterns = true,
+ silent = true,
+ split = 'aboveleft',
+ verbose = 3,
+ } }, { output = true }))
eq(0, meths.get_option_value("verbose", {}))
command('edit foo.txt | edit bar.txt')
eq(' 1 #h "foo.txt" line 1',