Files
neovim/test/functional/legacy/normal_spec.lua
Sébastien Hoffmann 259e6fa9cc fix(ruler)!: consistent width in last line and statusline
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
2026-08-04 06:36:58 +02:00

165 lines
5.0 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, finally = t.describe, t.it, t.before_each, t.finally
local clear = n.clear
local exec = n.exec
local feed = n.feed
local api = n.api
local eq = t.eq
local fn = n.fn
describe('normal', function()
local screen
before_each(function()
clear()
screen = Screen.new(40, 19)
end)
-- oldtest: Test_normal_j_below_botline()
it([[no skipped lines with "j" scrolling below botline and 'foldmethod' not "manual"]], function()
exec([[
set number foldmethod=diff scrolloff=0
call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
norm Lj
]])
screen:expect([[
{8: 2 }222222222222222222222222222222222222|
{8: }222222222222222222222222222222222222|*4
{8: }22222222222222222222 |
{8: 3 }333333333333333333333333333333333333|
{8: }333333333333333333333333333333333333|*4
{8: }33333333333333333333 |
{8: 4 }^444444444444444444444444444444444444|
{8: }444444444444444444444444444444444444|*4
{8: }44444444444444444444 |
|
]])
end)
-- oldtest: Test_single_line_scroll()
it('(Half)-page scroll up or down reveals virtual lines #19605, #27967', function()
fn.setline(1, 'foobar one two three')
exec('set smoothscroll')
local ns = api.nvim_create_namespace('')
api.nvim_buf_set_extmark(0, ns, 0, 0, {
virt_lines = { { { '---', 'IncSearch' } } },
virt_lines_above = true,
})
-- Nvim: not actually necessary to scroll down to hide the virtual line.
-- Check topfill instead of skipcol and show the screen state.
feed('<C-E>')
eq(0, fn.winsaveview().topfill)
local s1 = [[
^foobar one two three |
{1:~ }|*17
|
]]
screen:expect(s1)
feed('<C-B>')
eq(1, fn.winsaveview().topfill)
local s2 = [[
{2:---} |
^foobar one two three |
{1:~ }|*16
|
]]
screen:expect(s2)
feed('<C-E>')
eq(0, fn.winsaveview().topfill)
screen:expect(s1)
feed('<C-U>')
eq(1, fn.winsaveview().topfill)
screen:expect(s2)
-- Nvim: also test virt_lines below the last line
feed('yy100pG<C-L>')
api.nvim_buf_set_extmark(0, ns, 100, 0, { virt_lines = { { { '---', 'IncSearch' } } } })
screen:expect({
grid = [[
foobar one two three |*17
^foobar one two three |
|
]],
})
feed('<C-F>')
screen:expect({
grid = [[
^foobar one two three |
{2:---} |
{1:~ }|*16
|
]],
})
feed('ggG<C-D>')
screen:expect({
grid = [[
foobar one two three |*16
^foobar one two three |
{2:---} |
|
]],
})
end)
-- oldtest: Test_normal_gm()
it('gm sets curswant correctly', function()
screen:try_resize(75, 10)
exec([[
call setline(1, repeat([" abcd\tefgh\tij"], 10))
call cursor(1, 1)
]])
feed('jVjzf')
-- gm
feed('gmk')
eq(18, fn.virtcol('.'))
-- g0
feed('gj0k')
eq(1, fn.virtcol('.'))
-- g^
feed('jg^k')
eq(3, fn.virtcol('.'))
exec('call cursor(10, 1)')
-- gm
feed('gmk')
eq(18, fn.virtcol('.'))
-- g0
feed('gj0k')
eq(1, fn.virtcol('.'))
-- g^
feed('jg^k')
eq(3, fn.virtcol('.'))
end)
-- oldtest: Test_pos_percentage_in_turkish_locale()
it('viewport position percentage in Turkish locale', function()
t.skip(not t.translations_enabled(), 'N/A: Nvim not built with ENABLE_TRANSLATIONS')
t.skip(not pcall(exec, 'lang tr_TR.UTF-8'), 'Turkish locale not available')
local build_dir = t.paths.test_build_dir
local locale_dir = build_dir .. '/share/locale/tr/LC_MESSAGES'
fn.mkdir(locale_dir, 'p')
fn.filecopy(build_dir .. '/src/nvim/po/tr.mo', locale_dir .. '/nvim.mo')
finally(function()
n.rmdir(vim.fs.dirname(locale_dir))
end)
clear({ env = { LANG = 'tr_TR.UTF-8' } })
screen = Screen.new(40, 5)
exec('set ruler')
exec('lang tr_TR.UTF-8')
exec('put =range(1,40)')
exec('5')
screen:expect([[
3 |
^4 |
5 |
6 |
40 more lines 5,1 %8|
]])
end)
end)