mirror of
https://github.com/neovim/neovim.git
synced 2026-03-06 17:17:21 +00:00
fix(statusline): broken statusline on error #38000
Problem: after #33036, an error from evaluating 'statusline' clears it and doesn't draw the statusline. (causing glitchy redraws) Solution: use the default value instead. If 'stl' is somehow ever empty, still call redraw_custom_statusline to at least draw an empty statusline. Ideally our default 'stl' shouldn't itself error too! :-) Also adjust some prior screen:expect()s to avoid immediate success warnings.
This commit is contained in:
@@ -6286,10 +6286,10 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
current window and buffer, while %{} items are evaluated in the
|
||||
context of the window that the statusline belongs to.
|
||||
|
||||
When there is error while evaluating the option then it will be made
|
||||
empty to avoid further errors. Otherwise screen updating would loop.
|
||||
When the result contains unprintable characters the result is
|
||||
unpredictable.
|
||||
When there is an error while evaluating the option it will be reset to
|
||||
its default value to avoid further errors. Otherwise screen updating
|
||||
would loop. When the result contains unprintable characters the
|
||||
result is unpredictable.
|
||||
|
||||
Note that the only effect of 'ruler' when this option is set (and
|
||||
'laststatus' is 2 or 3) is controlling the output of |CTRL-G|.
|
||||
|
||||
8
runtime/lua/vim/_meta/options.lua
generated
8
runtime/lua/vim/_meta/options.lua
generated
@@ -6728,10 +6728,10 @@ vim.wo.stc = vim.wo.statuscolumn
|
||||
--- current window and buffer, while %{} items are evaluated in the
|
||||
--- context of the window that the statusline belongs to.
|
||||
---
|
||||
--- When there is error while evaluating the option then it will be made
|
||||
--- empty to avoid further errors. Otherwise screen updating would loop.
|
||||
--- When the result contains unprintable characters the result is
|
||||
--- unpredictable.
|
||||
--- When there is an error while evaluating the option it will be reset to
|
||||
--- its default value to avoid further errors. Otherwise screen updating
|
||||
--- would loop. When the result contains unprintable characters the
|
||||
--- result is unpredictable.
|
||||
---
|
||||
--- Note that the only effect of 'ruler' when this option is set (and
|
||||
--- 'laststatus' is 2 or 3) is controlling the output of `CTRL-G`.
|
||||
|
||||
@@ -8794,10 +8794,10 @@ local options = {
|
||||
current window and buffer, while %{} items are evaluated in the
|
||||
context of the window that the statusline belongs to.
|
||||
|
||||
When there is error while evaluating the option then it will be made
|
||||
empty to avoid further errors. Otherwise screen updating would loop.
|
||||
When the result contains unprintable characters the result is
|
||||
unpredictable.
|
||||
When there is an error while evaluating the option it will be reset to
|
||||
its default value to avoid further errors. Otherwise screen updating
|
||||
would loop. When the result contains unprintable characters the
|
||||
result is unpredictable.
|
||||
|
||||
Note that the only effect of 'ruler' when this option is set (and
|
||||
'laststatus' is 2 or 3) is controlling the output of |CTRL-G|.
|
||||
|
||||
@@ -85,8 +85,7 @@ void win_redr_status(win_T *wp)
|
||||
// Don't redraw right now, do it later. Don't update status line when
|
||||
// popup menu is visible and may be drawn over it
|
||||
wp->w_redr_status = true;
|
||||
} else if (*wp->w_p_stl != NUL
|
||||
|| (*p_stl != NUL && (!wp->w_floating || (is_stl_global && wp == curwin)))) {
|
||||
} else if (*wp->w_p_stl != NUL || !wp->w_floating || (is_stl_global && wp == curwin)) {
|
||||
// redraw custom status line
|
||||
redraw_custom_statusline(wp);
|
||||
}
|
||||
@@ -2136,13 +2135,12 @@ stcsign:
|
||||
redraw_not_allowed = save_redraw_not_allowed;
|
||||
|
||||
// Check for an error. If there is one the display will be messed up and
|
||||
// might loop redrawing. Avoid that by making the corresponding option
|
||||
// empty.
|
||||
// might loop redrawing. Avoid that by setting the option to its default.
|
||||
// TODO(Bram): find out why using called_emsg_before makes tests fail, does it
|
||||
// matter?
|
||||
// if (called_emsg > called_emsg_before)
|
||||
if (opt_idx != kOptInvalid && did_emsg > did_emsg_before) {
|
||||
set_option_direct(opt_idx, STATIC_CSTR_AS_OPTVAL(""), opt_scope, SID_ERROR);
|
||||
set_option_direct(opt_idx, get_option_default(opt_idx, opt_scope), opt_scope, SID_ERROR);
|
||||
}
|
||||
|
||||
// A user function may reset KeyTyped, restore it.
|
||||
|
||||
@@ -949,6 +949,12 @@ describe('default statusline', function()
|
||||
it('setting statusline to empty string sets default statusline', function()
|
||||
exec_lua("vim.o.statusline = 'asdf'")
|
||||
eq('asdf', eval('&statusline'))
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|*13
|
||||
{3:asdf }|
|
||||
|
|
||||
]])
|
||||
|
||||
local default_statusline = table.concat({
|
||||
'%<',
|
||||
@@ -962,15 +968,37 @@ describe('default statusline', function()
|
||||
})
|
||||
|
||||
exec_lua("vim.o.statusline = ''")
|
||||
|
||||
eq(default_statusline, eval('&statusline'))
|
||||
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|*13
|
||||
{3:[No Name] 0,0-1 All}|
|
||||
|
|
||||
]])
|
||||
|
||||
-- Reset to default (via the correct scope) if there's an error.
|
||||
command('setglobal statusline=%{a%}')
|
||||
eq(default_statusline, eval('&statusline'))
|
||||
eq(default_statusline, eval('&g:statusline'))
|
||||
eq('', eval('&l:statusline'))
|
||||
command('redrawstatus') -- like Vim, statusline isn't immediately redrawn after an error
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|*13
|
||||
{3:[No Name] 0,0-1 All}|
|
||||
{9:E121: Undefined variable: a} |
|
||||
]])
|
||||
command('setlocal statusline=%{b%}')
|
||||
eq(default_statusline, eval('&statusline'))
|
||||
eq(default_statusline, eval('&g:statusline'))
|
||||
eq('', eval('&l:statusline'))
|
||||
command('redrawstatus') -- like Vim, statusline isn't immediately redrawn after an error
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|*13
|
||||
{3:[No Name] 0,0-1 All}|
|
||||
{9:E121: Undefined variable: b} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('shows busy status when buffer is set to be busy', function()
|
||||
@@ -1064,7 +1092,7 @@ describe("'statusline' in floatwin", function()
|
||||
|
||||
-- no statusline is displayed because the statusline option was cleared
|
||||
api.nvim_win_set_config(win, cfg)
|
||||
screen:expect(without_stl)
|
||||
screen:expect_unchanged()
|
||||
|
||||
-- displayed after the option is reset
|
||||
command(set_stl)
|
||||
@@ -1090,6 +1118,19 @@ describe("'statusline' in floatwin", function()
|
||||
]])
|
||||
command('tabfirst')
|
||||
api.nvim_win_set_config(win2, { style = 'minimal' })
|
||||
screen:expect([[
|
||||
{5: }{101:2}{5:+ [No Name] }{24: }{102:2}{24:+ [No Name] }{2: }{24:X}|
|
||||
┌──────────┐ |
|
||||
{1:~}│{4:^1 }│{1: }|
|
||||
{1:~}│{4:2 }│{1: }|
|
||||
{1:~}│{4:3 }│{1: }|
|
||||
{1:~}│{4:4 }│{1: }|
|
||||
{1:~}│{3:<Name] [+]}│{1: }|
|
||||
{1:~}└──────────┘{1: }|
|
||||
{1:~ }|*10
|
||||
{2:[No Name] }|
|
||||
|
|
||||
]])
|
||||
command('tabnext')
|
||||
screen:expect([[
|
||||
{24: }{102:2}{24:+ [No Name] }{5: }{101:2}{5:+ [No Name] }{2: }{24:X}|
|
||||
|
||||
@@ -64,7 +64,9 @@ func Test_statusline_will_be_disabled_with_error()
|
||||
catch
|
||||
endtry
|
||||
call assert_true(s:func_in_statusline_called)
|
||||
call assert_equal('', &statusline)
|
||||
" Nvim: resets to default value instead.
|
||||
" call assert_equal('', &statusline)
|
||||
call assert_equal(nvim_get_option_info2('statusline', {}).default, &statusline)
|
||||
set statusline=
|
||||
endfunc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user