aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-08-13 10:45:21 +0200
committerbfredl <bjorn.linse@gmail.com>2022-08-13 10:45:21 +0200
commit33f4ba7379b5ad1670f9168dd98e3031780776f1 (patch)
treef7bda95f5e50a98a3b61cbbd1811f2ecad8502da
parenta850b15e1968476e0f609a9d699cdf24fd13e3a2 (diff)
downloadrneovim-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.c4
-rw-r--r--src/nvim/buffer.c4
-rw-r--r--src/nvim/option.c8
-rw-r--r--src/nvim/ui.c2
-rw-r--r--src/nvim/window.c34
-rw-r--r--test/functional/ui/winbar_spec.lua134
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)