neovim/test/functional/terminal/highlight_spec.lua
2024-01-12 18:59:14 +00:00

391 lines
14 KiB
Lua

local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local api = helpers.api
local testprg, command = helpers.testprg, helpers.command
local nvim_prog_abs = helpers.nvim_prog_abs
local eq, eval = helpers.eq, helpers.eval
local fn = helpers.fn
local nvim_set = helpers.nvim_set
local is_os = helpers.is_os
local skip = helpers.skip
describe(':terminal highlight', function()
local screen
before_each(function()
clear()
screen = Screen.new(50, 7)
screen:set_default_attr_ids({
[1] = { foreground = 45 },
[2] = { background = 46 },
[3] = { foreground = 45, background = 46 },
[4] = { bold = true, italic = true, underline = true, strikethrough = true },
[5] = { bold = true },
[6] = { foreground = 12 },
[7] = { bold = true, reverse = true },
[8] = { background = 11 },
[9] = { foreground = 130 },
[10] = { reverse = true },
[11] = { background = 11 },
[12] = { bold = true, underdouble = true },
[13] = { italic = true, undercurl = true },
})
screen:attach({ rgb = false })
command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
{10: } |
|*4
{5:-- TERMINAL --} |
]])
end)
local function descr(title, attr_num, set_attrs_fn)
local function sub(s)
local str = s:gsub('NUM', attr_num)
return str
end
describe(title, function()
before_each(function()
set_attrs_fn()
thelpers.feed_data('text')
thelpers.clear_attrs()
thelpers.feed_data('text')
end)
local function pass_attrs()
skip(is_os('win'))
screen:expect(sub([[
tty ready |
{NUM:text}text{10: } |
|*4
{5:-- TERMINAL --} |
]]))
end
it('will pass the corresponding attributes', pass_attrs)
it('will pass the corresponding attributes on scrollback', function()
skip(is_os('win'))
pass_attrs()
local lines = {}
for i = 1, 8 do
table.insert(lines, 'line' .. tostring(i))
end
table.insert(lines, '')
thelpers.feed_data(lines)
screen:expect([[
line4 |
line5 |
line6 |
line7 |
line8 |
{10: } |
{5:-- TERMINAL --} |
]])
feed('<c-\\><c-n>gg')
screen:expect(sub([[
^tty ready |
{NUM:text}textline1 |
line2 |
line3 |
line4 |
line5 |
|
]]))
end)
end)
end
descr('foreground', 1, function()
thelpers.set_fg(45)
end)
descr('background', 2, function()
thelpers.set_bg(46)
end)
descr('foreground and background', 3, function()
thelpers.set_fg(45)
thelpers.set_bg(46)
end)
descr('bold, italics, underline and strikethrough', 4, function()
thelpers.set_bold()
thelpers.set_italic()
thelpers.set_underline()
thelpers.set_strikethrough()
end)
descr('bold and underdouble', 12, function()
thelpers.set_bold()
thelpers.set_underdouble()
end)
descr('italics and undercurl', 13, function()
thelpers.set_italic()
thelpers.set_undercurl()
end)
end)
it(':terminal highlight has lower precedence than editor #9964', function()
clear()
local screen = Screen.new(30, 4)
screen:set_default_attr_ids({
-- "Normal" highlight emitted by the child nvim process.
N_child = {
foreground = tonumber('0x4040ff'),
background = tonumber('0xffff40'),
fg_indexed = true,
bg_indexed = true,
},
-- "Search" highlight in the parent nvim process.
S = { background = Screen.colors.Green, italic = true, foreground = Screen.colors.Red },
-- "Question" highlight in the parent nvim process.
-- note: bg is indexed as it comes from the (cterm) child, while fg isn't as it comes from (rgb) parent
Q = {
background = tonumber('0xffff40'),
bold = true,
foreground = Screen.colors.SeaGreen4,
bg_indexed = true,
},
})
screen:attach({ rgb = true })
-- Child nvim process in :terminal (with cterm colors).
fn.termopen({
nvim_prog_abs(),
'-n',
'-u',
'NORC',
'-i',
'NONE',
'--cmd',
nvim_set .. ' notermguicolors',
'+hi Normal ctermfg=Blue ctermbg=Yellow',
'+norm! ichild nvim',
'+norm! oline 2',
}, {
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
})
screen:expect([[
{N_child:^child nvim }|
{N_child:line 2 }|
{N_child: }|
|
]])
command('hi Search gui=italic guifg=Red guibg=Green cterm=italic ctermfg=Red ctermbg=Green')
feed('/nvim<cr>')
screen:expect([[
{N_child:child }{S:^nvim}{N_child: }|
{N_child:line 2 }|
{N_child: }|
/nvim |
]])
command('syntax keyword Question line')
screen:expect([[
{N_child:child }{S:^nvim}{N_child: }|
{Q:line}{N_child: 2 }|
{N_child: }|
/nvim |
]])
end)
describe(':terminal highlight forwarding', function()
local screen
before_each(function()
clear()
screen = Screen.new(50, 7)
screen:set_rgb_cterm(true)
screen:set_default_attr_ids({
[1] = { { reverse = true }, { reverse = true } },
[2] = { { bold = true }, { bold = true } },
[3] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } },
[4] = { { foreground = tonumber('0xff8000') }, {} },
})
screen:attach()
command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
{1: } |
|*4
{2:-- TERMINAL --} |
]])
end)
it('will handle cterm and rgb attributes', function()
skip(is_os('win'))
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.feed_termcode('[38:2:255:128:0m')
thelpers.feed_data('color')
thelpers.clear_attrs()
thelpers.feed_data('text')
screen:expect {
grid = [[
tty ready |
{3:text}{4:color}text{1: } |
|*4
{2:-- TERMINAL --} |
]],
}
end)
end)
describe(':terminal highlight with custom palette', function()
local screen
before_each(function()
clear()
screen = Screen.new(50, 7)
screen:set_default_attr_ids({
[1] = { foreground = tonumber('0x123456') }, -- no fg_indexed when overridden
[2] = { foreground = 12 },
[3] = { bold = true, reverse = true },
[5] = { background = 11 },
[6] = { foreground = 130 },
[7] = { reverse = true },
[8] = { background = 11 },
[9] = { bold = true },
})
screen:attach({ rgb = true })
api.nvim_set_var('terminal_color_3', '#123456')
command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
{7: } |
|*4
{9:-- TERMINAL --} |
]])
end)
it('will use the custom color', function()
skip(is_os('win'))
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.clear_attrs()
thelpers.feed_data('text')
screen:expect([[
tty ready |
{1:text}text{7: } |
|*4
{9:-- TERMINAL --} |
]])
end)
end)
describe('synIDattr()', function()
local screen
before_each(function()
clear()
screen = Screen.new(50, 7)
command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black')
-- Salmon #fa8072 Maroon #800000
command(
'highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough'
)
end)
it('returns cterm-color if RGB-capable UI is _not_ attached', function()
eq('252', eval('synIDattr(hlID("Normal"), "fg")'))
eq('252', eval('synIDattr(hlID("Normal"), "fg#")'))
eq('', eval('synIDattr(hlID("Normal"), "bg")'))
eq('', eval('synIDattr(hlID("Normal"), "bg#")'))
eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
eq('79', eval('synIDattr(hlID("Keyword"), "fg#")'))
eq('', eval('synIDattr(hlID("Keyword"), "sp")'))
eq('', eval('synIDattr(hlID("Keyword"), "sp#")'))
end)
it('returns gui-color if "gui" arg is passed', function()
eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")'))
eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")'))
end)
it('returns gui-color if RGB-capable UI is attached', function()
screen:attach({ rgb = true })
eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")'))
eq('Black', eval('synIDattr(hlID("Normal"), "bg")'))
eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")'))
eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")'))
end)
it('returns #RRGGBB value for fg#/bg#/sp#', function()
screen:attach({ rgb = true })
eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")'))
eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")'))
eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")'))
eq('#800000', eval('synIDattr(hlID("Keyword"), "sp#")'))
end)
it('returns color number if non-GUI', function()
screen:attach({ rgb = false })
eq('252', eval('synIDattr(hlID("Normal"), "fg")'))
eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
end)
it('returns "1" if group has given highlight attribute', function()
local hl_attrs = {
'underline',
'undercurl',
'underdouble',
'underdotted',
'underdashed',
'strikethrough',
}
for _, hl_attr in ipairs(hl_attrs) do
local context = 'using ' .. hl_attr .. ' attr'
command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr)
eq('', eval('synIDattr(hlID("Normal"), "' .. hl_attr .. '")'), context)
eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context)
eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context)
end
end)
end)
describe('fg/bg special colors', function()
local screen
before_each(function()
clear()
screen = Screen.new(50, 7)
command('highlight Normal ctermfg=145 ctermbg=16 guifg=#ff0000 guibg=Black')
command('highlight Visual ctermfg=bg ctermbg=fg guifg=bg guibg=fg guisp=bg')
end)
it('resolve to "Normal" values', function()
eq(eval('synIDattr(hlID("Normal"), "bg")'), eval('synIDattr(hlID("Visual"), "fg")'))
eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")'))
eq(eval('synIDattr(hlID("Normal"), "fg")'), eval('synIDattr(hlID("Visual"), "bg")'))
eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")'))
eq('bg', eval('synIDattr(hlID("Visual"), "fg", "gui")'))
eq('bg', eval('synIDattr(hlID("Visual"), "fg#", "gui")'))
eq('fg', eval('synIDattr(hlID("Visual"), "bg", "gui")'))
eq('fg', eval('synIDattr(hlID("Visual"), "bg#", "gui")'))
eq('bg', eval('synIDattr(hlID("Visual"), "sp", "gui")'))
eq('bg', eval('synIDattr(hlID("Visual"), "sp#", "gui")'))
end)
it('resolve to "Normal" values in RGB-capable UI', function()
screen:attach({ rgb = true })
eq('bg', eval('synIDattr(hlID("Visual"), "fg")'))
eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")'))
eq('fg', eval('synIDattr(hlID("Visual"), "bg")'))
eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")'))
eq('bg', eval('synIDattr(hlID("Visual"), "sp")'))
eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "sp#")'))
end)
it('resolve after the "Normal" group is modified', function()
screen:attach({ rgb = true })
local new_guibg = '#282c34'
local new_guifg = '#abb2bf'
command('highlight Normal guifg=' .. new_guifg .. ' guibg=' .. new_guibg)
eq(new_guibg, eval('synIDattr(hlID("Visual"), "fg#")'))
eq(new_guifg, eval('synIDattr(hlID("Visual"), "bg#")'))
eq(new_guibg, eval('synIDattr(hlID("Visual"), "sp#")'))
end)
end)