# HG changeset patch # User Bram Moolenaar # Date 1661965204 -7200 # Node ID b97a870a7c6392fe986ffe18e74d33800283cb63 # Parent 7a1cc16aed5bbc85a133b59675d758a78a3498de patch 9.0.0342: ":wincmd =" equalizes in two directions Commit: https://github.com/vim/vim/commit/21c3a80a7fd6b7fc250ce5dc287963511f54b86f Author: Bram Moolenaar Date: Wed Aug 31 17:49:14 2022 +0100 patch 9.0.0342: ":wincmd =" equalizes in two directions Problem: ":wincmd =" equalizes in two directions. Solution: Make ":vertical wincmd =" equalize vertically only and ":horizontal wincmd =" equalize horizontally only. diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -256,9 +256,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, @@ -553,6 +560,10 @@ CTRL-W = Make all windows (almost) equal '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/ex_cmdidxs.h b/src/ex_cmdidxs.h --- a/src/ex_cmdidxs.h +++ b/src/ex_cmdidxs.h @@ -13,24 +13,24 @@ static const unsigned short cmdidxs1[26] /* f */ 166, /* g */ 183, /* h */ 189, - /* i */ 198, - /* j */ 218, - /* k */ 220, - /* l */ 225, - /* m */ 288, - /* n */ 306, - /* o */ 326, - /* p */ 338, - /* q */ 377, - /* r */ 380, - /* s */ 400, - /* t */ 470, - /* u */ 516, - /* v */ 527, - /* w */ 548, - /* x */ 562, - /* y */ 572, - /* z */ 573 + /* i */ 199, + /* j */ 219, + /* k */ 221, + /* l */ 226, + /* m */ 289, + /* n */ 307, + /* o */ 327, + /* p */ 339, + /* q */ 378, + /* r */ 381, + /* s */ 401, + /* t */ 471, + /* u */ 517, + /* v */ 528, + /* w */ 549, + /* x */ 563, + /* y */ 573, + /* z */ 574 }; /* @@ -48,7 +48,7 @@ static const unsigned char cmdidxs2[26][ /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 9, 11, 12, 0, 0, 0, 0, 0, 0, 0, 23, 0, 24, 0, 0 }, /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 }, /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, - /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0 }, /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][ /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -static const int command_count = 590; +static const int command_count = 591; diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -707,6 +707,9 @@ EXCMD(CMD_hide, "hide", ex_hide, EXCMD(CMD_history, "history", ex_history, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), +EXCMD(CMD_horizontal, "horizontal", ex_wrongmodifier, + EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM, + ADDR_NONE), EXCMD(CMD_insert, "insert", ex_append, EX_BANG|EX_RANGE|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY, ADDR_LINES), diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2987,8 +2987,13 @@ parse_command_modifiers( continue; } + case 'h': if (checkforcmd_noparen(&eap->cmd, "horizontal", 3)) + { + cmod->cmod_split |= WSP_HOR; + continue; + } // ":hide" and ":hide | cmd" are not modifiers - case 'h': if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3) + if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3) || *p == NUL || ends_excmd(*p)) break; eap->cmd = p; diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -367,6 +367,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/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -708,6 +708,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 342, +/**/ 341, /**/ 340, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -1209,14 +1209,15 @@ extern int (*dyn_libintl_wputenv)(const /* * 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 /* * arguments for gui_set_shellsize() diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -434,12 +434,16 @@ newwindow: | ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT)); break; -// make all windows the same height +// make all windows the same width and/or height case '=': + { + int mod = cmdmod.cmod_split & (WSP_VERT | WSP_HOR); #ifdef FEAT_GUI - need_mouse_correct = TRUE; + need_mouse_correct = TRUE; #endif - win_equal(NULL, FALSE, 'b'); + win_equal(NULL, FALSE, + mod == WSP_VERT ? 'v' : mod == WSP_HOR ? 'h' : 'b'); + } break; // increase current window height