mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(statusline): overwriting stl_items with nvim_eval_statusline() {-item #32265
Problem:
When an evaluation {-item calls `nvim_eval_statusline()`, that nested
call may overwrite the same memory used for `stl_items`.
Solution:
Make `curitem` static and use it to compute an offset to avoid
overwriting `stl_items` in nested calls to `build_stl_str_hl()`. Move
miscellaneous statusline tests into `describe()` block.
			
			
This commit is contained in:
		| @@ -927,6 +927,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op | ||||
|   static stl_hlrec_t *stl_hltab = NULL; | ||||
|   static StlClickRecord *stl_tabtab = NULL; | ||||
|   static int *stl_separator_locations = NULL; | ||||
|   static int curitem = 0; | ||||
|  | ||||
| #define TMPLEN 70 | ||||
|   char buf_tmp[TMPLEN]; | ||||
| @@ -1013,7 +1014,11 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op | ||||
|   int groupdepth = 0; | ||||
|   int evaldepth = 0; | ||||
|  | ||||
|   int curitem = 0; | ||||
|   // nvim_eval_statusline() can be called from inside a {-expression item so | ||||
|   // this may be a recursive call. Keep track of the start index into "stl_items". | ||||
|   // During post-processing only treat items filled in a certain recursion level. | ||||
|   int evalstart = curitem; | ||||
|  | ||||
|   bool prevchar_isflag = true; | ||||
|   bool prevchar_isitem = false; | ||||
|  | ||||
| @@ -1949,7 +1954,9 @@ stcsign: | ||||
|   } | ||||
|  | ||||
|   *out_p = NUL; | ||||
|   int itemcnt = curitem; | ||||
|   // Subtract offset from `itemcnt` and restore `curitem` to previous recursion level. | ||||
|   int itemcnt = curitem - evalstart; | ||||
|   curitem = evalstart; | ||||
|  | ||||
|   // Free the format buffer if we allocated it internally | ||||
|   if (usefmt != fmt) { | ||||
| @@ -1975,7 +1982,7 @@ stcsign: | ||||
|       trunc_p = stl_items[0].start; | ||||
|       item_idx = 0; | ||||
|  | ||||
|       for (int i = 0; i < itemcnt; i++) { | ||||
|       for (int i = evalstart; i < itemcnt + evalstart; i++) { | ||||
|         if (stl_items[i].type == Trunc) { | ||||
|           // Truncate at %< stl_items. | ||||
|           trunc_p = stl_items[i].start; | ||||
| @@ -2005,9 +2012,9 @@ stcsign: | ||||
|  | ||||
|       // Ignore any items in the statusline that occur after | ||||
|       // the truncation point | ||||
|       for (int i = 0; i < itemcnt; i++) { | ||||
|       for (int i = evalstart; i < itemcnt + evalstart; i++) { | ||||
|         if (stl_items[i].start > trunc_p) { | ||||
|           for (int j = i; j < itemcnt; j++) { | ||||
|           for (int j = i; j < itemcnt + evalstart; j++) { | ||||
|             if (stl_items[j].type == ClickFunc) { | ||||
|               XFREE_CLEAR(stl_items[j].cmd); | ||||
|             } | ||||
| @@ -2046,7 +2053,7 @@ stcsign: | ||||
|       //       the truncation marker `<` is not counted. | ||||
|       int item_offset = trunc_len - 1; | ||||
|  | ||||
|       for (int i = item_idx; i < itemcnt; i++) { | ||||
|       for (int i = item_idx; i < itemcnt + evalstart; i++) { | ||||
|         // Items starting at or after the end of the truncated section need | ||||
|         // to be moved backwards. | ||||
|         if (stl_items[i].start >= trunc_end_p) { | ||||
| @@ -2079,7 +2086,7 @@ stcsign: | ||||
|     // Find how many separators there are, which we will use when | ||||
|     // figuring out how many groups there are. | ||||
|     int num_separators = 0; | ||||
|     for (int i = 0; i < itemcnt; i++) { | ||||
|     for (int i = evalstart; i < itemcnt + evalstart; i++) { | ||||
|       if (stl_items[i].type == Separate) { | ||||
|         // Create an array of the start location for each separator mark. | ||||
|         stl_separator_locations[num_separators] = i; | ||||
| @@ -2104,7 +2111,7 @@ stcsign: | ||||
|         } | ||||
|  | ||||
|         for (int item_idx = stl_separator_locations[l] + 1; | ||||
|              item_idx < itemcnt; | ||||
|              item_idx < itemcnt + evalstart; | ||||
|              item_idx++) { | ||||
|           stl_items[item_idx].start += dislocation; | ||||
|         } | ||||
| @@ -2118,7 +2125,7 @@ stcsign: | ||||
|   if (hltab != NULL) { | ||||
|     *hltab = stl_hltab; | ||||
|     stl_hlrec_t *sp = stl_hltab; | ||||
|     for (int l = 0; l < itemcnt; l++) { | ||||
|     for (int l = evalstart; l < itemcnt + evalstart; l++) { | ||||
|       if (stl_items[l].type == Highlight | ||||
|           || stl_items[l].type == HighlightFold || stl_items[l].type == HighlightSign) { | ||||
|         sp->start = stl_items[l].start; | ||||
| @@ -2139,7 +2146,7 @@ stcsign: | ||||
|   if (tabtab != NULL) { | ||||
|     *tabtab = stl_tabtab; | ||||
|     StlClickRecord *cur_tab_rec = stl_tabtab; | ||||
|     for (int l = 0; l < itemcnt; l++) { | ||||
|     for (int l = evalstart; l < itemcnt + evalstart; l++) { | ||||
|       if (stl_items[l].type == TabPage) { | ||||
|         cur_tab_rec->start = stl_items[l].start; | ||||
|         if (stl_items[l].minwid == 0) { | ||||
|   | ||||
| @@ -507,268 +507,263 @@ describe('global statusline', function() | ||||
|   end) | ||||
| end) | ||||
|  | ||||
| it('statusline does not crash if it has Arabic characters #19447', function() | ||||
|   clear() | ||||
|   api.nvim_set_option_value('statusline', 'غً', {}) | ||||
|   api.nvim_set_option_value('laststatus', 2, {}) | ||||
|   command('redraw!') | ||||
|   assert_alive() | ||||
| end) | ||||
|  | ||||
| it('statusline is redrawn with :resize from <Cmd> mapping #19629', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(40, 8) | ||||
|   exec([[ | ||||
|     set laststatus=2 | ||||
|     nnoremap <Up> <cmd>resize -1<CR> | ||||
|     nnoremap <Down> <cmd>resize +1<CR> | ||||
|   ]]) | ||||
|   feed('<Up>') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }|*4 | ||||
|     {3:[No Name]                               }| | ||||
|                                             |*2 | ||||
|   ]]) | ||||
|   feed('<Down>') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }|*5 | ||||
|     {3:[No Name]                               }| | ||||
|                                             | | ||||
|   ]]) | ||||
| end) | ||||
|  | ||||
| it('showcmdloc=statusline does not show if statusline is too narrow', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(40, 8) | ||||
|   command('set showcmd') | ||||
|   command('set showcmdloc=statusline') | ||||
|   command('1vsplit') | ||||
|   screen:expect([[ | ||||
|     ^ │                                      | | ||||
|     {1:~}│{1:~                                     }|*5 | ||||
|     {3:< }{2:[No Name]                             }| | ||||
|                                             | | ||||
|   ]]) | ||||
|   feed('1234') | ||||
|   screen:expect_unchanged() | ||||
| end) | ||||
|  | ||||
| it('K_EVENT does not trigger a statusline redraw unnecessarily', function() | ||||
|   clear() | ||||
|   local _ = Screen.new(40, 8) | ||||
|   -- does not redraw on vim.schedule (#17937) | ||||
|   command([[ | ||||
|     set laststatus=2 | ||||
|     let g:counter = 0 | ||||
|     func Status() | ||||
|       let g:counter += 1 | ||||
|       lua vim.schedule(function() end) | ||||
|       return g:counter | ||||
|     endfunc | ||||
|     set statusline=%!Status() | ||||
|   ]]) | ||||
|   sleep(50) | ||||
|   eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
|   -- also in insert mode | ||||
|   feed('i') | ||||
|   sleep(50) | ||||
|   eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
|   -- does not redraw on timer call (#14303) | ||||
|   command([[ | ||||
|     let g:counter = 0 | ||||
|     func Timer(timer) | ||||
|     endfunc | ||||
|     call timer_start(1, 'Timer', {'repeat': 100}) | ||||
|   ]]) | ||||
|   sleep(50) | ||||
|   eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
| end) | ||||
|  | ||||
| it('statusline is redrawn on various state changes', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(40, 4) | ||||
|  | ||||
|   -- recording state change #22683 | ||||
|   command('set ls=2 stl=%{repeat(reg_recording(),5)}') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:                                        }| | ||||
|                                             | | ||||
|   ]]) | ||||
|   feed('qQ') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:QQQQQ                                   }| | ||||
|     {5:recording @Q}                            | | ||||
|   ]]) | ||||
|   feed('q') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:                                        }| | ||||
|                                             | | ||||
|   ]]) | ||||
|  | ||||
|   -- Visual mode change #23932 | ||||
|   command('set ls=2 stl=%{mode(1)}') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:n                                       }| | ||||
|                                             | | ||||
|   ]]) | ||||
|   feed('v') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:v                                       }| | ||||
|     {5:-- VISUAL --}                            | | ||||
|   ]]) | ||||
|   feed('V') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:V                                       }| | ||||
|     {5:-- VISUAL LINE --}                       | | ||||
|   ]]) | ||||
|   feed('<C-V>') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:^V                                      }| | ||||
|     {5:-- VISUAL BLOCK --}                      | | ||||
|   ]]) | ||||
|   feed('<Esc>') | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|     {1:~                                       }| | ||||
|     {3:n                                       }| | ||||
|                                             | | ||||
|   ]]) | ||||
| end) | ||||
|  | ||||
| it('ruler is redrawn in cmdline with redrawstatus #22804', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(40, 2) | ||||
|   command([[ | ||||
|     let g:n = 'initial value' | ||||
|     set ls=1 ru ruf=%{g:n} | ||||
|     redraw | ||||
|     let g:n = 'other value' | ||||
|     redrawstatus | ||||
|   ]]) | ||||
|   screen:expect([[ | ||||
|     ^                                        | | ||||
|                           other value       | | ||||
|   ]]) | ||||
| end) | ||||
|  | ||||
| it('shows correct ruler in cmdline with no statusline', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(30, 8) | ||||
|   -- Use long ruler to check 'ruler' with 'rulerformat' set has correct width. | ||||
|   command [[ | ||||
|     set ruler rulerformat=%{winnr()}longlonglong ls=0 winwidth=10 | ||||
|     split | ||||
|     wincmd b | ||||
|     vsplit | ||||
|     wincmd t | ||||
|     wincmd | | ||||
|     mode | ||||
|   ]] | ||||
|   -- Window 1 is current. It has a statusline, so cmdline should show the | ||||
|   -- last window's ruler, which has no statusline. | ||||
|   command '1wincmd w' | ||||
|   screen:expect [[ | ||||
|     ^                              | | ||||
|     {1:~                             }|*2 | ||||
|     {3:[No Name]      1longlonglong  }| | ||||
|                    │              | | ||||
|     {1:~              }│{1:~             }|*2 | ||||
|                    3longlonglong  | | ||||
|   ]] | ||||
|   -- Window 2 is current. It has no statusline, so cmdline should show its | ||||
|   -- ruler instead. | ||||
|   command '2wincmd w' | ||||
|   screen:expect [[ | ||||
|                                   | | ||||
|     {1:~                             }|*2 | ||||
|     {2:[No Name]      1longlonglong  }| | ||||
|     ^               │              | | ||||
|     {1:~              }│{1:~             }|*2 | ||||
|                    2longlonglong  | | ||||
|   ]] | ||||
|   -- Window 3 is current. Cmdline should again show its ruler. | ||||
|   command '3wincmd w' | ||||
|   screen:expect [[ | ||||
|                                   | | ||||
|     {1:~                             }|*2 | ||||
|     {2:[No Name]      1longlonglong  }| | ||||
|                    │^              | | ||||
|     {1:~              }│{1:~             }|*2 | ||||
|                    3longlonglong  | | ||||
|   ]] | ||||
| end) | ||||
|  | ||||
| it('uses "stl" and "stlnc" fillchars even if they are the same #19803', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(53, 4) | ||||
|   command('hi clear StatusLine') | ||||
|   command('hi clear StatusLineNC') | ||||
|   command('vsplit') | ||||
|   screen:expect { | ||||
|     grid = [[ | ||||
|     ^                          │                          | | ||||
|     {1:~                         }│{1:~                         }| | ||||
|     [No Name]                  [No Name]                 | | ||||
|                                                          | | ||||
|   ]], | ||||
|   } | ||||
| end) | ||||
|  | ||||
| it('showcmdloc=statusline works with vertical splits', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(53, 4) | ||||
|   command('rightbelow vsplit') | ||||
|   command('set showcmd showcmdloc=statusline') | ||||
|   feed('1234') | ||||
|   screen:expect([[ | ||||
|                               │^                          | | ||||
|     {1:~                         }│{1:~                         }| | ||||
|     {2:[No Name]                  }{3:[No Name]      1234       }| | ||||
|                                                          | | ||||
|   ]]) | ||||
|   feed('<Esc>') | ||||
|   command('set laststatus=3') | ||||
|   feed('1234') | ||||
|   screen:expect([[ | ||||
|                               │^                          | | ||||
|     {1:~                         }│{1:~                         }| | ||||
|     {3:[No Name]                                 1234       }| | ||||
|                                                          | | ||||
|   ]]) | ||||
| end) | ||||
|  | ||||
| it('keymap is shown with vertical splits #27269', function() | ||||
|   clear() | ||||
|   local screen = Screen.new(53, 4) | ||||
|   command('setlocal keymap=dvorak') | ||||
|   command('rightbelow vsplit') | ||||
|   screen:expect([[ | ||||
|                               │^                          | | ||||
|     {1:~                         }│{1:~                         }| | ||||
|     {2:[No Name]         <en-dv>  }{3:[No Name]         <en-dv> }| | ||||
|                                                          | | ||||
|   ]]) | ||||
|   command('set laststatus=3') | ||||
|   screen:expect([[ | ||||
|                               │^                          | | ||||
|     {1:~                         }│{1:~                         }| | ||||
|     {3:[No Name]                                    <en-dv> }| | ||||
|                                                          | | ||||
|   ]]) | ||||
| describe('statusline', function() | ||||
|   local screen | ||||
|   before_each(function() | ||||
|     clear() | ||||
|     screen = Screen.new(40, 8) | ||||
|     screen:add_extra_attr_ids { | ||||
|       [100] = { bold = true, reverse = true, foreground = Screen.colors.Blue }, | ||||
|       [101] = { reverse = true, bold = true, foreground = Screen.colors.SlateBlue }, | ||||
|     } | ||||
|   end) | ||||
|  | ||||
|   it('does not crash if it has Arabic characters #19447', function() | ||||
|     api.nvim_set_option_value('statusline', 'غً', {}) | ||||
|     api.nvim_set_option_value('laststatus', 2, {}) | ||||
|     command('redraw!') | ||||
|     assert_alive() | ||||
|   end) | ||||
|  | ||||
|   it('is redrawn with :resize from <Cmd> mapping #19629', function() | ||||
|     exec([[ | ||||
|       set laststatus=2 | ||||
|       nnoremap <Up> <cmd>resize -1<CR> | ||||
|       nnoremap <Down> <cmd>resize +1<CR> | ||||
|     ]]) | ||||
|     feed('<Up>') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*4 | ||||
|       {3:[No Name]                               }| | ||||
|                                               |*2 | ||||
|     ]]) | ||||
|     feed('<Down>') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:[No Name]                               }| | ||||
|                                               | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('does not contain showmcd with showcmdloc=statusline when too narrow', function() | ||||
|     command('set showcmd') | ||||
|     command('set showcmdloc=statusline') | ||||
|     command('1vsplit') | ||||
|     screen:expect([[ | ||||
|       ^ │                                      | | ||||
|       {1:~}│{1:~                                     }|*5 | ||||
|       {3:< }{2:[No Name]                             }| | ||||
|                                               | | ||||
|     ]]) | ||||
|     feed('1234') | ||||
|     screen:expect_unchanged() | ||||
|   end) | ||||
|  | ||||
|   it('does not redraw unnecessarily after K_EVENT', function() | ||||
|     -- does not redraw on vim.schedule (#17937) | ||||
|     command([[ | ||||
|       set laststatus=2 | ||||
|       let g:counter = 0 | ||||
|       func Status() | ||||
|         let g:counter += 1 | ||||
|         lua vim.schedule(function() end) | ||||
|         return g:counter | ||||
|       endfunc | ||||
|       set statusline=%!Status() | ||||
|     ]]) | ||||
|     sleep(50) | ||||
|     eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
|     -- also in insert mode | ||||
|     feed('i') | ||||
|     sleep(50) | ||||
|     eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
|     -- does not redraw on timer call (#14303) | ||||
|     command([[ | ||||
|       let g:counter = 0 | ||||
|       func Timer(timer) | ||||
|       endfunc | ||||
|       call timer_start(1, 'Timer', {'repeat': 100}) | ||||
|     ]]) | ||||
|     sleep(50) | ||||
|     eq(1, eval('g:counter < 50'), 'g:counter=' .. eval('g:counter')) | ||||
|   end) | ||||
|  | ||||
|   it('is redrawn on various state changes', function() | ||||
|     -- recording state change #22683 | ||||
|     command('set ls=2 stl=%{repeat(reg_recording(),5)}') | ||||
|     local s1 = [[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:                                        }| | ||||
|                                               | | ||||
|     ]] | ||||
|     screen:expect(s1) | ||||
|     feed('qQ') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:QQQQQ                                   }| | ||||
|       {5:recording @Q}                            | | ||||
|     ]]) | ||||
|     feed('q') | ||||
|     screen:expect(s1) | ||||
|  | ||||
|     -- Visual mode change #23932 | ||||
|     command('set ls=2 stl=%{mode(1)}') | ||||
|     local s2 = [[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:n                                       }| | ||||
|                                               | | ||||
|     ]] | ||||
|     screen:expect(s2) | ||||
|     feed('v') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:v                                       }| | ||||
|       {5:-- VISUAL --}                            | | ||||
|     ]]) | ||||
|     feed('V') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:V                                       }| | ||||
|       {5:-- VISUAL LINE --}                       | | ||||
|     ]]) | ||||
|     feed('<C-V>') | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {3:^V                                      }| | ||||
|       {5:-- VISUAL BLOCK --}                      | | ||||
|     ]]) | ||||
|     feed('<Esc>') | ||||
|     screen:expect(s2) | ||||
|   end) | ||||
|  | ||||
|   it('ruler is redrawn in cmdline with redrawstatus #22804', function() | ||||
|     command([[ | ||||
|       let g:n = 'initial value' | ||||
|       set ls=1 ru ruf=%{g:n} | ||||
|       redraw | ||||
|       let g:n = 'other value' | ||||
|       redrawstatus | ||||
|     ]]) | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*6 | ||||
|                             other value       | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('hidden moves ruler to cmdline', function() | ||||
|     -- Use long ruler to check 'ruler' with 'rulerformat' set has correct width. | ||||
|     command [[ | ||||
|       set ruler rulerformat=%{winnr()}longlonglong ls=0 winwidth=10 | ||||
|       split | ||||
|       wincmd b | ||||
|       vsplit | ||||
|       wincmd t | ||||
|       wincmd | | ||||
|       mode | ||||
|     ]] | ||||
|     -- Window 1 is current. It has a statusline, so cmdline should show the | ||||
|     -- last window's ruler, which has no statusline. | ||||
|     command '1wincmd w' | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*2 | ||||
|       {3:[No Name]             1longlonglong     }| | ||||
|                           │                   | | ||||
|       {1:~                   }│{1:~                  }|*2 | ||||
|                             3longlonglong     | | ||||
|     ]]) | ||||
|     -- Window 2 is current. It has no statusline, so cmdline should show its | ||||
|     -- ruler instead. | ||||
|     command '2wincmd w' | ||||
|     screen:expect([[ | ||||
|                                               | | ||||
|       {1:~                                       }|*2 | ||||
|       {2:[No Name]             1longlonglong     }| | ||||
|       ^                    │                   | | ||||
|       {1:~                   }│{1:~                  }|*2 | ||||
|                             2longlonglong     | | ||||
|     ]]) | ||||
|     -- Window 3 is current. Cmdline should again show its ruler. | ||||
|     command '3wincmd w' | ||||
|     screen:expect([[ | ||||
|                                               | | ||||
|       {1:~                                       }|*2 | ||||
|       {2:[No Name]             1longlonglong     }| | ||||
|                           │^                   | | ||||
|       {1:~                   }│{1:~                  }|*2 | ||||
|                             3longlonglong     | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('uses "stl" and "stlnc" fillchars even if they are the same #19803', function() | ||||
|     command('hi clear StatusLine') | ||||
|     command('hi clear StatusLineNC') | ||||
|     command('vsplit') | ||||
|     screen:expect([[ | ||||
|       ^                    │                   | | ||||
|       {1:~                   }│{1:~                  }|*5 | ||||
|       [No Name]            [No Name]          | | ||||
|                                               | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('showcmdloc=statusline works with vertical splits', function() | ||||
|     command('rightbelow vsplit') | ||||
|     command('set showcmd showcmdloc=statusline') | ||||
|     feed('1234') | ||||
|     screen:expect([[ | ||||
|                          │^                    | | ||||
|       {1:~                  }│{1:~                   }|*5 | ||||
|       {2:[No Name]           }{3:[No Name] 1234      }| | ||||
|                                               | | ||||
|     ]]) | ||||
|     feed('<Esc>') | ||||
|     command('set laststatus=3') | ||||
|     feed('1234') | ||||
|     screen:expect([[ | ||||
|                          │^                    | | ||||
|       {1:~                  }│{1:~                   }|*5 | ||||
|       {3:[No Name]                    1234       }| | ||||
|                                               | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('keymap is shown with vertical splits #27269', function() | ||||
|     command('setlocal keymap=dvorak') | ||||
|     command('rightbelow vsplit') | ||||
|     screen:expect([[ | ||||
|                          │^                    | | ||||
|       {1:~                  }│{1:~                   }|*5 | ||||
|       {2:[No Name]  <en-dv>  }{3:[No Name]   <en-dv> }| | ||||
|                                               | | ||||
|     ]]) | ||||
|  | ||||
|     command('set laststatus=3') | ||||
|     screen:expect([[ | ||||
|                          │^                    | | ||||
|       {1:~                  }│{1:~                   }|*5 | ||||
|       {3:[No Name]                       <en-dv> }| | ||||
|                                               | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it("nested call from nvim_eval_statusline() doesn't overwrite items #32259", function() | ||||
|     exec_lua('vim.o.laststatus = 2') | ||||
|     exec_lua([[vim.o.statusline = '%#Special#B:%{nvim_eval_statusline("%f", []).str}']]) | ||||
|     screen:expect([[ | ||||
|       ^                                        | | ||||
|       {1:~                                       }|*5 | ||||
|       {101:B:[No Name]                             }| | ||||
|                                               | | ||||
|     ]]) | ||||
|   end) | ||||
| end) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 luukvbaal
					luukvbaal