Skip to content

Commit 21c3a80

Browse files
committed
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.
1 parent 92a3d20 commit 21c3a80

8 files changed

Lines changed: 99 additions & 33 deletions

File tree

runtime/doc/windows.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,16 @@ and 'winminwidth' are relevant.
256256
*:vert* *:vertical*
257257
:vert[ical] {cmd}
258258
Execute {cmd}. If it contains a command that splits a window,
259-
it will be split vertically.
259+
it will be split vertically. For `vertical wincmd =` windows
260+
will be equialized only vertically.
260261
Doesn't work for |:execute| and |:normal|.
261262

263+
*:hor* *:horizontal*
264+
:hor[izontal] {cmd}
265+
Execute {cmd}. Currently only makes a difference for
266+
`horizontal wincmd =`, which will equal windows only
267+
horizontally.
268+
262269
:lefta[bove] {cmd} *:lefta* *:leftabove*
263270
:abo[veleft] {cmd} *:abo* *:aboveleft*
264271
Execute {cmd}. If it contains a command that splits a window,
@@ -553,6 +560,10 @@ CTRL-W = Make all windows (almost) equally high and wide, but use
553560
'winheight' and 'winwidth' for the current window.
554561
Windows with 'winfixheight' set keep their height and windows
555562
with 'winfixwidth' set keep their width.
563+
To equalize only vertically (make window equally high) use
564+
`vertical wincmd =`
565+
To equalize only horizontally (make window equally wide) use
566+
`horizontal wincmd =`
556567

557568
:res[ize] -N *:res* *:resize* *CTRL-W_-*
558569
CTRL-W - Decrease current window height by N (default 1).

src/ex_cmdidxs.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@ static const unsigned short cmdidxs1[26] =
1313
/* f */ 166,
1414
/* g */ 183,
1515
/* h */ 189,
16-
/* i */ 198,
17-
/* j */ 218,
18-
/* k */ 220,
19-
/* l */ 225,
20-
/* m */ 288,
21-
/* n */ 306,
22-
/* o */ 326,
23-
/* p */ 338,
24-
/* q */ 377,
25-
/* r */ 380,
26-
/* s */ 400,
27-
/* t */ 470,
28-
/* u */ 516,
29-
/* v */ 527,
30-
/* w */ 548,
31-
/* x */ 562,
32-
/* y */ 572,
33-
/* z */ 573
16+
/* i */ 199,
17+
/* j */ 219,
18+
/* k */ 221,
19+
/* l */ 226,
20+
/* m */ 289,
21+
/* n */ 307,
22+
/* o */ 327,
23+
/* p */ 339,
24+
/* q */ 378,
25+
/* r */ 381,
26+
/* s */ 401,
27+
/* t */ 471,
28+
/* u */ 517,
29+
/* v */ 528,
30+
/* w */ 549,
31+
/* x */ 563,
32+
/* y */ 573,
33+
/* z */ 574
3434
};
3535

3636
/*
@@ -48,7 +48,7 @@ static const unsigned char cmdidxs2[26][26] =
4848
/* 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 },
4949
/* 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 },
5050
/* 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 },
51-
/* 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 },
51+
/* 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 },
5252
/* 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 },
5353
/* 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 },
5454
/* 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][26] =
6969
/* 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 }
7070
};
7171

72-
static const int command_count = 590;
72+
static const int command_count = 591;

src/ex_cmds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,9 @@ EXCMD(CMD_hide, "hide", ex_hide,
707707
EXCMD(CMD_history, "history", ex_history,
708708
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
709709
ADDR_NONE),
710+
EXCMD(CMD_horizontal, "horizontal", ex_wrongmodifier,
711+
EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM,
712+
ADDR_NONE),
710713
EXCMD(CMD_insert, "insert", ex_append,
711714
EX_BANG|EX_RANGE|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
712715
ADDR_LINES),

src/ex_docmd.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2987,8 +2987,13 @@ parse_command_modifiers(
29872987
continue;
29882988
}
29892989

2990+
case 'h': if (checkforcmd_noparen(&eap->cmd, "horizontal", 3))
2991+
{
2992+
cmod->cmod_split |= WSP_HOR;
2993+
continue;
2994+
}
29902995
// ":hide" and ":hide | cmd" are not modifiers
2991-
case 'h': if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3)
2996+
if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3)
29922997
|| *p == NUL || ends_excmd(*p))
29932998
break;
29942999
eap->cmd = p;

src/testdir/test_window_cmd.vim

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,46 @@ func Test_window_height()
367367
bw Xa Xb Xc
368368
endfunc
369369

370+
func Test_wincmd_equal()
371+
edit Xone
372+
below split Xtwo
373+
rightbelow vsplit Xthree
374+
call assert_equal('Xone', bufname(winbufnr(1)))
375+
call assert_equal('Xtwo', bufname(winbufnr(2)))
376+
call assert_equal('Xthree', bufname(winbufnr(3)))
377+
378+
" Xone and Xtwo should be about the same height
379+
let [wh1, wh2] = [winheight(1), winheight(2)]
380+
call assert_inrange(wh1 - 1, wh1 + 1, wh2)
381+
" Xtwo and Xthree should be about the same width
382+
let [ww2, ww3] = [winwidth(2), winwidth(3)]
383+
call assert_inrange(ww2 - 1, ww2 + 1, ww3)
384+
385+
1wincmd w
386+
10wincmd _
387+
2wincmd w
388+
20wincmd |
389+
call assert_equal(10, winheight(1))
390+
call assert_equal(20, winwidth(2))
391+
392+
" equalizing horizontally doesn't change the heights
393+
hor wincmd =
394+
call assert_equal(10, winheight(1))
395+
let [ww2, ww3] = [winwidth(2), winwidth(3)]
396+
call assert_inrange(ww2 - 1, ww2 + 1, ww3)
397+
398+
2wincmd w
399+
20wincmd |
400+
call assert_equal(20, winwidth(2))
401+
" equalizing vertically doesn't change the widths
402+
vert wincmd =
403+
call assert_equal(20, winwidth(2))
404+
let [wh1, wh2] = [winheight(1), winheight(2)]
405+
call assert_inrange(wh1 - 1, wh1 + 1, wh2)
406+
407+
bwipe Xone Xtwo Xthree
408+
endfunc
409+
370410
func Test_window_width()
371411
e Xa
372412
vsplit Xb

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,8 @@ static char *(features[]) =
707707

708708
static int included_patches[] =
709709
{ /* Add new patch number below this line */
710+
/**/
711+
342,
710712
/**/
711713
341,
712714
/**/

src/vim.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,14 +1209,15 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
12091209
/*
12101210
* arguments for win_split()
12111211
*/
1212-
#define WSP_ROOM 1 // require enough room
1213-
#define WSP_VERT 2 // split vertically
1214-
#define WSP_TOP 4 // window at top-left of shell
1215-
#define WSP_BOT 8 // window at bottom-right of shell
1216-
#define WSP_HELP 16 // creating the help window
1217-
#define WSP_BELOW 32 // put new window below/right
1218-
#define WSP_ABOVE 64 // put new window above/left
1219-
#define WSP_NEWLOC 128 // don't copy location list
1212+
#define WSP_ROOM 0x01 // require enough room
1213+
#define WSP_VERT 0x02 // split/equalize vertically
1214+
#define WSP_HOR 0x04 // equalize horizontally
1215+
#define WSP_TOP 0x08 // window at top-left of shell
1216+
#define WSP_BOT 0x10 // window at bottom-right of shell
1217+
#define WSP_HELP 0x20 // creating the help window
1218+
#define WSP_BELOW 0x40 // put new window below/right
1219+
#define WSP_ABOVE 0x80 // put new window above/left
1220+
#define WSP_NEWLOC 0x100 // don't copy location list
12201221

12211222
/*
12221223
* arguments for gui_set_shellsize()

src/window.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,12 +434,16 @@ do_window(
434434
| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
435435
break;
436436

437-
// make all windows the same height
437+
// make all windows the same width and/or height
438438
case '=':
439+
{
440+
int mod = cmdmod.cmod_split & (WSP_VERT | WSP_HOR);
439441
#ifdef FEAT_GUI
440-
need_mouse_correct = TRUE;
442+
need_mouse_correct = TRUE;
441443
#endif
442-
win_equal(NULL, FALSE, 'b');
444+
win_equal(NULL, FALSE,
445+
mod == WSP_VERT ? 'v' : mod == WSP_HOR ? 'h' : 'b');
446+
}
443447
break;
444448

445449
// increase current window height

0 commit comments

Comments
 (0)