patch 9.2.0386: No scroll/scrollbar support in the tabpanel
Commit:
https://github.com/vim/vim/commit/2ea4a7c3b73468683249fe194707c8d7e67ecdb3
Author: Yasuhiro Matsumoto <[email protected]>
Date: Tue Apr 21 20:20:30 2026 +0000
patch 9.2.0386: No scroll/scrollbar support in the tabpanel
Problem: No scroll/scrollbar support in the tabpanel
Solution: Add support for it (Yasuhiro Matsumoto)
closes: #19979
Signed-off-by: Yasuhiro Matsumoto <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index c02d40eaa..d2611db09 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.2. Last change: 2026 Apr 20
+*options.txt* For Vim version 9.2. Last change: 2026 Apr 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -9065,6 +9065,23 @@ A jump table for the options with a short description
can be found at |Q_op|.
tab panel will not be displayed.
(default 20)
+ scroll Enable mouse wheel scrolling over the tabpanel
+ area when the tab list exceeds the visible
+ screen height. The scroll step is controlled
+ by 'mousescroll'. When disabled (the default),
+ the tabpanel shows the page containing the
+ current tab, with no way to view tabs outside
+ that page.
+
+ scrollbar Reserve a one-column scrollbar in the tabpanel
+ showing the current scroll position. The
+ scrollbar uses the |hl-PmenuSbar| and
+ |hl-PmenuThumb| highlight groups for the track
+ and thumb respectively. Clicking on the
+ scrollbar column jumps the thumb to that
+ position; the thumb can also be dragged.
+ Implies "scroll".
+
vert Use a vertical separator for tabpanel.
The vertical separator character is taken from
"tpl_vert" in 'fillchars'.
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index 3e307b648..3130c185f 100644
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -1,4 +1,4 @@
-*tabpage.txt* For Vim version 9.2. Last change: 2026 Feb 14
+*tabpage.txt* For Vim version 9.2. Last change: 2026 Apr 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -482,6 +482,37 @@ The vertical separator character is taken from "tpl_vert"
in 'fillchars'.
You can customize the appearance of the tab page labels using the highlight
groups: |hl-TabPanel| |hl-TabPanelSel| |hl-TabPanelFill|
+SCROLLING IN THE TABPANEL: *tabpanel-scroll*
+
+When the total height of the tab list exceeds the visible screen height, the
+tabpanel by default displays the "page" that contains the current tab and
+offers no way to view tabs outside that page.
+
+To make the tabpanel scrollable, add "scroll" to 'tabpanelopt': >
+ :set tabpanelopt+=scroll
+
+With "scroll" enabled, mouse wheel events over the tabpanel area scroll the
+tab list up or down. The scroll step follows the 'mousescroll' setting.
+Wheel events inside the tabpanel area are consumed by the tabpanel and do not
+trigger |<ScrollWheelUp>| or |<ScrollWheelDown>| mappings.
+
+To additionally show a vertical scrollbar indicating the current scroll
+position, use "scrollbar": >
+ :set tabpanelopt+=scrollbar
+
+The "scrollbar" value implies "scroll". A one-column scrollbar is reserved at
+the edge of the tabpanel; clicking on the scrollbar column moves the thumb to
+the click position, and the thumb can be dragged to scroll continuously.
+
+When "vert" is combined with "scrollbar", the scrollbar is drawn next to the
+vertical separator, on the panel side.
+
+The scrollbar uses the |hl-PmenuSbar| highlight group for the track and
+|hl-PmenuThumb| for the thumb.
+
+The scroll offset is remembered across redraws but is reset when "scroll" or
+"scrollbar" is toggled off and back on.
+
==============================================================================
6. Setting 'guitablabel' *setting-guitablabel*
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 2b0e6cab3..c4cc01bdc 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -10889,6 +10889,7 @@ tabpagebuflist() builtin.txt
/*tabpagebuflist()*
tabpagenr() builtin.txt /*tabpagenr()*
tabpagewinnr() builtin.txt /*tabpagewinnr()*
tabpanel tabpage.txt /*tabpanel*
+tabpanel-scroll tabpage.txt /*tabpanel-scroll*
tag tagsrch.txt /*tag*
tag-! tagsrch.txt /*tag-!*
tag-binary-search tagsrch.txt /*tag-binary-search*
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 90d563c90..90cd1a3ef 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -52616,6 +52616,9 @@ Other ~
- Allow mouse clickable regions in the 'statusline', 'tabline' and the
'tabpanel' using the |stl-%[FuncName]| atom.
- Enable reflow support in the |:terminal|.
+- Added "scroll" and "scrollbar" sub-options to 'tabpanelopt' so the
+ tabpanel can scroll when the tab list exceeds the visible screen
+ height.
Platform specific ~
-----------------
diff --git a/src/buffer.c b/src/buffer.c
index 7ea9e9351..44e504c53 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4946,6 +4946,9 @@ build_stl_str_hl_local(
maxwid = 50;
}
}
+ // Keep the uncapped value for %N[FuncName] click-region IDs; the 50
+ // cap below applies only when minwid is used as a padding width.
+ int raw_minwid = minwid * l;
minwid = (minwid > 50 ? 50 : minwid) * l;
if (*s == '(')
{
@@ -5306,7 +5309,11 @@ build_stl_str_hl_local(
{
stl_items[curitem].stl_type = ClickFunc;
stl_items[curitem].stl_start = p;
- stl_items[curitem].stl_minwid = minwid;
+ // The stl_minwid field is overloaded: it may be the
+ // "min" part of %<min>.<max> used for padding, or an
+ // identifier passed to the %N[FuncName] callback. Store
+ // the uncapped value so IDs above 50 are preserved.
+ stl_items[curitem].stl_minwid = raw_minwid;
stl_items[curitem].stl_clickfunc =
vim_strnsave(s, rb - s);
s = rb + 1;
diff --git a/src/mouse.c b/src/mouse.c
index f6ab77004..93fdd3182 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -240,6 +240,9 @@ do_mouse(
int in_status_line; // mouse in status line
static int in_tab_line = FALSE; // mouse clicked in tab line
static int in_tabpanel = FALSE; // mouse clicked in tabpanel
+#ifdef FEAT_TABPANEL
+ static bool in_tabpanel_scrollbar = false; // dragging tabpanel
scrollbar
+#endif
int in_sep_line; // mouse in vertical separator line
int c1, c2;
#if defined(FEAT_FOLDING)
@@ -346,6 +349,9 @@ do_mouse(
got_click = TRUE;
in_tab_line = FALSE;
in_tabpanel = FALSE;
+#ifdef FEAT_TABPANEL
+ in_tabpanel_scrollbar = false;
+#endif
}
else
{
@@ -354,15 +360,31 @@ do_mouse(
if (!is_drag) // release, reset got_click
{
got_click = FALSE;
- if (in_tab_line || in_tabpanel)
+ if (in_tab_line || in_tabpanel
+#ifdef FEAT_TABPANEL
+ || in_tabpanel_scrollbar
+#endif
+ )
{
in_tab_line = FALSE;
in_tabpanel = FALSE;
+#ifdef FEAT_TABPANEL
+ in_tabpanel_scrollbar = false;
+#endif
return FALSE;
}
}
}
+#ifdef FEAT_TABPANEL
+ // Continue a scrollbar drag before any tab-selection handling.
+ if (is_drag && in_tabpanel_scrollbar)
+ {
+ tabpanel_drag_scrollbar(mouse_row);
+ return FALSE;
+ }
+#endif
+
// CTRL right mouse button does CTRL-T
if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT)
{
@@ -494,6 +516,15 @@ do_mouse(
if (mouse_col < firstwin->w_wincol
|| mouse_col >= firstwin->w_wincol + topframe->fr_width)
{
+ // A click on the scrollbar column starts a drag interaction and
+ // preempts tab-selection.
+ if (is_click && !is_drag && mouse_on_tabpanel_scrollbar())
+ {
+ in_tabpanel_scrollbar = TRUE;
+ tabpanel_drag_scrollbar(mouse_row);
+ return FALSE;
+ }
+
// Dispatch 'tabpanel' %[FuncName] click regions before falling through
// to tab-page selection. On drag events fall through to the normal
// tab-drag handling.
@@ -1276,6 +1307,17 @@ ins_mousescroll(int dir)
cap.oap = &oa;
cap.arg = dir;
+#ifdef FEAT_TABPANEL
+ if (mouse_row >= 0 && mouse_col >= 0
+ && (dir == MSCR_UP || dir == MSCR_DOWN)
+ && mouse_on_tabpanel())
+ {
+ (void)tabpanel_scroll(dir == MSCR_UP ? 1 : -1,
+ mouse_vert_step > 0 ? mouse_vert_step : 3);
+ return;
+ }
+#endif
+
switch (dir)
{
case MSCR_UP:
@@ -2409,6 +2451,17 @@ nv_mousescroll(cmdarg_T *cap)
{
win_T *old_curwin = curwin;
+#ifdef FEAT_TABPANEL
+ if (mouse_row >= 0 && mouse_col >= 0
+ && (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN)
+ && mouse_on_tabpanel())
+ {
+ (void)tabpanel_scroll(cap->arg == MSCR_UP ? 1 : -1,
+ mouse_vert_step > 0 ? mouse_vert_step : 3);
+ return;
+ }
+#endif
+
if (mouse_row >= 0 && mouse_col >= 0)
{
// Find the window at the mouse pointer coordinates.
diff --git a/src/proto/tabpanel.pro b/src/proto/tabpanel.pro
index d62d13f3a..72726d89e 100644
--- a/src/proto/tabpanel.pro
+++ b/src/proto/tabpanel.pro
@@ -4,4 +4,8 @@ int tabpanel_width(void);
int tabpanel_leftcol(void);
void draw_tabpanel(void);
int get_tabpagenr_on_tabpanel(void);
+bool mouse_on_tabpanel(void);
+bool mouse_on_tabpanel_scrollbar(void);
+bool tabpanel_drag_scrollbar(int screen_row);
+bool tabpanel_scroll(int dir, int count);
/* vim: set ft=c : */
diff --git a/src/tabpanel.c b/src/tabpanel.c
index 4138f9760..07be48e44 100644
--- a/src/tabpanel.c
+++ b/src/tabpanel.c
@@ -20,6 +20,7 @@ static void do_by_tplmode(int tplmode, int col_start, int
col_end,
static void tabpanel_free_click_regions(void);
static void tabpanel_append_click_regions(stl_clickrec_T *clicktab,
char_u *buf, int row, int col_start, int col_end, int tabnr);
+static void draw_tabpanel_scrollbar(int screen_col);
// set pcurtab_row. don't redraw tabpanel.
#define TPLMODE_GET_CURTAB_ROW 0
@@ -31,6 +32,7 @@ static void tabpanel_append_click_regions(stl_clickrec_T
*clicktab,
#define TPL_FILLCHAR ' '
#define VERT_LEN 1
+#define SCROLL_LEN 1
// tpl_align's values
#define ALIGN_LEFT 0
@@ -40,7 +42,12 @@ static char_u *opt_name = (char_u *)"tabpanel";
static int opt_scope = OPT_LOCAL;
static int tpl_align = ALIGN_LEFT;
static int tpl_columns = 20;
-static int tpl_is_vert = FALSE;
+static bool tpl_is_vert = false;
+static bool tpl_scroll = false;
+static bool tpl_scrollbar = false;
+static int tpl_scroll_offset = 0;
+static int tpl_total_rows = 0;
+static int tpl_scrollbar_col = -1; // screen column of scrollbar, -1 if
none
typedef struct {
win_T *wp;
@@ -61,7 +68,9 @@ tabpanelopt_changed(void)
char_u *p;
int new_align = ALIGN_LEFT;
long new_columns = 20;
- int new_is_vert = FALSE;
+ bool new_is_vert = false;
+ bool new_scroll = false;
+ bool new_scrollbar = false;
p = p_tplo;
while (*p != NUL)
@@ -92,7 +101,18 @@ tabpanelopt_changed(void)
else if (STRNCMP(p, "vert", 4) == 0)
{
p += 4;
- new_is_vert = TRUE;
+ new_is_vert = true;
+ }
+ else if (STRNCMP(p, "scrollbar", 9) == 0)
+ {
+ p += 9;
+ new_scrollbar = true;
+ new_scroll = true;
+ }
+ else if (STRNCMP(p, "scroll", 6) == 0)
+ {
+ p += 6;
+ new_scroll = true;
}
if (*p != ',' && *p != NUL)
@@ -104,6 +124,10 @@ tabpanelopt_changed(void)
tpl_align = new_align;
tpl_columns = new_columns;
tpl_is_vert = new_is_vert;
+ if (tpl_scroll != new_scroll)
+ tpl_scroll_offset = 0;
+ tpl_scroll = new_scroll;
+ tpl_scrollbar = new_scrollbar;
shell_new_columns();
return OK;
@@ -266,39 +290,65 @@ draw_tabpanel(void)
// Reset got_int to avoid build_stl_str_hl() isn't evaluated.
got_int = FALSE;
+ int sb_len = tpl_scrollbar ? SCROLL_LEN : 0;
+ int sb_screen_col = -1;
+
if (tpl_is_vert)
{
if (is_right)
{
// draw main contents in tabpanel
- do_by_tplmode(TPLMODE_GET_CURTAB_ROW, VERT_LEN,
+ do_by_tplmode(TPLMODE_GET_CURTAB_ROW, VERT_LEN + sb_len,
maxwidth - VERT_LEN, &curtab_row, NULL);
- do_by_tplmode(TPLMODE_REDRAW, VERT_LEN, maxwidth, &curtab_row,
- NULL);
+ do_by_tplmode(TPLMODE_REDRAW, VERT_LEN + sb_len, maxwidth,
+ &curtab_row, NULL);
// draw vert separator in tabpanel
for (vsrow = 0; vsrow < Rows; vsrow++)
screen_putchar(curwin->w_fill_chars.tpl_vert, vsrow,
topframe->fr_width, vs_attr);
+ if (tpl_scrollbar)
+ sb_screen_col = topframe->fr_width + VERT_LEN;
}
else
{
// draw main contents in tabpanel
- do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth - VERT_LEN,
- &curtab_row, NULL);
- do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - VERT_LEN,
+ do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0,
+ maxwidth - VERT_LEN - sb_len, &curtab_row, NULL);
+ do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - VERT_LEN - sb_len,
&curtab_row, NULL);
// draw vert separator in tabpanel
for (vsrow = 0; vsrow < Rows; vsrow++)
screen_putchar(curwin->w_fill_chars.tpl_vert, vsrow,
maxwidth - VERT_LEN, vs_attr);
+ if (tpl_scrollbar)
+ sb_screen_col = maxwidth - VERT_LEN - SCROLL_LEN;
}
}
else
{
- do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth, &curtab_row, NULL);
- do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth, &curtab_row, NULL);
+ if (is_right)
+ {
+ do_by_tplmode(TPLMODE_GET_CURTAB_ROW, sb_len, maxwidth,
+ &curtab_row, NULL);
+ do_by_tplmode(TPLMODE_REDRAW, sb_len, maxwidth, &curtab_row, NULL);
+ if (tpl_scrollbar)
+ sb_screen_col = topframe->fr_width;
+ }
+ else
+ {
+ do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth - sb_len,
+ &curtab_row, NULL);
+ do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - sb_len,
+ &curtab_row, NULL);
+ if (tpl_scrollbar)
+ sb_screen_col = maxwidth - SCROLL_LEN;
+ }
}
+ tpl_scrollbar_col = sb_screen_col;
+ if (sb_screen_col >= 0)
+ draw_tabpanel_scrollbar(sb_screen_col);
+
got_int |= saved_got_int;
// A user function may reset KeyTyped, restore it.
@@ -556,8 +606,13 @@ do_by_tplmode(
args.col_end = col_end;
if (tplmode != TPLMODE_GET_CURTAB_ROW && args.maxrow > 0)
- while (args.offsetrow + args.maxrow <= *pcurtab_row)
- args.offsetrow += args.maxrow;
+ {
+ if (tpl_scroll)
+ args.offsetrow = tpl_scroll_offset;
+ else
+ while (args.offsetrow + args.maxrow <= *pcurtab_row)
+ args.offsetrow += args.maxrow;
+ }
tp = first_tabpage;
@@ -579,8 +634,13 @@ do_by_tplmode(
if (tplmode == TPLMODE_GET_CURTAB_ROW)
{
*pcurtab_row = row;
- do_unlet((char_u *)"g:actual_curtabpage", TRUE);
- break;
+ // When scroll mode is active keep iterating so tpl_total_rows
+ // receives the true content height; otherwise bail out early.
+ if (!tpl_scroll)
+ {
+ do_unlet((char_u *)"g:actual_curtabpage", TRUE);
+ break;
+ }
}
}
else
@@ -608,7 +668,8 @@ do_by_tplmode(
stl_hlrec_T *tabtab;
stl_clickrec_T *clicktab = NULL;
- if (args.maxrow <= row - args.offsetrow)
+ if (tplmode != TPLMODE_GET_CURTAB_ROW
+ && args.maxrow <= row - args.offsetrow)
break;
buf[0] = NUL;
@@ -677,6 +738,142 @@ do_by_tplmode(
// fill the area of TabPanelFill.
screen_fill_tailing_area(tplmode, MAX(row - args.offsetrow, 0),
args.maxrow,
args.col_start, args.col_end, attr_tplf);
+
+ // Capture the true content height during the GET_CURTAB_ROW pass, which
+ // ignores maxrow and therefore walks every tab. REDRAW stops at the
+ // visible edge so its "row" is clamped and unusable here.
+ if (tplmode == TPLMODE_GET_CURTAB_ROW && tpl_scroll)
+ tpl_total_rows = row;
+}
+
+/*
+ * Draw the tabpanel scrollbar (track + thumb) at screen column 'screen_col'.
+ * The scrollbar spans the full screen height. The thumb position and size
+ * are derived from tpl_scroll_offset, tpl_total_rows and Rows.
+ */
+ static void
+draw_tabpanel_scrollbar(int screen_col)
+{
+ int attr_sb = HL_ATTR(HLF_PSB);
+ int attr_thumb = HL_ATTR(HLF_PST);
+ int thumb_top = 0;
+ int thumb_height = 0;
+
+ if (tpl_total_rows > Rows && Rows > 0)
+ {
+ thumb_height = Rows * Rows / tpl_total_rows;
+ if (thumb_height < 1)
+ thumb_height = 1;
+ thumb_top = Rows * tpl_scroll_offset / tpl_total_rows;
+ if (thumb_top + thumb_height > Rows)
+ thumb_top = Rows - thumb_height;
+ if (thumb_top < 0)
+ thumb_top = 0;
+ }
+
+ for (int r = 0; r < Rows; r++)
+ {
+ bool on_thumb = thumb_height > 0
+ && r >= thumb_top && r < thumb_top + thumb_height;
+ screen_putchar(TPL_FILLCHAR, r, screen_col,
+ on_thumb ? attr_thumb : attr_sb);
+ }
+}
+
+/*
+ * Return true if the mouse is currently positioned over the tabpanel area.
+ */
+ bool
+mouse_on_tabpanel(void)
+{
+ if (tabpanel_width() == 0)
+ return false;
+ return mouse_col < firstwin->w_wincol
+ || mouse_col >= firstwin->w_wincol + topframe->fr_width;
+}
+
+/*
+ * Return true if the mouse is currently on the scrollbar column.
+ * The scrollbar column is tracked by draw_tabpanel() and is -1 when the
+ * scrollbar is not enabled or not yet drawn.
+ */
+ bool
+mouse_on_tabpanel_scrollbar(void)
+{
+ return tpl_scrollbar && tpl_scrollbar_col >= 0
+ && mouse_col == tpl_scrollbar_col;
+}
+
+/*
+ * Move the scrollbar thumb so it is vertically centred on screen row
+ * 'screen_row', updating tpl_scroll_offset accordingly. Used for both
+ * initial clicks and subsequent drag events.
+ * Returns true if the event was consumed (offset changed or not).
+ */
+ bool
+tabpanel_drag_scrollbar(int screen_row)
+{
+ int thumb_height;
+ int max_offset;
+ int track_range;
+ int thumb_top;
+ int new_offset;
+
+ if (!tpl_scrollbar || Rows <= 0 || tpl_total_rows <= Rows)
+ return false;
+
+ thumb_height = Rows * Rows / tpl_total_rows;
+ if (thumb_height < 1)
+ thumb_height = 1;
+ track_range = Rows - thumb_height;
+ if (track_range <= 0)
+ return true;
+
+ max_offset = tpl_total_rows - Rows;
+ thumb_top = screen_row - thumb_height / 2;
+ if (thumb_top < 0)
+ thumb_top = 0;
+ if (thumb_top > track_range)
+ thumb_top = track_range;
+
+ new_offset = thumb_top * max_offset / track_range;
+ if (new_offset != tpl_scroll_offset)
+ {
+ tpl_scroll_offset = new_offset;
+ redraw_tabpanel = TRUE;
+ }
+ return true;
+}
+
+/*
+ * Scroll the tabpanel by 'count' rows in direction 'dir' (1 = down, -1 = up).
+ * Returns true if the offset changed and a redraw was scheduled.
+ * Has no effect unless 'tabpanelopt' contains "scroll".
+ */
+ bool
+tabpanel_scroll(int dir, int count)
+{
+ int max_offset;
+ int new_offset;
+
+ if (!tpl_scroll || tabpanel_width() == 0)
+ return false;
+
+ max_offset = tpl_total_rows - Rows;
+ if (max_offset < 0)
+ max_offset = 0;
+
+ new_offset = tpl_scroll_offset + (dir > 0 ? count : -count);
+ if (new_offset < 0)
+ new_offset = 0;
+ if (new_offset > max_offset)
+ new_offset = max_offset;
+ if (new_offset == tpl_scroll_offset)
+ return false;
+
+ tpl_scroll_offset = new_offset;
+ redraw_tabpanel = TRUE;
+ return true;
}
#endif // FEAT_TABPANEL
diff --git a/src/testdir/test_tabpanel.vim b/src/testdir/test_tabpanel.vim
index 7803a0eb4..427360aed 100644
--- a/src/testdir/test_tabpanel.vim
+++ b/src/testdir/test_tabpanel.vim
@@ -962,8 +962,68 @@ func Test_tabpanel_large_columns()
call assert_fails(':set tabpanelopt=columns:-1', 'E474:')
endfunc
+func Test_tabpanel_scrollopt_accepted()
+ " 'scroll' / 'scrollbar' must be accepted in 'tabpanelopt'.
+ set tabpanelopt=scroll
+ call assert_equal('scroll', &tabpanelopt)
+ set tabpanelopt=scrollbar
+ call assert_equal('scrollbar', &tabpanelopt)
+
+ " Combination with other values.
+ set tabpanelopt=align:right,scroll
+ call assert_equal('align:right,scroll', &tabpanelopt)
+ set tabpanelopt=columns:15,vert,scrollbar
+ call assert_equal('columns:15,vert,scrollbar', &tabpanelopt)
+ set tabpanelopt=align:right,columns:12,vert,scrollbar
+ call assert_equal('align:right,columns:12,vert,scrollbar', &tabpanelopt)
+
+ " Unknown values must still fail.
+ call assert_fails(':set tabpanelopt=scrol', 'E474:')
+ call assert_fails(':set tabpanelopt=scrollbarx', 'E474:')
+
+ call s:reset()
+endfunc
+
+func Test_tabpanel_scroll_many_tabs()
+ let save_lines = &lines
+ let save_showtabpanel = &showtabpanel
+ let save_tabpanelopt = &tabpanelopt
+
+ " Make the screen short so the tab list exceeds the visible height.
+ set lines=8
+ set showtabpanel=2
+ set tabpanelopt=scroll
+ for i in range(20)
+ tabnew
+ endfor
+
+ " Should not crash with many tabs and scroll enabled.
+ redraw!
+
+ " Switching to scrollbar resets the offset but must also not crash.
+ set tabpanelopt=scrollbar
+ redraw!
+
+ " Disabling scroll returns to normal behavior.
+ set tabpanelopt=
+ redraw!
+
+ " Right alignment with scrollbar.
+ set tabpanelopt=align:right,scrollbar
+ redraw!
+
+ " Vertical separator with scrollbar.
+ set tabpanelopt=columns:10,vert,scrollbar
+ redraw!
+
+ " Cleanup.
+ %bwipeout!
+ let &tabpanelopt = save_tabpanelopt
+ let &showtabpanel = save_showtabpanel
+ let &lines = save_lines
+endfunc
+
func Test_tabpanel_variable_height()
- CheckFeature tabpanel
let save_lines = &lines
let save_showtabpanel = &showtabpanel
diff --git a/src/version.c b/src/version.c
index aa38e1a35..36a8da078 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 386,
/**/
385,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1wFHxw-00EKsZ-Of%40256bit.org.