diff options
author | bfredl <bjorn.linse@gmail.com> | 2022-08-13 10:45:21 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-08-13 10:45:21 +0200 |
commit | 33f4ba7379b5ad1670f9168dd98e3031780776f1 (patch) | |
tree | f7bda95f5e50a98a3b61cbbd1811f2ecad8502da | |
parent | a850b15e1968476e0f609a9d699cdf24fd13e3a2 (diff) | |
download | rneovim-33f4ba7379b5ad1670f9168dd98e3031780776f1.tar.gz rneovim-33f4ba7379b5ad1670f9168dd98e3031780776f1.tar.bz2 rneovim-33f4ba7379b5ad1670f9168dd98e3031780776f1.zip |
fix(winbar): do not always assume cursor is valid. fixes #19458
-rw-r--r-- | src/nvim/api/win_config.c | 4 | ||||
-rw-r--r-- | src/nvim/buffer.c | 4 | ||||
-rw-r--r-- | src/nvim/option.c | 8 | ||||
-rw-r--r-- | src/nvim/ui.c | 2 | ||||
-rw-r--r-- | src/nvim/window.c | 34 | ||||
-rw-r--r-- | test/functional/ui/winbar_spec.lua | 134 |
6 files changed, 119 insertions, 67 deletions
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 969643eeef..a153f746b6 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -167,7 +167,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, E if (fconfig.style == kWinStyleMinimal) { win_set_minimal_style(wp); - didset_window_options(wp); + didset_window_options(wp, true); } return wp->handle; } @@ -209,7 +209,7 @@ void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) } if (fconfig.style == kWinStyleMinimal) { win_set_minimal_style(win); - didset_window_options(win); + didset_window_options(win, true); } } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7c187ca735..ce788cc7a0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2596,7 +2596,7 @@ void get_winopts(buf_T *buf) } if (curwin->w_float_config.style == kWinStyleMinimal) { - didset_window_options(curwin); + didset_window_options(curwin, false); win_set_minimal_style(curwin); } @@ -2604,7 +2604,7 @@ void get_winopts(buf_T *buf) if (p_fdls >= 0) { curwin->w_p_fdl = p_fdls; } - didset_window_options(curwin); + didset_window_options(curwin, false); } /// Find the mark for the buffer 'buf' for the current window. diff --git a/src/nvim/option.c b/src/nvim/option.c index 3305f2c16d..916c460ed6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1981,7 +1981,7 @@ static void didset_options(void) (void)check_cedit(); // initialize the table for 'breakat'. fill_breakat_flags(); - didset_window_options(curwin); + didset_window_options(curwin, true); } // More side effects of setting options. @@ -6303,7 +6303,7 @@ void win_copy_options(win_T *wp_from, win_T *wp_to) { copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt); copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt); - didset_window_options(wp_to); + didset_window_options(wp_to, true); } /// Copy the options from one winopt_T to another. @@ -6428,7 +6428,7 @@ void clear_winopt(winopt_T *wop) clear_string_option((char_u **)&wop->wo_wbr); } -void didset_window_options(win_T *wp) +void didset_window_options(win_T *wp, bool valid_cursor) { check_colorcolumn(wp); briopt_check(wp); @@ -6437,7 +6437,7 @@ void didset_window_options(win_T *wp) set_chars_option(wp, &wp->w_p_lcs, true); parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl check_blending(wp); - set_winbar_win(wp, false); + set_winbar_win(wp, false, valid_cursor); wp->w_grid_alloc.blending = wp->w_p_winbl > 0; } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 2cbdeb318b..be0dda0a2f 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -662,6 +662,6 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) // non-positive indicates no request wp->w_height_request = MAX(height, 0); wp->w_width_request = MAX(width, 0); - win_set_inner_size(wp); + win_set_inner_size(wp, true); } } diff --git a/src/nvim/window.c b/src/nvim/window.c index 1eff379f77..9d2432ea3b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -705,7 +705,7 @@ win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err) wp->w_vsep_width = 0; win_config_float(wp, fconfig); - win_set_inner_size(wp); + win_set_inner_size(wp, true); wp->w_pos_changed = true; redraw_later(wp, VALID); return wp; @@ -789,7 +789,7 @@ void win_config_float(win_T *wp, FloatConfig fconfig) wp->w_width = MIN(wp->w_width, Columns - win_border_width(wp)); } - win_set_inner_size(wp); + win_set_inner_size(wp, true); must_redraw = MAX(must_redraw, VALID); wp->w_pos_changed = true; @@ -6162,7 +6162,7 @@ void win_new_height(win_T *wp, int height) wp->w_height = height; wp->w_pos_changed = true; - win_set_inner_size(wp); + win_set_inner_size(wp, true); } void scroll_to_fraction(win_T *wp, int prev_height) @@ -6271,7 +6271,7 @@ void scroll_to_fraction(win_T *wp, int prev_height) invalidate_botline_win(wp); } -void win_set_inner_size(win_T *wp) +void win_set_inner_size(win_T *wp, bool valid_cursor) { int width = wp->w_width_request; if (width == 0) { @@ -6285,7 +6285,7 @@ void win_set_inner_size(win_T *wp) } if (height != prev_height) { - if (height > 0) { + if (height > 0 && valid_cursor) { if (wp == curwin) { // w_wrow needs to be valid. When setting 'laststatus' this may // call win_new_height() recursively. @@ -6304,7 +6304,7 @@ void win_set_inner_size(win_T *wp) // There is no point in adjusting the scroll position when exiting. Some // values might be invalid. // Skip scroll_to_fraction() when 'cmdheight' was set to one from zero. - if (!exiting && !made_cmdheight_nonzero) { + if (!exiting && !made_cmdheight_nonzero && valid_cursor) { scroll_to_fraction(wp, prev_height); } redraw_later(wp, NOT_VALID); // SOME_VALID?? @@ -6313,11 +6313,13 @@ void win_set_inner_size(win_T *wp) if (width != wp->w_width_inner) { wp->w_width_inner = width; wp->w_lines_valid = 0; - changed_line_abv_curs_win(wp); - invalidate_botline_win(wp); - if (wp == curwin) { - update_topline(wp); - curs_columns(wp, true); // validate w_wrow + if (valid_cursor) { + changed_line_abv_curs_win(wp); + invalidate_botline_win(wp); + if (wp == curwin) { + update_topline(wp); + curs_columns(wp, true); // validate w_wrow + } } redraw_later(wp, NOT_VALID); } @@ -6346,7 +6348,7 @@ static int win_border_width(win_T *wp) void win_new_width(win_T *wp, int width) { wp->w_width = width; - win_set_inner_size(wp); + win_set_inner_size(wp, true); wp->w_redr_status = true; wp->w_pos_changed = true; @@ -6738,9 +6740,11 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) /// Add or remove window bar from window "wp". /// /// @param make_room Whether to resize frames to make room for winbar. +/// @param valid_cursor Whether the cursor is valid and should be used while +/// resizing. /// /// @return Success status. -int set_winbar_win(win_T *wp, bool make_room) +int set_winbar_win(win_T *wp, bool make_room, bool valid_cursor) { // Require the local value to be set in order to show winbar on a floating window. int winbar_height = wp->w_floating ? ((*wp->w_p_wbr != NUL) ? 1 : 0) @@ -6756,7 +6760,7 @@ int set_winbar_win(win_T *wp, bool make_room) } } wp->w_winbar_height = winbar_height; - win_set_inner_size(wp); + win_set_inner_size(wp, valid_cursor); wp->w_redr_status = wp->w_redr_status || winbar_height; if (winbar_height == 0) { @@ -6777,7 +6781,7 @@ int set_winbar_win(win_T *wp, bool make_room) void set_winbar(bool make_room) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (set_winbar_win(wp, make_room) == FAIL) { + if (set_winbar_win(wp, make_room, true) == FAIL) { break; } } diff --git a/test/functional/ui/winbar_spec.lua b/test/functional/ui/winbar_spec.lua index 60fa10da87..8976c4371f 100644 --- a/test/functional/ui/winbar_spec.lua +++ b/test/functional/ui/winbar_spec.lua @@ -579,47 +579,95 @@ describe('winbar', function() end) end) -it('local winbar works with tabs', function() - clear() - local screen = Screen.new(60, 13) - screen:attach() - screen:set_default_attr_ids({ - [1] = {bold = true}, - [2] = {reverse = true}, - [3] = {bold = true, foreground = Screen.colors.Blue}, - [4] = {underline = true, background = Screen.colors.LightGray} - }) - meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 }) - command('tabnew') - screen:expect([[ - {4: [No Name] }{1: [No Name] }{2: }{4:X}| - ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - | - ]]) - command('tabnext') - screen:expect{grid=[[ - {1: [No Name] }{4: [No Name] }{2: }{4:X}| - {1:foo }| - ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - | - ]]} +describe('local winbar with tabs', function() + local screen + before_each(function() + clear() + screen = Screen.new(60, 10) + screen:attach() + screen:set_default_attr_ids({ + [1] = {bold = true}, + [2] = {reverse = true}, + [3] = {bold = true, foreground = Screen.colors.Blue}, + [4] = {underline = true, background = Screen.colors.LightGray} + }) + meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 }) + end) + + it('works', function() + command('tabnew') + screen:expect([[ + {4: [No Name] }{1: [No Name] }{2: }{4:X}| + ^ | + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + | + ]]) + command('tabnext') + screen:expect{grid=[[ + {1: [No Name] }{4: [No Name] }{2: }{4:X}| + {1:foo }| + ^ | + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + | + ]]} + end) + + it('can edit new empty buffer #19458', function() + insert [[ + some + goofy + text]] + screen:expect{grid=[[ + {1:foo }| + some | + goofy | + tex^t | + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + | + ]]} + + -- this used to throw an E315 ml_get error + command 'tabedit' + screen:expect{grid=[[ + {4: + [No Name] }{1: [No Name] }{2: }{4:X}| + ^ | + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + | + ]]} + + command 'tabprev' + screen:expect{grid=[[ + {1: + [No Name] }{4: [No Name] }{2: }{4:X}| + {1:foo }| + some | + goofy | + tex^t | + {3:~ }| + {3:~ }| + {3:~ }| + {3:~ }| + | + ]]} + end) end) |