From ad84bbbd13ee9dff8370af4cee2ad414b1b0e398 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 6 Aug 2022 06:40:05 +0800 Subject: [PATCH 1/2] fix(tabpage): check if ROWS_AVAIL changed for resize --- src/nvim/buffer_defs.h | 19 ++++++------ src/nvim/window.c | 11 +++---- test/functional/editor/tabpage_spec.lua | 41 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3d4ac140f0..9b8aa09aa1 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -943,16 +943,15 @@ struct diffblock_S { typedef struct tabpage_S tabpage_T; struct tabpage_S { handle_T handle; - tabpage_T *tp_next; ///< next tabpage or NULL - frame_T *tp_topframe; ///< topframe for the windows - win_T *tp_curwin; ///< current window in this Tab page - win_T *tp_prevwin; ///< previous window in this Tab page - win_T *tp_firstwin; ///< first window in this Tab page - win_T *tp_lastwin; ///< last window in this Tab page - long tp_old_Rows; ///< Rows when Tab page was left - long tp_old_Columns; ///< Columns when Tab page was left - long tp_ch_used; ///< value of 'cmdheight' when frame size - ///< was set + tabpage_T *tp_next; ///< next tabpage or NULL + frame_T *tp_topframe; ///< topframe for the windows + win_T *tp_curwin; ///< current window in this Tab page + win_T *tp_prevwin; ///< previous window in this Tab page + win_T *tp_firstwin; ///< first window in this Tab page + win_T *tp_lastwin; ///< last window in this Tab page + long tp_old_Rows_avail; ///< ROWS_AVAIL when Tab page was left + long tp_old_Columns; ///< Columns when Tab page was left + long tp_ch_used; ///< value of 'cmdheight' when frame size was set diff_T *tp_first_diff; buf_T *(tp_diffbuf[DB_COUNT]); diff --git a/src/nvim/window.c b/src/nvim/window.c index 3400797f84..9837672e62 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4280,7 +4280,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) tp->tp_prevwin = prevwin; tp->tp_firstwin = firstwin; tp->tp_lastwin = lastwin; - tp->tp_old_Rows = Rows; + tp->tp_old_Rows_avail = ROWS_AVAIL; tp->tp_old_Columns = Columns; firstwin = NULL; lastwin = NULL; @@ -4320,10 +4320,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a const int row = win_comp_pos(); // recompute w_winrow for all windows diff_need_scrollbind = true; - // The tabpage line may have appeared or disappeared, may need to resize - // the frames for that. When the Vim window was resized need to update - // frame sizes too. Use the stored value of p_ch, so that it can be - // different for each tab page. + // Use the stored value of p_ch, so that it can be different for each tab page. if (p_ch != curtab->tp_ch_used) { clear_cmdline = true; } @@ -4336,7 +4333,9 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a clear_cmdline = true; } - if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow)) { + // The tabpage line may have appeared or disappeared, may need to resize the frames for that. + // When the Vim window was resized or ROWS_AVAIL changed need to update frame sizes too. + if (curtab->tp_old_Rows_avail != ROWS_AVAIL || (old_off != firstwin->w_winrow)) { shell_new_rows(); } if (curtab->tp_old_Columns != Columns && starting == 0) { diff --git a/test/functional/editor/tabpage_spec.lua b/test/functional/editor/tabpage_spec.lua index 2494daf99b..4eb19dcf3a 100644 --- a/test/functional/editor/tabpage_spec.lua +++ b/test/functional/editor/tabpage_spec.lua @@ -1,4 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command @@ -51,5 +52,45 @@ describe('tabpage', function() ]]) neq(999, eval('g:win_closed')) end) + + it('switching tabpage after setting laststatus=3 #19591', function() + local screen = Screen.new(40, 8) + screen:set_default_attr_ids({ + [0] = {bold = true, foreground = Screen.colors.Blue}, + [1] = {bold = true, reverse = true}, -- StatusLine + [2] = {reverse = true}, -- TabLineFill, WinSeparator + [3] = {bold = true}, -- TabLineSel + [4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine + [5] = {bold = true, foreground = Screen.colors.Magenta}, + }) + screen:attach() + + command('tabnew') + command('tabprev') + command('set laststatus=3') + command('tabnext') + feed('') + screen:expect([[ + {4: [No Name] }{3: [No Name] }{2: }{4:X}| + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {1:[No Name] }| + "[No Name]" --No lines in buffer-- | + ]]) + command('vnew') + screen:expect([[ + {4: [No Name] }{3: }{5:2}{3: [No Name] }{2: }{4:X}| + ^ {2:│} | + {0:~ }{2:│}{0:~ }| + {0:~ }{2:│}{0:~ }| + {0:~ }{2:│}{0:~ }| + {0:~ }{2:│}{0:~ }| + {1:[No Name] }| + "[No Name]" --No lines in buffer-- | + ]]) + end) end) From 37b3fc493cb911406a42dfd2f2958c23e53c4452 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 6 Aug 2022 06:45:44 +0800 Subject: [PATCH 2/2] fix(ui): set redraw_cmdline when setting window height --- src/nvim/window.c | 1 + ...tatusline_spec.lua => statusline_spec.lua} | 55 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) rename test/functional/ui/{global_statusline_spec.lua => statusline_spec.lua} (90%) diff --git a/src/nvim/window.c b/src/nvim/window.c index 9837672e62..00076b0a45 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5503,6 +5503,7 @@ void win_setheight_win(int height, win_T *win) msg_row = row; msg_col = 0; redraw_all_later(NOT_VALID); + redraw_cmdline = true; } } diff --git a/test/functional/ui/global_statusline_spec.lua b/test/functional/ui/statusline_spec.lua similarity index 90% rename from test/functional/ui/global_statusline_spec.lua rename to test/functional/ui/statusline_spec.lua index f6821ec589..3706a5589e 100644 --- a/test/functional/ui/global_statusline_spec.lua +++ b/test/functional/ui/statusline_spec.lua @@ -1,7 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, command, feed = helpers.clear, helpers.command, helpers.feed -local eq, funcs, meths = helpers.eq, helpers.funcs, helpers.meths +local assert_alive = helpers.assert_alive +local clear = helpers.clear +local command = helpers.command +local feed = helpers.feed +local eq = helpers.eq +local funcs = helpers.funcs +local meths = helpers.meths +local exec = helpers.exec describe('global statusline', function() local screen @@ -258,3 +264,48 @@ describe('global statusline', function() eq(1, meths.get_option('cmdheight')) end) end) + +it('statusline does not crash if it has Arabic characters #19447', function() + clear() + meths.set_option('statusline', 'غً') + meths.set_option('laststatus', 2) + command('redraw!') + assert_alive() +end) + +it('statusline is redrawn with :resize from mapping #19629', function() + clear() + local screen = Screen.new(40, 8) + screen:set_default_attr_ids({ + [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [1] = {bold = true, reverse = true}, -- StatusLine + }) + screen:attach() + exec([[ + set laststatus=2 + nnoremap resize -1 + nnoremap resize +1 + ]]) + feed('') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {1:[No Name] }| + | + | + ]]) + feed('') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {1:[No Name] }| + | + ]]) +end)