Skip to content

Commit 620c655

Browse files
seandewarchrisbra
authored andcommitted
patch 9.1.1831: stray vseps in right-most 'winfixwidth' window
Problem: vertical separator of 'winfixwidth' windows may remain if they become right-most windows from closing windows to the right. Solution: Don't implicitly rely on frame_new_width to fix vseps, as the call may be skipped for 'winfixwidth' windows to preserve their width; do it explicitly in winframe_remove (Sean Dewar). Note that I prefer win_new_width here over setting w_width directly, which would've previously been done by win_split_ins after frame_add_vsep, as this wasn't true for winframe_remove. Though the equivalent issue of bottom 'winfixheight' windows leaving stray statuslines with &ls=0 doesn't seem to exist, test it anyway. closes: #18481 Signed-off-by: Sean Dewar <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent 3b3cb04 commit 620c655

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
> +0&#ffffff0@35||+1&&| +0&&@37
2+
|~+0#4040ff13&| @34||+1#0000000&|~+0#4040ff13&| @36
3+
|~| @34||+1#0000000&|~+0#4040ff13&| @36
4+
|~| @34||+1#0000000&|~+0#4040ff13&| @36
5+
|~| @34||+1#0000000&|~+0#4040ff13&| @36
6+
|~| @34||+1#0000000&|~+0#4040ff13&| @36
7+
|[+3#0000000&|N|o| |N|a|m|e|]| @8|0|,|0|-|1| @9|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @10|0|,|0|-|1| @9|A|l@1
8+
|:+0&&|q|u|i|t| @69
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
> +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|[+3#0000000&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1
4+
| +0&&@74
5+
|~+0#4040ff13&| @73
6+
|~| @73
7+
|~| @73
8+
|:+0#0000000&|q|u|i|t| @51|0|,|0|-|1| @8|A|l@1|

src/testdir/test_window_cmd.vim

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,4 +2305,50 @@ func Test_winfixsize_positions()
23052305
%bwipe
23062306
endfunc
23072307

2308+
func Test_winfixsize_vsep_statusline()
2309+
CheckScreendump
2310+
let lines =<< trim END
2311+
set noequalalways splitbelow splitright
2312+
vsplit
2313+
setlocal winfixwidth
2314+
vsplit
2315+
func SetupWfh()
2316+
set laststatus=0
2317+
only
2318+
split
2319+
set winfixheight
2320+
split
2321+
endfunc
2322+
END
2323+
call writefile(lines, 'XTestWinfixsizeVsepStatusline', 'D')
2324+
let buf = RunVimInTerminal('-S XTestWinfixsizeVsepStatusline', #{rows: 8})
2325+
2326+
call term_sendkeys(buf, ":echo winwidth(1) winwidth(2) winwidth(3)\n")
2327+
call WaitForAssert({-> assert_match('^16 37 20\>', term_getline(buf, 8))})
2328+
2329+
call term_sendkeys(buf, ":quit\n")
2330+
call VerifyScreenDump(buf, 'Test_winfixsize_vsep_statusline_1', {})
2331+
2332+
" Reported widths should be consistent with the screen dump.
2333+
call term_sendkeys(buf, ":echo winwidth(1) winwidth(2)\n")
2334+
" (May be better if 'wfw' window remains at 37 columns, but the resize is
2335+
" consistent with how things currently work for 'winfix*' windows)
2336+
call WaitForAssert({-> assert_match('^36 38\>', term_getline(buf, 8))})
2337+
2338+
" For good measure, also check bottom-most 'winfixheight' windows don't leave
2339+
" stray statuslines with &laststatus=0.
2340+
call term_sendkeys(buf,
2341+
\ ":call SetupWfh() | echo winheight(1) winheight(2) winheight(3)\n")
2342+
call WaitForAssert({-> assert_match('^1 3 1\>', term_getline(buf, 8))})
2343+
2344+
call term_sendkeys(buf, ":quit\n")
2345+
call VerifyScreenDump(buf, 'Test_winfixsize_vsep_statusline_2', {})
2346+
2347+
call term_sendkeys(buf, ":echo winheight(1) winheight(2)\n")
2348+
" (Likewise, may be better if 'wfh' window remains at 3 rows)
2349+
call WaitForAssert({-> assert_match('^2 4\>', term_getline(buf, 8))})
2350+
2351+
call StopVimInTerminal(buf)
2352+
endfunc
2353+
23082354
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

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

730730
static int included_patches[] =
731731
{ /* Add new patch number below this line */
732+
/**/
733+
1831,
732734
/**/
733735
1830,
734736
/**/

src/window.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static int frame_fixed_height(frame_T *frp);
3232
static int frame_fixed_width(frame_T *frp);
3333
static void frame_add_statusline(frame_T *frp);
3434
static void frame_new_width(frame_T *topfrp, int width, int leftfirst, int wfw);
35-
static void frame_add_vsep(frame_T *frp);
35+
static void frame_set_vsep(frame_T *frp, int add);
3636
static int frame_minwidth(frame_T *topfrp, win_T *next_curwin);
3737
static void frame_fix_width(win_T *wp);
3838
static int win_alloc_firstwin(win_T *oldwin);
@@ -1363,7 +1363,7 @@ win_split_ins(
13631363
if (flags & (WSP_TOP | WSP_BOT))
13641364
{
13651365
if (flags & WSP_BOT)
1366-
frame_add_vsep(curfrp);
1366+
frame_set_vsep(curfrp, TRUE);
13671367
// Set width of neighbor frame
13681368
frame_new_width(curfrp, curfrp->fr_width
13691369
- (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP,
@@ -3577,6 +3577,11 @@ winframe_remove(
35773577
frp2 = win_altframe(win, tp);
35783578
wp = frame2win(frp2);
35793579

3580+
// If this is a rightmost window, remove vertical separators to the left.
3581+
if (win->w_vsep_width == 0 && frp_close->fr_parent->fr_layout == FR_ROW &&
3582+
frp_close->fr_prev != NULL)
3583+
frame_set_vsep(frp_close->fr_prev, FALSE);
3584+
35803585
// Remove this frame from the list of frames.
35813586
frame_remove(frp_close);
35823587

@@ -3742,7 +3747,7 @@ winframe_restore(win_T *wp, int dir, frame_T *unflat_altfr)
37423747
// Vertical separators to the left may have been lost. Restore them.
37433748
if (wp->w_vsep_width == 0
37443749
&& frp->fr_parent->fr_layout == FR_ROW && frp->fr_prev != NULL)
3745-
frame_add_vsep(frp->fr_prev);
3750+
frame_set_vsep(frp->fr_prev, TRUE);
37463751

37473752
// Statuslines above may have been lost. Restore them.
37483753
if (wp->w_status_height == 0
@@ -4223,37 +4228,42 @@ frame_new_width(
42234228
}
42244229

42254230
/*
4226-
* Add the vertical separator to windows at the right side of "frp".
4231+
* Add or remove the vertical separator of windows to the right side of "frp".
42274232
* Note: Does not check if there is room!
42284233
*/
42294234
static void
4230-
frame_add_vsep(frame_T *frp)
4235+
frame_set_vsep(frame_T *frp, int add)
42314236
{
42324237
win_T *wp;
42334238

42344239
if (frp->fr_layout == FR_LEAF)
42354240
{
42364241
wp = frp->fr_win;
4237-
if (wp->w_vsep_width == 0)
4242+
if (add && wp->w_vsep_width == 0)
42384243
{
42394244
if (wp->w_width > 0) // don't make it negative
4240-
--wp->w_width;
4245+
win_new_width(wp, wp->w_width - 1);
42414246
wp->w_vsep_width = 1;
42424247
}
4248+
else if (!add && wp->w_vsep_width == 1)
4249+
{
4250+
win_new_width(wp, wp->w_width + 1);
4251+
wp->w_vsep_width = 0;
4252+
}
42434253
}
42444254
else if (frp->fr_layout == FR_COL)
42454255
{
42464256
// Handle all the frames in the column.
42474257
FOR_ALL_FRAMES(frp, frp->fr_child)
4248-
frame_add_vsep(frp);
4258+
frame_set_vsep(frp, add);
42494259
}
42504260
else // frp->fr_layout == FR_ROW
42514261
{
42524262
// Only need to handle the last frame in the row.
42534263
frp = frp->fr_child;
42544264
while (frp->fr_next != NULL)
42554265
frp = frp->fr_next;
4256-
frame_add_vsep(frp);
4266+
frame_set_vsep(frp, add);
42574267
}
42584268
}
42594269

0 commit comments

Comments
 (0)