mirror of
https://github.com/neovim/neovim.git
synced 2026-08-14 03:04:54 +00:00
Problem: Traditionally, the ruler in the last line is one cell shorter than in the statusline, leaving the last cell of the screen blank. According to code comments, this is in order to prevent unwanted scrolling on "some" (unspecified, but presumably ancient) terminals. Berkeley vi is more specific in its `vs_modeline` function: dumb terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses. (n)curses still has a similar limitation in `(w)addstr`, but apparently only for historical reasons. Maintaining the different widths leads to awkward inconsistencies when the ruler is configured with 'rulerformat', except for the special case where it contains a top-level `%=`. Shifting the ruler in the last line to the left would be a solution, but the empty cell at the end doesn't seem to be relevant anymore. Solution: extend the ruler in the last line all the way to the right edge of the screen, just like in the statusline. The exact same amount of place will be available to the rest of the UI as before. BREAKING CHANGE: - the default ruler width is now 18 cells - the last cell of the screen is no longer empty Closes #41076
435 lines
18 KiB
Lua
435 lines
18 KiB
Lua
local t = require('test.testutil')
|
||
local n = require('test.functional.testnvim')()
|
||
local Screen = require('test.functional.ui.screen')
|
||
|
||
local describe, it, before_each = t.describe, t.it, t.before_each
|
||
local clear = n.clear
|
||
local eq = t.eq
|
||
local exec = n.exec
|
||
local exec_lua = n.exec_lua
|
||
local command = n.command
|
||
local feed = n.feed
|
||
local fn = n.fn
|
||
|
||
-- oldtest: Test_window_cmd_ls0_split_scrolling()
|
||
it('scrolling with laststatus=0 and :botright split', function()
|
||
clear('--cmd', 'set ruler')
|
||
local screen = Screen.new(40, 10)
|
||
exec([[
|
||
set laststatus=0
|
||
call setline(1, range(1, 100))
|
||
normal! G
|
||
]])
|
||
command('botright split')
|
||
screen:expect([[
|
||
97 |
|
||
98 |
|
||
99 |
|
||
100 |
|
||
{2:[No Name] [+] 100,1 Bot}|
|
||
97 |
|
||
98 |
|
||
99 |
|
||
^100 |
|
||
100,1 Bot|
|
||
]])
|
||
end)
|
||
|
||
describe('splitkeep', function()
|
||
local screen
|
||
|
||
before_each(function()
|
||
clear('--cmd', 'set splitkeep=screen')
|
||
screen = Screen.new()
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_cursor()
|
||
it('does not adjust cursor in window that did not change size', function()
|
||
screen:try_resize(75, 8)
|
||
-- FIXME: bottom window is different without the "vsplit | close"
|
||
exec([[
|
||
vsplit | close
|
||
set scrolloff=5
|
||
set splitkeep=screen
|
||
autocmd CursorMoved * wincmd p | wincmd p
|
||
call setline(1, range(1, 200))
|
||
func CursorEqualize()
|
||
call cursor(100, 1)
|
||
wincmd =
|
||
endfunc
|
||
wincmd s
|
||
call CursorEqualize()
|
||
]])
|
||
|
||
screen:expect([[
|
||
99 |
|
||
^100 |
|
||
101 |
|
||
{3:[No Name] [+] }|
|
||
5 |
|
||
6 |
|
||
{2:[No Name] [+] }|
|
||
|
|
||
]])
|
||
|
||
feed('j')
|
||
screen:expect([[
|
||
100 |
|
||
^101 |
|
||
102 |
|
||
{3:[No Name] [+] }|
|
||
5 |
|
||
6 |
|
||
{2:[No Name] [+] }|
|
||
|
|
||
]])
|
||
|
||
command('set scrolloff=0')
|
||
feed('G')
|
||
screen:expect([[
|
||
198 |
|
||
199 |
|
||
^200 |
|
||
{3:[No Name] [+] }|
|
||
5 |
|
||
6 |
|
||
{2:[No Name] [+] }|
|
||
|
|
||
]])
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_callback()
|
||
it('does not scroll when split in callback', function()
|
||
exec([[
|
||
call setline(1, range(&lines))
|
||
function C1(a, b, c)
|
||
split | wincmd p
|
||
endfunction
|
||
function C2(a, b, c)
|
||
close | split
|
||
endfunction
|
||
]])
|
||
exec_lua([[
|
||
vim.api.nvim_set_keymap("n", "j", "", { callback = function()
|
||
vim.cmd("call jobstart([&sh, &shcf, 'true'], { 'on_exit': 'C1' })")
|
||
end
|
||
})]])
|
||
exec_lua([[
|
||
vim.api.nvim_set_keymap("n", "t", "", { callback = function()
|
||
vim.api.nvim_set_current_win(
|
||
vim.api.nvim_open_win(vim.api.nvim_create_buf(false, {}), false, {
|
||
width = 10,
|
||
relative = "cursor",
|
||
height = 4,
|
||
row = 0,
|
||
col = 0,
|
||
}))
|
||
vim.cmd("call jobstart([&sh, &shcf, 'true'], { 'term': v:true, 'on_exit': 'C2' })")
|
||
end
|
||
})]])
|
||
feed('j')
|
||
screen:expect([[
|
||
0 |
|
||
1 |
|
||
2 |
|
||
3 |
|
||
4 |
|
||
5 |
|
||
{2:[No Name] [+] }|
|
||
^7 |
|
||
8 |
|
||
9 |
|
||
10 |
|
||
11 |
|
||
{3:[No Name] [+] }|
|
||
|
|
||
]])
|
||
feed(':quit<CR>Ht')
|
||
screen:expect([[
|
||
^0 |
|
||
1 |
|
||
2 |
|
||
3 |
|
||
4 |
|
||
5 |
|
||
{3:[No Name] [+] }|
|
||
7 |
|
||
8 |
|
||
9 |
|
||
10 |
|
||
11 |
|
||
{2:[No Name] [+] }|
|
||
:quit |
|
||
]])
|
||
feed(':set sb<CR>:quit<CR>Gj')
|
||
screen:expect([[
|
||
1 |
|
||
2 |
|
||
3 |
|
||
4 |
|
||
^5 |
|
||
{3:[No Name] [+] }|
|
||
7 |
|
||
8 |
|
||
9 |
|
||
10 |
|
||
11 |
|
||
12 |
|
||
{2:[No Name] [+] }|
|
||
:quit |
|
||
]])
|
||
feed(':quit<CR>Gt')
|
||
screen:expect([[
|
||
1 |
|
||
2 |
|
||
3 |
|
||
4 |
|
||
5 |
|
||
{2:[No Name] [+] }|
|
||
7 |
|
||
8 |
|
||
9 |
|
||
10 |
|
||
11 |
|
||
^12 |
|
||
{3:[No Name] [+] }|
|
||
:quit |
|
||
]])
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_fold()
|
||
it('does not scroll when window has closed folds', function()
|
||
exec([[
|
||
set commentstring=/*%s*/
|
||
set splitkeep=screen
|
||
set foldmethod=marker
|
||
set number
|
||
let line = 1
|
||
for n in range(1, &lines)
|
||
call setline(line, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
|
||
\ 'after fold'])
|
||
let line += 8
|
||
endfor
|
||
]])
|
||
feed('L:wincmd s<CR>')
|
||
screen:expect([[
|
||
{8: 1 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 8 }after fold |
|
||
{8: 9 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 16 }after fold |
|
||
{8: 17 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 24 }^after fold |
|
||
{3:[No Name] [+] }|
|
||
{8: 32 }after fold |
|
||
{8: 33 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 40 }after fold |
|
||
{8: 41 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 48 }after fold |
|
||
{2:[No Name] [+] }|
|
||
:wincmd s |
|
||
]])
|
||
feed(':quit<CR>')
|
||
screen:expect([[
|
||
{8: 1 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 8 }after fold |
|
||
{8: 9 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 16 }after fold |
|
||
{8: 17 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 24 }after fold |
|
||
{8: 25 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 32 }after fold |
|
||
{8: 33 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 40 }after fold |
|
||
{8: 41 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 48 }after fold |
|
||
{8: 49 }{13:^+-- 7 lines: int FuncName() {···················}|
|
||
:quit |
|
||
]])
|
||
feed('H:below split<CR>')
|
||
screen:expect([[
|
||
{8: 1 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 8 }after fold |
|
||
{8: 9 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 16 }after fold |
|
||
{8: 17 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{2:[No Name] [+] }|
|
||
{8: 25 }{13:^+-- 7 lines: int FuncName() {···················}|
|
||
{8: 32 }after fold |
|
||
{8: 33 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 40 }after fold |
|
||
{8: 41 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 48 }after fold |
|
||
{3:[No Name] [+] }|
|
||
:below split |
|
||
]])
|
||
feed(':wincmd k<CR>:quit<CR>')
|
||
screen:expect([[
|
||
{8: 1 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 8 }after fold |
|
||
{8: 9 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 16 }after fold |
|
||
{8: 17 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 24 }after fold |
|
||
{8: 25 }{13:^+-- 7 lines: int FuncName() {···················}|
|
||
{8: 32 }after fold |
|
||
{8: 33 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 40 }after fold |
|
||
{8: 41 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
{8: 48 }after fold |
|
||
{8: 49 }{13:+-- 7 lines: int FuncName() {···················}|
|
||
:quit |
|
||
]])
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_status()
|
||
it('does not scroll when split in callback', function()
|
||
exec([[
|
||
call setline(1, ['a', 'b', 'c'])
|
||
set nomodified
|
||
set splitkeep=screen
|
||
let win = winnr()
|
||
wincmd s
|
||
wincmd j
|
||
]])
|
||
feed(':call win_move_statusline(win, 1)<CR>')
|
||
screen:expect([[
|
||
a |
|
||
b |
|
||
c |
|
||
{1:~ }|*4
|
||
{2:[No Name] }|
|
||
^a |
|
||
b |
|
||
c |
|
||
{1:~ }|
|
||
{3:[No Name] }|
|
||
:call win_move_statusline(win, 1) |
|
||
]])
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_skipcol()
|
||
it('skipcol is not reset unnecessarily and is copied to new window', function()
|
||
screen:try_resize(40, 12)
|
||
exec([[
|
||
set splitkeep=topline smoothscroll splitbelow scrolloff=0
|
||
call setline(1, 'with lots of text in one line '->repeat(6))
|
||
norm 2
|
||
wincmd s
|
||
]])
|
||
screen:expect([[
|
||
{1:<<<}e line with lots of text in one line |
|
||
with lots of text in one line with lots |
|
||
of text in one line |
|
||
{1:~ }|
|
||
{2:[No Name] [+] }|
|
||
{1:<<<}e line with lots of text in one line |
|
||
^with lots of text in one line with lots |
|
||
of text in one line |
|
||
{1:~ }|*2
|
||
{3:[No Name] [+] }|
|
||
|
|
||
]])
|
||
end)
|
||
|
||
-- oldtest: Test_splitkeep_line()
|
||
it("no scrolling with 'splitkeep' and line()", function()
|
||
screen:try_resize(40, 6)
|
||
exec([[
|
||
set splitkeep=screen nosplitbelow
|
||
autocmd WinResized * call line('w0', 1000)
|
||
call setline(1, range(1000))
|
||
]])
|
||
screen:expect([[
|
||
^0 |
|
||
1 |
|
||
2 |
|
||
3 |
|
||
4 |
|
||
|
|
||
]])
|
||
feed(':wincmd s<CR>')
|
||
screen:expect([[
|
||
^0 |
|
||
1 |
|
||
{3:[No Name] [+] }|
|
||
3 |
|
||
{2:[No Name] [+] }|
|
||
:wincmd s |
|
||
]])
|
||
end)
|
||
end)
|
||
|
||
-- oldtest: Test_winfixsize_vsep_statusline()
|
||
it("'winfixwidth/height' does not leave stray vseps/statuslines", function()
|
||
clear()
|
||
local screen = Screen.new(75, 8)
|
||
exec([[
|
||
set noequalalways splitbelow splitright
|
||
vsplit
|
||
setlocal winfixwidth
|
||
vsplit
|
||
]])
|
||
eq(16, fn.winwidth(1))
|
||
eq(37, fn.winwidth(2))
|
||
eq(20, fn.winwidth(3))
|
||
|
||
command('quit')
|
||
screen:expect([[
|
||
^ │ |
|
||
{1:~ }│{1:~ }|*5
|
||
{3:[No Name] }{2:[No Name] }|
|
||
|
|
||
]])
|
||
-- Checks w_view_width in Nvim; especially important as the screen test may still pass if only
|
||
-- w_width changed to make room for the vsep.
|
||
eq(36, fn.winwidth(1))
|
||
eq(38, fn.winwidth(2))
|
||
|
||
exec([[
|
||
set laststatus=0
|
||
only
|
||
split
|
||
set winfixheight
|
||
split
|
||
]])
|
||
eq(1, fn.winheight(1))
|
||
eq(3, fn.winheight(2))
|
||
eq(1, fn.winheight(3))
|
||
|
||
command('quit')
|
||
screen:expect([[
|
||
^ |
|
||
{1:~ }|
|
||
{3:[No Name] }|
|
||
|
|
||
{1:~ }|*3
|
||
|
|
||
]])
|
||
eq(2, fn.winheight(1))
|
||
eq(4, fn.winheight(2))
|
||
end)
|
||
|
||
-- oldtest: Test_resize_from_another_tabpage()
|
||
it('resizing window from another tabpage', function()
|
||
clear()
|
||
local screen = Screen.new(75, 8)
|
||
screen:add_extra_attr_ids({
|
||
[100] = { foreground = Screen.colors.Magenta1, bold = true },
|
||
})
|
||
exec([[
|
||
set laststatus=2
|
||
vnew
|
||
let w = win_getid()
|
||
tabnew
|
||
call win_execute(w, 'vertical resize 20')
|
||
tabprev
|
||
]])
|
||
screen:expect([[
|
||
{5: }{100:2}{5: [No Name] }{24: [No Name] }{2: }{24:X}|
|
||
^ │ |
|
||
{1:~ }│{1:~ }|*4
|
||
{3:[No Name] }{2:[No Name] }|
|
||
|
|
||
]])
|
||
end)
|