mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 17:41:48 +00:00
fix(terminal): truecolor SGR with colour space id #41491
libvterm reads the first three sub-parameters of an SGR 38:2 or 48:2 sequence as R:G:B, so a colour space id shifts the channels: the empty slot becomes red via CSI_ARG_MISSING truncating to 255, and green and blue move over one. Skip the colour space id when the colon-separated group holds more than three arguments. The group length comes from CSI_ARG_HAS_MORE rather than the raw argument count, so a following semicolon-separated parameter is not consumed.
This commit is contained in:
@@ -90,15 +90,25 @@ static int lookup_colour(const VTermState *state, int palette, const long args[]
|
||||
VTermColor *col)
|
||||
{
|
||||
switch (palette) {
|
||||
case 2: // RGB mode - 3 args contain colour values directly
|
||||
if (argcount < 3) {
|
||||
case 2: { // RGB mode - 3 args contain colour values directly
|
||||
// ITU-T T.416 places a colour space id before R:G:B, as in "38:2::R:G:B".
|
||||
// Skip it when this colon-separated group holds more than three arguments.
|
||||
int grouplen = 0;
|
||||
while (grouplen < argcount && CSI_ARG_HAS_MORE(args[grouplen])) {
|
||||
grouplen++;
|
||||
}
|
||||
grouplen = grouplen < argcount ? grouplen + 1 : argcount;
|
||||
const int skip = grouplen > 3 ? 1 : 0;
|
||||
|
||||
if (argcount - skip < 3) {
|
||||
return argcount;
|
||||
}
|
||||
|
||||
vterm_color_rgb(col, (uint8_t)CSI_ARG(args[0]), (uint8_t)CSI_ARG(args[1]),
|
||||
(uint8_t)CSI_ARG(args[2]));
|
||||
vterm_color_rgb(col, (uint8_t)CSI_ARG(args[skip]), (uint8_t)CSI_ARG(args[skip + 1]),
|
||||
(uint8_t)CSI_ARG(args[skip + 2]));
|
||||
|
||||
return 3;
|
||||
return skip + 3;
|
||||
}
|
||||
|
||||
case 5: // XTerm 256-colour mode
|
||||
if (!argcount || CSI_ARG_IS_MISSING(args[0])) {
|
||||
|
||||
@@ -332,6 +332,20 @@ describe(':terminal highlight forwarding', function()
|
||||
{1:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('handles truecolor SGR with a colour space id', function()
|
||||
skip(is_os('win'))
|
||||
tt.feed_termcode('[38:2::255:128:0m')
|
||||
tt.feed_data('color')
|
||||
tt.clear_attrs()
|
||||
tt.feed_data('text')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{3:color}text^ |
|
||||
|*4
|
||||
{1:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
--- @param buflocal boolean
|
||||
|
||||
Reference in New Issue
Block a user