mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 8.2.4982: colors in terminal window are not 100% correct
Problem: Colors in terminal window are not 100% correct. Solution: Use g:terminal_ansi_colors as documented. (closes #10429, closes #7227 closes #10347)
This commit is contained in:
207
src/terminal.c
207
src/terminal.c
@@ -162,6 +162,8 @@ struct terminal_S {
|
||||
int tl_cursor_shape; // 1: block, 2: underline, 3: bar
|
||||
char_u *tl_cursor_color; // NULL or allocated
|
||||
|
||||
long_u *tl_palette; // array of 16 colors specified by term_start, can
|
||||
// be NULL
|
||||
int tl_using_altscreen;
|
||||
garray_T tl_osc_buf; // incomplete OSC string
|
||||
};
|
||||
@@ -242,6 +244,25 @@ cursor_color_get(char_u *color)
|
||||
return (color == NULL) ? (char_u *)"" : color;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if the user-defined palette (either g:terminal_ansi_colors or the
|
||||
* "ansi_colors" argument in term_start()) shall be applied.
|
||||
*/
|
||||
static int
|
||||
term_use_palette()
|
||||
{
|
||||
if (0
|
||||
#ifdef FEAT_GUI
|
||||
|| gui.in_use
|
||||
#endif
|
||||
#ifdef FEAT_TERMGUICOLORS
|
||||
|| p_tgc
|
||||
#endif
|
||||
)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse 'termwinsize' and set "rows" and "cols" for the terminal size in the
|
||||
@@ -705,6 +726,18 @@ term_start(
|
||||
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
|
||||
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
|
||||
|
||||
// Save the user-defined palette, it is only used in GUI (or 'tgc' is on).
|
||||
if (opt->jo_set2 & JO2_ANSI_COLORS)
|
||||
{
|
||||
term->tl_palette = ALLOC_MULT(long_u, 16);
|
||||
if (term->tl_palette == NULL)
|
||||
{
|
||||
vim_free(term);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(term->tl_palette, opt->jo_ansi_colors, sizeof(long_u) * 16);
|
||||
}
|
||||
|
||||
// System dependent: setup the vterm and maybe start the job in it.
|
||||
if (argv == NULL
|
||||
&& argvar->v_type == VAR_STRING
|
||||
@@ -1118,6 +1151,7 @@ free_unused_terminals()
|
||||
#endif
|
||||
vim_free(term->tl_highlight_name);
|
||||
vim_free(term->tl_cursor_color);
|
||||
vim_free(term->tl_palette);
|
||||
vim_free(term);
|
||||
}
|
||||
}
|
||||
@@ -2795,31 +2829,24 @@ color2index(VTermColor *color, int fg, int *boldp)
|
||||
int blue = color->blue;
|
||||
int green = color->green;
|
||||
|
||||
*boldp = FALSE;
|
||||
|
||||
if (VTERM_COLOR_IS_INVALID(color))
|
||||
return 0;
|
||||
|
||||
if (VTERM_COLOR_IS_INDEXED(color))
|
||||
{
|
||||
// The first 16 colors and default: use the ANSI index.
|
||||
switch (color->index + 1)
|
||||
// Use the color as-is if possible, give up otherwise.
|
||||
if (color->index < t_colors)
|
||||
return color->index + 1;
|
||||
// 8-color terminals can actually display twice as many colors by
|
||||
// setting the high-intensity/bold bit.
|
||||
else if (t_colors == 8 && fg && color->index < 16)
|
||||
{
|
||||
case 0: return 0;
|
||||
case 1: return lookup_color( 0, fg, boldp) + 1; // black
|
||||
case 2: return lookup_color( 4, fg, boldp) + 1; // dark red
|
||||
case 3: return lookup_color( 2, fg, boldp) + 1; // dark green
|
||||
case 4: return lookup_color( 7, fg, boldp) + 1; // dark yellow
|
||||
case 5: return lookup_color( 1, fg, boldp) + 1; // dark blue
|
||||
case 6: return lookup_color( 5, fg, boldp) + 1; // dark magenta
|
||||
case 7: return lookup_color( 3, fg, boldp) + 1; // dark cyan
|
||||
case 8: return lookup_color( 8, fg, boldp) + 1; // light grey
|
||||
case 9: return lookup_color(12, fg, boldp) + 1; // dark grey
|
||||
case 10: return lookup_color(20, fg, boldp) + 1; // red
|
||||
case 11: return lookup_color(16, fg, boldp) + 1; // green
|
||||
case 12: return lookup_color(24, fg, boldp) + 1; // yellow
|
||||
case 13: return lookup_color(14, fg, boldp) + 1; // blue
|
||||
case 14: return lookup_color(22, fg, boldp) + 1; // magenta
|
||||
case 15: return lookup_color(18, fg, boldp) + 1; // cyan
|
||||
case 16: return lookup_color(26, fg, boldp) + 1; // white
|
||||
*boldp = TRUE;
|
||||
return (color->index & 7) + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t_colors >= 256)
|
||||
@@ -4251,11 +4278,13 @@ init_vterm_ansi_colors(VTerm *vterm)
|
||||
{
|
||||
dictitem_T *var = find_var((char_u *)"g:terminal_ansi_colors", NULL, TRUE);
|
||||
|
||||
if (var != NULL
|
||||
&& (var->di_tv.v_type != VAR_LIST
|
||||
|| var->di_tv.vval.v_list == NULL
|
||||
|| var->di_tv.vval.v_list->lv_first == &range_list_item
|
||||
|| set_ansi_colors_list(vterm, var->di_tv.vval.v_list) == FAIL))
|
||||
if (var == NULL)
|
||||
return;
|
||||
|
||||
if (var->di_tv.v_type != VAR_LIST
|
||||
|| var->di_tv.vval.v_list == NULL
|
||||
|| var->di_tv.vval.v_list->lv_first == &range_list_item
|
||||
|| set_ansi_colors_list(vterm, var->di_tv.vval.v_list) == FAIL)
|
||||
semsg(_(e_invalid_argument_str), "g:terminal_ansi_colors");
|
||||
}
|
||||
#endif
|
||||
@@ -4689,6 +4718,62 @@ create_vterm(term_T *term, int rows, int cols)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the terminal palette to its default value.
|
||||
*/
|
||||
static void
|
||||
term_reset_palette(VTerm *vterm)
|
||||
{
|
||||
VTermState *state = vterm_obtain_state(vterm);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < 16; index++)
|
||||
{
|
||||
VTermColor color;
|
||||
|
||||
color.type = VTERM_COLOR_INDEXED;
|
||||
ansi_color2rgb(index, &color.red, &color.green, &color.blue,
|
||||
&color.index);
|
||||
// The first valid index starts at 1.
|
||||
color.index -= 1;
|
||||
|
||||
vterm_state_set_palette_color(state, index, &color);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
term_update_palette(term_T *term)
|
||||
{
|
||||
if (term_use_palette()
|
||||
&& (term->tl_palette != NULL
|
||||
|| find_var((char_u *)"g:terminal_ansi_colors", NULL, TRUE)
|
||||
!= NULL))
|
||||
{
|
||||
if (term->tl_palette != NULL)
|
||||
set_vterm_palette(term->tl_vterm, term->tl_palette);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
}
|
||||
else
|
||||
term_reset_palette(term->tl_vterm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when option 'termguicolors' is changed.
|
||||
*/
|
||||
void
|
||||
term_update_palette_all()
|
||||
{
|
||||
term_T *term;
|
||||
|
||||
FOR_ALL_TERMS(term)
|
||||
{
|
||||
if (term->tl_vterm == NULL)
|
||||
continue;
|
||||
term_update_palette(term);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when option 'background' or 'termguicolors' was set,
|
||||
* or when any highlight is changed.
|
||||
@@ -6346,6 +6431,8 @@ f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
buf_T *buf;
|
||||
term_T *term;
|
||||
listitem_T *li;
|
||||
int n = 0;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_buffer_arg(argvars, 0) == FAIL
|
||||
@@ -6364,9 +6451,38 @@ f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
emsg(_(e_list_required));
|
||||
return;
|
||||
}
|
||||
|
||||
if (set_ansi_colors_list(term->tl_vterm, argvars[1].vval.v_list) == FAIL)
|
||||
if (argvars[1].vval.v_list->lv_first == &range_list_item
|
||||
|| argvars[1].vval.v_list->lv_len != 16)
|
||||
{
|
||||
emsg(_(e_invalid_argument));
|
||||
return;
|
||||
}
|
||||
|
||||
if (term->tl_palette == NULL)
|
||||
term->tl_palette = ALLOC_MULT(long_u, 16);
|
||||
if (term->tl_palette == NULL)
|
||||
return;
|
||||
|
||||
FOR_ALL_LIST_ITEMS(argvars[1].vval.v_list, li)
|
||||
{
|
||||
char_u *color_name;
|
||||
guicolor_T guicolor;
|
||||
|
||||
color_name = tv_get_string_chk(&li->li_tv);
|
||||
if (color_name == NULL)
|
||||
return;
|
||||
|
||||
guicolor = GUI_GET_COLOR(color_name);
|
||||
if (guicolor == INVALCOLOR)
|
||||
{
|
||||
semsg(_(e_cannot_allocate_color_str), color_name);
|
||||
return;
|
||||
}
|
||||
|
||||
term->tl_palette[n++] = GUI_MCH_GET_RGB(guicolor);
|
||||
}
|
||||
|
||||
term_update_palette(term);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6823,12 +6939,13 @@ conpty_term_and_job_init(
|
||||
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
|
||||
goto failed;
|
||||
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (opt->jo_set2 & JO2_ANSI_COLORS)
|
||||
set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
#endif
|
||||
if (term_use_palette())
|
||||
{
|
||||
if (term->tl_palette != NULL)
|
||||
set_vterm_palette(term->tl_vterm, term->tl_palette);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
}
|
||||
|
||||
channel_set_job(channel, job, opt);
|
||||
job_set_options(job, opt);
|
||||
@@ -7154,12 +7271,13 @@ winpty_term_and_job_init(
|
||||
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
|
||||
goto failed;
|
||||
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (opt->jo_set2 & JO2_ANSI_COLORS)
|
||||
set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
#endif
|
||||
if (term_use_palette())
|
||||
{
|
||||
if (term->tl_palette != NULL)
|
||||
set_vterm_palette(term->tl_vterm, term->tl_palette);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
}
|
||||
|
||||
channel_set_job(channel, job, opt);
|
||||
job_set_options(job, opt);
|
||||
@@ -7413,12 +7531,13 @@ term_and_job_init(
|
||||
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (opt->jo_set2 & JO2_ANSI_COLORS)
|
||||
set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
#endif
|
||||
if (term_use_palette())
|
||||
{
|
||||
if (term->tl_palette != NULL)
|
||||
set_vterm_palette(term->tl_vterm, term->tl_palette);
|
||||
else
|
||||
init_vterm_ansi_colors(term->tl_vterm);
|
||||
}
|
||||
|
||||
// This may change a string in "argvar".
|
||||
term->tl_job = job_start(argvar, argv, opt, &term->tl_job);
|
||||
|
Reference in New Issue
Block a user