diff --git a/src/nvim/vterm/pen.c b/src/nvim/vterm/pen.c index f2054633d5..4b7221be14 100644 --- a/src/nvim/vterm/pen.c +++ b/src/nvim/vterm/pen.c @@ -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])) { diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 9df2777d1f..acab5331a4 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -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