Skip to content

Commit b7a8dfe

Browse files
committed
patch 8.0.0748: running Vim in terminal window doesn't use the right colors
Problem: When running Vim in a terminal window it does not detect the right number of colors available. Solution: Detect the version string that libvterm returns. Pass the number of colors in $COLORS.
1 parent e173fd0 commit b7a8dfe

3 files changed

Lines changed: 72 additions & 33 deletions

File tree

src/os_unix.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4063,7 +4063,13 @@ set_child_environment(long rows, long columns, char *term)
40634063
static char envbuf_Rows[20];
40644064
static char envbuf_Lines[20];
40654065
static char envbuf_Columns[20];
4066+
static char envbuf_Colors[20];
40664067
# endif
4068+
long colors =
4069+
# ifdef FEAT_GUI
4070+
gui.in_use ? 256*256*256 :
4071+
# endif
4072+
t_colors;
40674073

40684074
/* Simulate to have a dumb terminal (for now) */
40694075
# ifdef HAVE_SETENV
@@ -4074,6 +4080,8 @@ set_child_environment(long rows, long columns, char *term)
40744080
setenv("LINES", (char *)envbuf, 1);
40754081
sprintf((char *)envbuf, "%ld", columns);
40764082
setenv("COLUMNS", (char *)envbuf, 1);
4083+
sprintf((char *)envbuf, "%ld", colors);
4084+
setenv("COLORS", (char *)envbuf, 1);
40774085
# else
40784086
/*
40794087
* Putenv does not copy the string, it has to remain valid.
@@ -4088,6 +4096,8 @@ set_child_environment(long rows, long columns, char *term)
40884096
vim_snprintf(envbuf_Columns, sizeof(envbuf_Columns),
40894097
"COLUMNS=%ld", columns);
40904098
putenv(envbuf_Columns);
4099+
vim_snprintf(envbuf_Colors, sizeof(envbuf_Colors), "COLORS=%ld", colors);
4100+
putenv(envbuf_Colors);
40914101
# endif
40924102
}
40934103

src/term.c

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,8 +1428,6 @@ parse_builtin_tcap(char_u *term)
14281428
}
14291429
}
14301430
#if defined(HAVE_TGETENT) || defined(FEAT_TERMRESPONSE)
1431-
static void set_color_count(int nr);
1432-
14331431
/*
14341432
* Set number of colors.
14351433
* Store it as a number in t_colors.
@@ -1447,6 +1445,35 @@ set_color_count(int nr)
14471445
*nr_colors = NUL;
14481446
set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE, 0);
14491447
}
1448+
1449+
/*
1450+
* Set the color count to "val" and redraw if it changed.
1451+
*/
1452+
static void
1453+
may_adjust_color_count(int val)
1454+
{
1455+
if (val != t_colors)
1456+
{
1457+
/* Nr of colors changed, initialize highlighting and
1458+
* redraw everything. This causes a redraw, which usually
1459+
* clears the message. Try keeping the message if it
1460+
* might work. */
1461+
set_keep_msg_from_hist();
1462+
set_color_count(val);
1463+
init_highlight(TRUE, FALSE);
1464+
# ifdef DEBUG_TERMRESPONSE
1465+
{
1466+
char buf[100];
1467+
int r = redraw_asap(CLEAR);
1468+
1469+
sprintf(buf, "Received t_Co, redraw_asap(): %d", r);
1470+
log_tr(buf);
1471+
}
1472+
# else
1473+
redraw_asap(CLEAR);
1474+
# endif
1475+
}
1476+
}
14501477
#endif
14511478

14521479
#ifdef HAVE_TGETENT
@@ -2713,9 +2740,9 @@ term_get_winpos(int *x, int *y)
27132740
# endif
27142741

27152742
void
2716-
term_set_winsize(int width, int height)
2743+
term_set_winsize(int height, int width)
27172744
{
2718-
OUT_STR(tgoto((char *)T_CWS, height, width));
2745+
OUT_STR(tgoto((char *)T_CWS, width, height));
27192746
}
27202747
#endif
27212748

@@ -2823,6 +2850,8 @@ term_settitle(char_u *title)
28232850
void
28242851
ttest(int pairs)
28252852
{
2853+
char_u *env_colors;
2854+
28262855
check_options(); /* make sure no options are NULL */
28272856

28282857
/*
@@ -2909,8 +2938,16 @@ ttest(int pairs)
29092938
}
29102939
need_gather = TRUE;
29112940

2912-
/* Set t_colors to the value of t_Co. */
2941+
/* Set t_colors to the value of $COLORS or t_Co. */
29132942
t_colors = atoi((char *)T_CCO);
2943+
env_colors = mch_getenv((char_u *)"COLORS");
2944+
if (env_colors != NULL && isdigit(*env_colors))
2945+
{
2946+
int colors = atoi((char *)env_colors);
2947+
2948+
if (colors != t_colors)
2949+
set_color_count(colors);
2950+
}
29142951
}
29152952

29162953
#if (defined(FEAT_GUI) && (defined(FEAT_MENU) || !defined(USE_ON_FLY_SCROLL))) \
@@ -4250,6 +4287,7 @@ check_termcode(
42504287
* "<Esc>[" or CSI:
42514288
*
42524289
* - Xterm version string: <Esc>[>{x};{vers};{y}c
4290+
* Libvterm returns {x} == 0, {vers} == 100, {y} == 0.
42534291
* Also eat other possible responses to t_RV, rxvt returns
42544292
* "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
42554293
* mrxvt has been reported to have "+" in the version. Assume
@@ -4359,10 +4397,8 @@ check_termcode(
43594397
/* rxvt sends its version number: "20703" is 2.7.3.
43604398
* Ignore it for when the user has set 'term' to xterm,
43614399
* even though it's an rxvt. */
4362-
if (extra > 0)
4363-
extra = atoi((char *)tp + extra);
4364-
if (extra > 20000)
4365-
extra = 0;
4400+
if (col > 20000)
4401+
col = 0;
43664402

43674403
if (tp[1 + (tp[0] != CSI)] == '>' && j == 2)
43684404
{
@@ -4371,25 +4407,36 @@ check_termcode(
43714407
if (!option_was_set((char_u *)"ttym"))
43724408
{
43734409
# ifdef TTYM_SGR
4374-
if (extra >= 277)
4410+
if (col >= 277)
43754411
set_option_value((char_u *)"ttym", 0L,
43764412
(char_u *)"sgr", 0);
43774413
else
43784414
# endif
43794415
/* if xterm version >= 95 use mouse dragging */
4380-
if (extra >= 95)
4416+
if (col >= 95)
43814417
set_option_value((char_u *)"ttym", 0L,
43824418
(char_u *)"xterm2", 0);
43834419
}
43844420

43854421
/* if xterm version >= 141 try to get termcap codes */
4386-
if (extra >= 141)
4422+
if (col >= 141)
43874423
{
43884424
LOG_TR("Enable checking for XT codes");
43894425
check_for_codes = TRUE;
43904426
need_gather = TRUE;
43914427
req_codes_from_term();
43924428
}
4429+
4430+
/* libvterm sends 0;100;0 */
4431+
if (col == 100
4432+
&& STRNCMP(tp + extra - 2, ">0;100;0c", 9) == 0)
4433+
{
4434+
/* If run from Vim $COLORS is set to the number of
4435+
* colors the terminal supports. Otherwise assume
4436+
* 256, libvterm supports even more. */
4437+
if (mch_getenv((char_u *)"COLORS") == NULL)
4438+
may_adjust_color_count(256);
4439+
}
43934440
}
43944441
# ifdef FEAT_EVAL
43954442
set_vim_var_string(VV_TERMRESPONSE, tp, i + 1);
@@ -5993,27 +6040,7 @@ got_code_from_term(char_u *code, int len)
59936040
{
59946041
/* Color count is not a key code. */
59956042
i = atoi((char *)str);
5996-
if (i != t_colors)
5997-
{
5998-
/* Nr of colors changed, initialize highlighting and
5999-
* redraw everything. This causes a redraw, which usually
6000-
* clears the message. Try keeping the message if it
6001-
* might work. */
6002-
set_keep_msg_from_hist();
6003-
set_color_count(i);
6004-
init_highlight(TRUE, FALSE);
6005-
#ifdef DEBUG_TERMRESPONSE
6006-
{
6007-
char buf[100];
6008-
int r = redraw_asap(CLEAR);
6009-
6010-
sprintf(buf, "Received t_Co, redraw_asap(): %d", r);
6011-
log_tr(buf);
6012-
}
6013-
#else
6014-
redraw_asap(CLEAR);
6015-
#endif
6016-
}
6043+
may_adjust_color_count(i);
60176044
}
60186045
else
60196046
{

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
748,
772774
/**/
773775
747,
774776
/**/

0 commit comments

Comments
 (0)