Files
neovim/test/functional/terminal/cursor_spec.lua
Gregory Anders 0dd933265f feat(terminal)!: cursor shape and blink (#31562)
When a terminal application running inside the terminal emulator sets
the cursor shape or blink status of the cursor, update the cursor in the
parent terminal to match.

This removes the "virtual cursor" that has been in use by the terminal
emulator since the beginning. The original rationale for using the
virtual cursor was to avoid having to support additional UI methods to
change the cursor color for other (non-TUI) UIs, instead relying on the
TermCursor and TermCursorNC highlight groups.

The TermCursor highlight group is now used in the default 'guicursor'
value, which has a new entry for Terminal mode. However, the
TermCursorNC highlight group is no longer supported: since terminal
windows now use the real cursor, when the window is not focused there is
no cursor displayed in the window at all, so there is nothing to
highlight. Users can still use the StatusLineTermNC highlight group to
differentiate non-focused terminal windows.

BREAKING CHANGE: The TermCursorNC highlight group is no longer supported.
2024-12-17 07:11:41 -06:00

1049 lines
46 KiB
Lua

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
before_each(function()
clear()
screen = tt.setup_screen()
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', function()
skip(is_os('win'), '#31587')
local idx ---@type number
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
idx = i
end
end
assert(idx)
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[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
else
eq(0, screen._mode_info[idx].blinkon)
eq(0, screen._mode_info[idx].blinkoff)
end
eq(v.shape, screen._mode_info[idx].cursor_shape)
end,
})
end
feed([[<C-\><C-N>]])
screen:expect([[
tty ready |
^ |
|*5
]])
-- Cursor returns to default on TermLeave
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('block', screen._mode_info[idx].cursor_shape)
end)
it('can be modified per terminal', function()
skip(is_os('win'), '#31587')
local idx ---@type number
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
idx = i
end
end
assert(idx)
-- Set cursor to vertical bar with blink
tt.feed_csi('5 q')
screen:expect({
grid = [[
tty ready |
^ |
|*4
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
end,
})
tt.hide_cursor()
screen:expect({
grid = [[
tty ready |
|
|*4
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
end,
})
-- Exit terminal mode to reset terminal cursor settings to default and
-- create a new terminal window
feed([[<C-\><C-N>]])
command('set statusline=~~~')
command('new')
call('termopen', { testprg('tty-test') })
feed('i')
screen:expect({
grid = [[
tty ready |
^ |
{17:~~~ }|
rows: 2, cols: 50 |
|
{18:~~~ }|
{3:-- TERMINAL --} |
]],
condition = function()
-- New terminal, cursor resets to defaults
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('block', screen._mode_info[idx].cursor_shape)
end,
})
-- Set cursor to underline, no blink
tt.feed_csi('4 q')
screen:expect({
grid = [[
tty ready |
^ |
{17:~~~ }|
rows: 2, cols: 50 |
|
{18:~~~ }|
{3:-- TERMINAL --} |
]],
condition = function()
eq(0, screen._mode_info[idx].blinkon)
eq(0, screen._mode_info[idx].blinkoff)
eq('horizontal', screen._mode_info[idx].cursor_shape)
end,
})
-- Switch back to first terminal, cursor should still be hidden
command('wincmd p')
screen:expect({
grid = [[
tty ready |
|
{18:~~~ }|
rows: 2, cols: 50 |
|
{17:~~~ }|
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
end,
})
end)
it('can be positioned arbitrarily', function()
clear()
screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'--cmd',
n.nvim_set .. ' noshowmode',
})
screen:expect([[
^ |
~ |*4
|
{3:-- TERMINAL --} |
]])
feed('i<Tab>')
screen:expect([[
^ |
~ |*4
|
{3:-- TERMINAL --} |
]])
end)
end)
describe('buffer cursor position is correct in terminal without number column', function()
local screen
local function setup_ex_register(str)
screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'-E',
'--cmd',
string.format('let @r = "%s"', str),
-- <Left> and <Right> don't always work
'--cmd',
'cnoremap <C-X> <Left>',
'--cmd',
'cnoremap <C-O> <Right>',
'--cmd',
'set notermguicolors',
}, {
cols = 70,
})
screen:set_default_attr_ids({
[1] = { foreground = 253, background = 11 },
[2] = { reverse = true },
[3] = { bold = true },
[4] = { background = 11 },
})
-- Also check for real cursor position, as it is used for stuff like input methods
screen._handle_busy_start = function() end
screen._handle_busy_stop = function() end
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:^ |
{3:-- TERMINAL --} |
]])
end
before_each(clear)
describe('in a line with no multibyte chars or trailing spaces,', function()
before_each(function()
setup_ex_register('aaaaaaaa')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaaaaa^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 9 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaaaa^a |
|
]])
eq({ 6, 8 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaaa^aa |
{3:-- TERMINAL --} |
]])
eq({ 6, 7 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaa^aaa |
|
]])
eq({ 6, 6 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:a^aaaaaaa |
{3:-- TERMINAL --} |
]])
eq({ 6, 2 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:^aaaaaaaa |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with single-cell multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('µµµµµµµµ')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µµµµµµµµ^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 17 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µµµµµµµ^µ |
|
]])
eq({ 6, 15 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µµµµµµ^µµ |
{3:-- TERMINAL --} |
]])
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µµµµµ^µµµ |
|
]])
eq({ 6, 11 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ^µµµµµµµ |
{3:-- TERMINAL --} |
]])
eq({ 6, 3 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:^µµµµµµµµ |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with single-cell composed multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 33 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳ |
|
]])
eq({ 6, 29 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
skip(is_os('win'))
feed('<C-R>r<C-X><C-X>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ̳µ̳µ̳µ̳µ̳µ̳^µ̳µ̳ |
{3:-- TERMINAL --} |
]])
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ̳µ̳µ̳µ̳µ̳^µ̳µ̳µ̳ |
|
]])
eq({ 6, 21 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
skip(is_os('win'))
feed('<C-R>r<C-B><C-O>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:µ̳^µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
{3:-- TERMINAL --} |
]])
eq({ 6, 5 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:^µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with double-cell multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('哦哦哦哦哦哦哦哦')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:哦哦哦哦哦哦哦哦^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:哦哦哦哦哦哦哦^哦 |
|
]])
eq({ 6, 22 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:哦哦哦哦哦哦^哦哦 |
{3:-- TERMINAL --} |
]])
eq({ 6, 19 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:哦哦哦哦哦^哦哦哦 |
|
]])
eq({ 6, 16 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:哦^哦哦哦哦哦哦哦 |
{3:-- TERMINAL --} |
]])
eq({ 6, 4 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:^哦哦哦哦哦哦哦哦 |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
it('at the end of a line with trailing spaces #16234', function()
setup_ex_register('aaaaaaaa ')
feed('<C-R>r')
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaaaaa ^ |
{3:-- TERMINAL --} |
]])
matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
|*4
Entering Ex mode. Type "visual" to go to Normal mode. |
:aaaaaaaa ^ |
|
]])
eq({ 6, 12 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('buffer cursor position is correct in terminal with number column', function()
local screen
local function setup_ex_register(str)
screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'-E',
'--cmd',
string.format('let @r = "%s"', str),
-- <Left> and <Right> don't always work
'--cmd',
'cnoremap <C-X> <Left>',
'--cmd',
'cnoremap <C-O> <Right>',
'--cmd',
'set notermguicolors',
}, {
cols = 70,
})
screen:set_default_attr_ids({
[1] = { foreground = 253, background = 11 },
[2] = { reverse = true },
[3] = { bold = true },
[4] = { background = 11 },
[7] = { foreground = 130 },
})
-- Also check for real cursor position, as it is used for stuff like input methods
screen._handle_busy_start = function() end
screen._handle_busy_stop = function() end
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:^ |
{3:-- TERMINAL --} |
]])
end
before_each(function()
clear()
command('au TermOpen * set number')
end)
describe('in a line with no multibyte chars or trailing spaces,', function()
before_each(function()
setup_ex_register('aaaaaaaa')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaaaaa^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 9 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaaaa^a |
|
]])
eq({ 6, 8 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaaa^aa |
{3:-- TERMINAL --} |
]])
eq({ 6, 7 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaa^aaa |
|
]])
eq({ 6, 6 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:a^aaaaaaa |
{3:-- TERMINAL --} |
]])
eq({ 6, 2 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:^aaaaaaaa |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with single-cell multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('µµµµµµµµ')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µµµµµµµµ^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 17 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µµµµµµµ^µ |
|
]])
eq({ 6, 15 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µµµµµµ^µµ |
{3:-- TERMINAL --} |
]])
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µµµµµ^µµµ |
|
]])
eq({ 6, 11 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ^µµµµµµµ |
{3:-- TERMINAL --} |
]])
eq({ 6, 3 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:^µµµµµµµµ |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with single-cell composed multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 33 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳ |
|
]])
eq({ 6, 29 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
skip(is_os('win'))
feed('<C-R>r<C-X><C-X>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳^µ̳µ̳ |
{3:-- TERMINAL --} |
]])
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳µ̳µ̳ |
|
]])
eq({ 6, 21 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
skip(is_os('win'))
feed('<C-R>r<C-B><C-O>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:µ̳^µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
{3:-- TERMINAL --} |
]])
eq({ 6, 5 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:^µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
describe('in a line with double-cell multibyte chars and no trailing spaces,', function()
before_each(function()
setup_ex_register('哦哦哦哦哦哦哦哦')
end)
it('at the end', function()
feed('<C-R>r')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:哦哦哦哦哦哦哦哦^ |
{3:-- TERMINAL --} |
]])
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:哦哦哦哦哦哦哦^哦 |
|
]])
eq({ 6, 22 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the end', function()
feed('<C-R>r<C-X><C-X>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:哦哦哦哦哦哦^哦哦 |
{3:-- TERMINAL --} |
]])
eq({ 6, 19 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:哦哦哦哦哦^哦哦哦 |
|
]])
eq({ 6, 16 }, eval('nvim_win_get_cursor(0)'))
end)
it('near the start', function()
feed('<C-R>r<C-B><C-O>')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:哦^哦哦哦哦哦哦哦 |
{3:-- TERMINAL --} |
]])
eq({ 6, 4 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:^哦哦哦哦哦哦哦哦 |
|
]])
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
end)
end)
it('at the end of a line with trailing spaces #16234', function()
setup_ex_register('aaaaaaaa ')
feed('<C-R>r')
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaaaaa ^ |
{3:-- TERMINAL --} |
]])
matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
feed([[<C-\><C-N>]])
screen:expect([[
{7: 1 } |
{7: 2 } |
{7: 3 } |
{7: 4 } |
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
{7: 6 }:aaaaaaaa ^ |
|
]])
eq({ 6, 12 }, eval('nvim_win_get_cursor(0)'))
end)
end)