aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt1
-rw-r--r--runtime/doc/map.txt10
-rw-r--r--runtime/doc/windows.txt13
-rw-r--r--src/nvim/api/command.c7
-rw-r--r--src/nvim/api/keysets.lua1
-rw-r--r--src/nvim/cmdexpand.c1
-rw-r--r--src/nvim/ex_cmds.lua6
-rw-r--r--src/nvim/ex_docmd.c7
-rw-r--r--src/nvim/lua/executor.c2
-rw-r--r--src/nvim/testdir/test_cmdline.vim4
-rw-r--r--src/nvim/testdir/test_usercommands.vim4
-rw-r--r--src/nvim/testdir/test_window_cmd.vim40
-rw-r--r--src/nvim/usercmd.c4
-rw-r--r--src/nvim/window.c8
-rw-r--r--src/nvim/window.h17
-rw-r--r--test/functional/api/command_spec.lua13
-rw-r--r--test/functional/api/vim_spec.lua26
17 files changed, 142 insertions, 22 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 89baf84c86..82978d0b3c 100644
--- 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
index ca1ddaabd4..da6a305e89 100644
--- 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
index 2627068a14..ddf4d09e92 100644
--- 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
index 1323fc347b..b821e07d60 100644
--- 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
index 6fad52ba75..af3dc24f51 100644
--- 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
index 6fc63f72a1..9d8dd197bd 100644
--- 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
index 4bed1e94b9..04b8832428 100644
--- 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
index 0af737ff50..ea21dc8ae7 100644
--- 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
index f144e47c3a..2315ecd874 100644
--- 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
index 4bfd22cb6c..bc06e70ff4 100644
--- 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
index e37fe43b22..1065dd16e2 100644
--- 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
index 83a3216534..1f4b9b77c6 100644
--- 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
index 9cc9fb5588..3726273d28 100644
--- 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
index c11484d1b8..c0b73ff837 100644
--- 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
index b75b8abd9b..3137035b25 100644
--- 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
index 440e93da0e..2d8bf23f5b 100644
--- 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
index 24d0b6da45..2e37c4787d 100644
--- 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',