diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c08813ef04..6779c867ce 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6031,7 +6031,7 @@ A jump table for the options with a short description can be found at |Q_op|. an expensive expression can negatively affect render performance. *'statusline'* *'stl'* *E540* *E542* -'statusline' 'stl' string (default "") +'statusline' 'stl' string (default "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}") global or local to window |global-local| When non-empty, this option determines the content of the status line. Also see |status-line|. diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index df5b3960db..1e0e40a3a3 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -6685,7 +6685,7 @@ vim.wo.stc = vim.wo.statuscolumn --- --- --- @type string -vim.o.statusline = "" +vim.o.statusline = "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}" vim.o.stl = vim.o.statusline vim.wo.statusline = vim.o.statusline vim.wo.stl = vim.wo.statusline diff --git a/src/nvim/option.c b/src/nvim/option.c index 5299d2a237..59f9b21fe5 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -439,7 +439,7 @@ void set_init_1(bool clean_arg) /// @param opt_flags Option flags (can be OPT_LOCAL, OPT_GLOBAL or a combination). /// /// @return Default value of option for the scope specified in opt_flags. -static OptVal get_option_default(const OptIndex opt_idx, int opt_flags) +OptVal get_option_default(const OptIndex opt_idx, int opt_flags) { vimoption_T *opt = &options[opt_idx]; bool is_global_local_option = option_is_global_local(opt_idx); @@ -3468,7 +3468,7 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value .os_errbuf = errbuf, .os_errbuflen = errbuflen, .os_buf = curbuf, - .os_win = curwin + .os_win = curwin, }; if (direct) { diff --git a/src/nvim/options.lua b/src/nvim/options.lua index b70799c625..624e4166a9 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -8541,7 +8541,14 @@ local options = { { abbreviation = 'stl', cb = 'did_set_statusline', - defaults = '', + defaults = table.concat({ + '%<', + '%f %h%w%m%r ', + '%=', + "%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}", + "%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}", + "%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}", + }), desc = [=[ When non-empty, this option determines the content of the status line. Also see |status-line|. diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 9d5b2f8ff8..e26099d71b 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -1792,6 +1792,16 @@ static const char *did_set_statustabline_rulerformat(optset_T *args, bool rulerf } const char *errmsg = NULL; char *s = *varp; + + // reset statusline to default when setting global option and empty string is being set + if (args->os_idx == kOptStatusline + && ((args->os_flags & OPT_GLOBAL) || !(args->os_flags & OPT_LOCAL)) + && s[0] == NUL) { + xfree(*varp); + *varp = xstrdup(get_option_default(args->os_idx, args->os_flags).data.string.data); + s = *varp; + } + if (rulerformat && *s == '%') { // set ru_wid if 'ruf' starts with "%99(" if (*++s == '-') { // ignore a '-' diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index ddae023ad5..04336b112f 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -90,85 +90,6 @@ void win_redr_status(win_T *wp) } else if (*p_stl != NUL || *wp->w_p_stl != NUL) { // redraw custom status line redraw_custom_statusline(wp); - } else { - schar_T fillchar = fillchar_status(&attr, wp); - const int stl_width = is_stl_global ? Columns : wp->w_width; - - get_trans_bufname(wp->w_buffer); - char *p = NameBuff; - int plen = (int)strlen(p); - - if ((bt_help(wp->w_buffer) - || wp->w_p_pvw - || bufIsChanged(wp->w_buffer) - || wp->w_buffer->b_p_ro) - && plen < MAXPATHL - 1) { - *(p + plen++) = ' '; // replace NUL with space - *(p + plen) = NUL; // NUL terminate the string - } - if (bt_help(wp->w_buffer)) { - plen += snprintf(p + plen, MAXPATHL - (size_t)plen, "%s", _("[Help]")); - } - if (wp->w_p_pvw) { - plen += snprintf(p + plen, MAXPATHL - (size_t)plen, "%s", _("[Preview]")); - } - if (bufIsChanged(wp->w_buffer)) { - plen += snprintf(p + plen, MAXPATHL - (size_t)plen, "%s", "[+]"); - } - if (wp->w_buffer->b_p_ro) { - plen += snprintf(p + plen, MAXPATHL - (size_t)plen, "%s", _("[RO]")); - } - (void)plen; - - int n = (stl_width + 1) / 2; - int this_ru_col = ru_col - (Columns - stl_width); - this_ru_col = MAX(this_ru_col, n); - if (this_ru_col <= 1) { - p = "<"; // No room for file name! - plen = 1; - } else { - int i; - - // Count total number of display cells. - plen = (int)mb_string2cells(p); - - // Find first character that will fit. - // Going from start to end is much faster for DBCS. - for (i = 0; p[i] != NUL && plen >= this_ru_col - 1; - i += utfc_ptr2len(p + i)) { - plen -= utf_ptr2cells(p + i); - } - if (i > 0) { - p = p + i - 1; - *p = '<'; - plen++; - } - } - - grid_line_start(&default_grid, is_stl_global ? (Rows - (int)p_ch - 1) : W_ENDROW(wp)); - const int off = is_stl_global ? 0 : wp->w_wincol; - - int width = grid_line_puts(off, p, -1, attr); - grid_line_fill(off + width, off + this_ru_col, fillchar, attr); - - int NameBufflen = get_keymap_str(wp, "<%s>", NameBuff, MAXPATHL); - if (NameBufflen > 0 && this_ru_col - plen > NameBufflen + 1) { - grid_line_puts(off + this_ru_col - NameBufflen - 1, NameBuff, -1, attr); - } - - win_redr_ruler(wp); - - // Draw the 'showcmd' information if 'showcmdloc' == "statusline". - if (p_sc && *p_sloc == 's') { - n = this_ru_col - plen - 2; // perform the calculation here so we only do it once - const int sc_width = MIN(10, n); - - if (sc_width > 0) { - grid_line_puts(off + this_ru_col - sc_width - 1, showcmd_buf, sc_width, attr); - } - } - - grid_line_flush(); } // May need to draw the character below the vertical separator. diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 3dcc3cfea7..0fc1fa8d64 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -274,7 +274,7 @@ describe('API/win', function() ccc │ccc | {21:dd^d }│{21:ddd }| {1:~ }│{1:~ }|*2 - {3:[No Name] [+] 4,3 All }{2:[No Name] [+] 4,3 All}| + {3:< Name] [+] 4,3 All }{2: 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}", + api.nvim_get_option_value('statusline', { scope = 'global' }) + ) command('set modified') command('enew') -- global-local: not preserved in new buffer -- confirm local value was not copied - eq('', api.nvim_get_option_value('statusline', { win = 0 })) + eq( + "%<%f %{%nvim_eval_statusline('%h%w%m%r', {'maxwidth': 30}).width > 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}", + api.nvim_get_option_value('statusline', { win = 0 }) + ) eq('', eval('&l:statusline')) end) diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua index 9a1ad991f7..e616cbde6b 100644 --- a/test/functional/legacy/autocmd_option_spec.lua +++ b/test/functional/legacy/autocmd_option_spec.lua @@ -355,21 +355,55 @@ describe('au OptionSet', function() it('with string global-local (to window) option', function() local oldval = eval('&statusline') + local default_statusline = + "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}" command('set statusline=foo') - expected_combination({ 'statusline', oldval, oldval, '', 'foo', 'global', 'set' }) + expected_combination({ + 'statusline', + oldval, + oldval, + oldval, + 'foo', + 'global', + 'set', + }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('set statusline&') - expected_combination({ 'statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set' }) + expected_combination({ + 'statusline', + 'foo', + 'foo', + 'foo', + default_statusline, + 'global', + 'set', + }) command('setglobal statusline=bar') - expected_combination({ 'statusline', oldval, '', oldval, 'bar', 'global', 'setglobal' }) + expected_combination({ + 'statusline', + default_statusline, + '', + default_statusline, + 'bar', + 'global', + 'setglobal', + }) command('noa set statusline&') command('setlocal statusline=baz') - expected_combination({ 'statusline', oldval, oldval, '', 'baz', 'local', 'setlocal' }) + expected_combination({ + 'statusline', + default_statusline, + default_statusline, + '', + 'baz', + 'local', + 'setlocal', + }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. diff --git a/test/functional/legacy/scroll_opt_spec.lua b/test/functional/legacy/scroll_opt_spec.lua index a0127e306e..427a69ca01 100644 --- a/test/functional/legacy/scroll_opt_spec.lua +++ b/test/functional/legacy/scroll_opt_spec.lua @@ -1053,7 +1053,7 @@ describe('smoothscroll', function() {8: }21 22 23 24 25 26 27 28 29 | {8: 11 }|| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {8: }21 22 23 24 25 26 27 28 29 | - {2:[Quickfix List] }| + {2:[Quickfix List] [-] }| | ]]) @@ -1064,7 +1064,7 @@ describe('smoothscroll', function() {3:[No Name] }| {8: 1 } | {1:~ }|*4 - {2:[Quickfix List] }| + {2:[Quickfix List] [-] }| :call setqflist([], 'r') | ]] screen:expect(screen_empty) @@ -1079,7 +1079,7 @@ describe('smoothscroll', function() {8: }21 22 23 24 25 26 27 28 29 | {8: 3 }|| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {8: }21 22 23 24 25 26 27 28 29 | - {2:[Quickfix List] }| + {2:[Quickfix List] [-] }| :call setqflist(g:l, 'r') | ]] screen:expect(screen_l_top) @@ -1094,7 +1094,7 @@ describe('smoothscroll', function() {8: }{10: 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 5}| {8: }{10:8 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 }| {8: }{10:77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95}| - {2:[Quickfix List] }| + {2:[Quickfix List] [-] }| :call setqflist(g:l1, 'r') | ]] screen:expect(screen_l1_top) @@ -1109,7 +1109,7 @@ describe('smoothscroll', function() {8: }{10: 965 966 967 968 969 970 971 972 973 974 975 976 977 978}| {8: }{10: 979 980 981 982 983 984 985 986 987 988 989 990 991 992}| {8: }{10: 993 994 995 996 997 998 999 }| - {2:[Quickfix List] }| + {2:[Quickfix List] [-] }| :call setqflist(g:l1, 'r') | ]] screen:expect(screen_l1_bot) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index c31ce3c678..dbddd76c99 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -4011,9 +4011,9 @@ stack traceback: ]] screen:expect [[ 19 | - {2:[No Name] [+] 20,1 3%}| + {2:< Name] [+] 20,1 3%}| ^19 | - {3:[No Name] [+] 20,1 3%}| + {3:< Name] [+] 20,1 3%}| | ]] exec_lua [[ @@ -4022,9 +4022,9 @@ stack traceback: ]] screen:expect [[ 99 | - {2:[No Name] [+] 100,1 19%}| + {2:< Name] [+] 100,1 19%}| ^19 | - {3:[No Name] [+] 20,1 3%}| + {3:< Name] [+] 20,1 3%}| | ]] end) diff --git a/test/functional/lua/with_spec.lua b/test/functional/lua/with_spec.lua index 92e798e7f3..98c623a07a 100644 --- a/test/functional/lua/with_spec.lua +++ b/test/functional/lua/with_spec.lua @@ -1189,9 +1189,9 @@ describe('vim._with', function() ]] screen:expect [[ 19 | - {1:[No Name] [+] 20,1 3%}| + {1:< Name] [+] 20,1 3%}| ^19 | - {2:[No Name] [+] 20,1 3%}| + {2:< Name] [+] 20,1 3%}| | ]] exec_lua [[ @@ -1200,9 +1200,9 @@ describe('vim._with', function() ]] screen:expect [[ 99 | - {1:[No Name] [+] 100,1 19%}| + {1:< Name] [+] 100,1 19%}| ^19 | - {2:[No Name] [+] 20,1 3%}| + {2:< Name] [+] 20,1 3%}| | ]] end) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 1b14edce1e..8e4f20c893 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -396,7 +396,7 @@ describe(':checkhealth window', function() top and [[ [4:--------------------------------------------------]|*12 - health:// | + health:// [-] | [2:--------------------------------------------------]|*11]] or ([[ [2:--------------------------------------------------]|*11 diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 93e55bb103..a003d7d6e6 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -172,7 +172,7 @@ describe(':terminal cursor', function() {4:~ }| {5:floob }| |*2 - {18:[Scratch] }| + {18:[Scratch] [-] }| | ]]) @@ -183,7 +183,7 @@ describe(':terminal cursor', function() {1:floob }| ^ | | - {17:[Scratch] }| + {17:[Scratch] [-] }| {3:-- TERMINAL --} | ]]) end) @@ -437,7 +437,7 @@ describe(':terminal cursor', function() screen:expect([[ ^ │ | │ |*4 - {17:[Scratch] }{18:[Scratch] }| + {17:[Scratch] [-] }{18:[Scratch] [-] }| {3:-- TERMINAL --} | ]]) eq('block', screen._mode_info[terminal_mode_idx].cursor_shape) @@ -463,7 +463,7 @@ describe(':terminal cursor', function() screen:expect([[ │^ | │ |*4 - {18:[Scratch] }{17:[Scratch] }| + {18:[Scratch] [-] }{17:[Scratch] [-] }| {3:-- TERMINAL --} | ]]) eq('horizontal', screen._mode_info[terminal_mode_idx].cursor_shape) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 37085a4e43..b608ff4778 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -2271,6 +2271,8 @@ describe('TUI', function() '--cmd', 'set notermguicolors', '--cmd', + nvim_set, + '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile', }, { term = true, @@ -2284,10 +2286,9 @@ describe('TUI', function() ]]) screen:expect([[ ^ │ | - {2:~ }│{4:~ }|*5 - {2:~ }│{5:[No Name] 0,0-1 All}| + {2:~ }│{4:~ }|*6 {2:~ }│ | - {5:new }{6:{MATCH:<.*[/\]nvim }}| + {5:new }{6:{MATCH:<.*[/\]nvim} [-] }| | ]]) end) @@ -2519,7 +2520,7 @@ describe('TUI', function() grid = [[ ^aaaaaaaaaaaa | aaaaaaaaaaaa |*3 - < [+] 1,1 | + < All | | -- TERMINAL -- | ]], diff --git a/test/functional/testnvim.lua b/test/functional/testnvim.lua index 44426fb991..ad7587b431 100644 --- a/test/functional/testnvim.lua +++ b/test/functional/testnvim.lua @@ -24,6 +24,7 @@ M.nvim_set = ( 'set shortmess+=IS background=light noswapfile noautoindent startofline' .. ' laststatus=1 undodir=. directory=. viewdir=. backupdir=.' .. ' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid' + .. [[ statusline=%<%f\ %{%nvim_eval_statusline('%h%w%m%r',\ {'maxwidth':\ 30}).width\ >\ 0\ ?\ '%h%w%m%r\ '\ :\ ''%}%=%{%\ &showcmdloc\ ==\ 'statusline'\ ?\ '%-10.S\ '\ :\ ''\ %}%{%\ exists('b:keymap_name')\ ?\ '<'..b:keymap_name..'>\ '\ :\ ''\ %}%{%\ &ruler\ ?\ (\ &rulerformat\ ==\ ''\ ?\ '%-14.(%l,%c%V%)\ %P'\ :\ &rulerformat\ )\ :\ ''\ %}]] ) M.nvim_argv = { M.nvim_prog, diff --git a/test/functional/ui/linematch_spec.lua b/test/functional/ui/linematch_spec.lua index dc16036f21..1b93bf23cc 100644 --- a/test/functional/ui/linematch_spec.lua +++ b/test/functional/ui/linematch_spec.lua @@ -114,7 +114,7 @@ describe('Diff mode screen with 3 diffs open', function() {7: }{8: 5 }{4: }{27:BBB}{4: }│{7: }{8: 7 }{4: }{27:BBB}{4: }│{7: }{8: 5 }{4: }{27:AAA}{4: }| {7: }{8: }{23:---------------------------}│{7: }{8: 8 }{22:>>>>>>> branch1 }│{7: }{8: }{23:---------------------------}| {1:~ }│{1:~ }│{1:~ }|*6 - {2:>>>>>> branch1 }│{7: }{8: 10 }{4:>>>>>>> branch1 }| {1:~ }│{1:~ }│{1:~ }|*3 - {2:>>>>>> branch1 }│{7: }{8: }{23:---------------------------}| {1:~ }│{1:~ }│{1:~ }|*3 - {2:>>>>>> branch1 }│{7: }{8: 10 }{4:>>>>>>> branch1 }| {1:~ }│{1:~ }│{1:~ }|*3 - {2:💻 }| | - ]], + ]], } end) diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua index 4f6d691dbd..218a6a02b1 100644 --- a/test/functional/ui/multigrid_spec.lua +++ b/test/functional/ui/multigrid_spec.lua @@ -282,7 +282,7 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 [4:----------]│[2:------------------------------------------]|*12 - {11:') @@ -767,3 +767,36 @@ describe('statusline', function() ]]) end) end) + +describe('default statusline', function() + local screen + + before_each(function() + clear() + screen = Screen.new(60, 16) + screen:add_extra_attr_ids { + [100] = { foreground = Screen.colors.Magenta1, bold = true }, + } + command('set laststatus=2') + command('set ruler') + end) + + it('setting statusline to empty string sets default statusline', function() + exec_lua("vim.o.statusline = 'asdf'") + eq('asdf', eval('&statusline')) + + local default_statusline = + "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}" + + exec_lua("vim.o.statusline = ''") + + eq(default_statusline, eval('&statusline')) + + screen:expect([[ + ^ | + {1:~ }|*13 + {3:[No Name] 0,0-1 All}| + | + ]]) + end) +end)