local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local tt = require('test.functional.testterm')
local feed, clear = n.feed, n.clear
local testprg, command = n.testprg, n.command
local eq, eval = t.eq, n.eval
local matches = t.matches
local call = n.call
local hide_cursor = tt.hide_cursor
local show_cursor = tt.show_cursor
local is_os = t.is_os
local skip = t.skip
describe(':terminal cursor', function()
local screen
local terminal_mode_idx ---@type number
before_each(function()
clear()
screen = tt.setup_screen()
if terminal_mode_idx == nil then
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
terminal_mode_idx = i
end
end
assert(terminal_mode_idx)
end
end)
it('moves the screen cursor when focused', function()
tt.feed_data('testing cursor')
screen:expect([[
tty ready |
testing cursor^ |
|*4
{3:-- TERMINAL --} |
]])
end)
it('is highlighted when not focused', function()
feed('<c-\\><c-n>')
screen:expect([[
tty ready |
^ |
|*5
]])
end)
describe('with number column', function()
before_each(function()
feed('<c-\\><c-n>:set number<cr>')
end)
it('is positioned correctly when unfocused', function()
screen:expect([[
{7: 1 }tty ready |
{7: 2 }^rows: 6, cols: 46 |
{7: 3 } |
{7: 4 } |
{7: 5 } |
{7: 6 } |
:set number |
]])
end)
it('is positioned correctly when focused', function()
screen:expect([[
{7: 1 }tty ready |
{7: 2 }^rows: 6, cols: 46 |
{7: 3 } |
{7: 4 } |
{7: 5 } |
{7: 6 } |
:set number |
]])
feed('i')
n.poke_eventloop()
screen:expect([[
{7: 1 }tty ready |
{7: 2 }rows: 6, cols: 46 |
{7: 3 }^ |
{7: 4 } |
{7: 5 } |
{7: 6 } |
{3:-- TERMINAL --} |
]])
end)
end)
describe('when invisible', function()
it('is not highlighted', function()
skip(is_os('win'), '#31587')
hide_cursor()
screen:expect([[
tty ready |
|*5
{3:-- TERMINAL --} |
]])
show_cursor()
screen:expect([[
tty ready |
^ |
|*4
{3:-- TERMINAL --} |
]])
-- same for when the terminal is unfocused
feed('<c-\\><c-n>')
hide_cursor()
screen:expect({
grid = [[
tty ready |
^ |
|*5
]],
unchanged = true,
})
show_cursor()
screen:expect({
grid = [[
tty ready |
^ |
|*5
]],
unchanged = true,
})
end)
it('becomes visible when exiting Terminal mode', function()
skip(is_os('win'), '#31587')
hide_cursor()
screen:expect([[
tty ready |
|*5
{3:-- TERMINAL --} |
]])
feed('<c-\\><c-n>')
screen:expect([[
tty ready |
^ |
|*5
]])
feed('i')
screen:expect([[
tty ready |
|*5
{3:-- TERMINAL --} |
]])
end)
end)
it('can be modified by application #3681 #31685', function()
skip(is_os('win'), '#31587')
local states = {
[1] = { blink = true, shape = 'block' },
[2] = { blink = false, shape = 'block' },
[3] = { blink = true, shape = 'horizontal' },
[4] = { blink = false, shape = 'horizontal' },
[5] = { blink = true, shape = 'vertical' },
[6] = { blink = false, shape = 'vertical' },
}
for k, v in pairs(states) do
tt.feed_csi(('%d q'):format(k))
screen:expect({
grid = [[
tty ready |
^ |
|*4
{3:-- TERMINAL --} |
]],
condition = function()
if v.blink then
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
else
eq(0, screen._mode_info[terminal_mode_idx].blinkon)
eq(0, screen._mode_info[terminal_mode_idx].blinkoff)
end
eq(v.shape, screen._mode_info[terminal_mode_idx].cursor_shape)
-- Cell percentages are hard coded for each shape in terminal.c
if v.shape == 'horizontal' then
eq(20, screen._mode_info[terminal_mode_idx].cell_percentage)
elseif v.shape == 'vertical' then
eq(25, screen._mode_info[terminal_mode_idx].cell_percentage)
end
end,
})
end
feed([[<C-\><C-N>]])
screen:expect([[
tty ready |
^ |
|*5
]])
-- Cursor returns to default on TermLeave
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('block', screen._mode_info[terminal_mode_idx].cursor_shape)
end)
it('can be modified per terminal', function()
skip(is_os('win'), '#31587')
-- Set cursor to vertical bar with blink
tt.feed_csi('5 q')
screen:expect({
grid = [[
tty ready |
^ |
|*4
{3:-- TERMINAL --} |
]],
condition = function()
eq
|