aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
12 files changed, 89 insertions, 12 deletions
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