changeset 30009:b97a870a7c63 v9.0.0342

patch 9.0.0342: ":wincmd =" equalizes in two directions Commit: https://github.com/vim/vim/commit/21c3a80a7fd6b7fc250ce5dc287963511f54b86f Author: Bram Moolenaar <Bram@vim.org> 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.
author Bram Moolenaar <Bram@vim.org>
date Wed, 31 Aug 2022 19:00:04 +0200
parents 7a1cc16aed5b
children 0379de231ecd
files runtime/doc/windows.txt src/ex_cmdidxs.h src/ex_cmds.h src/ex_docmd.c src/testdir/test_window_cmd.vim src/version.c src/vim.h src/window.c
diffstat 8 files changed, 99 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- 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).
--- 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;
--- 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),
--- 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;
--- 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
--- 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,
--- 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()
--- 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