Patch 8.2.4982

6 views
Skip to first unread message

Bram Moolenaar

unread,
May 20, 2022, 5:12:01 AM5/20/22
to vim...@googlegroups.com

Patch 8.2.4982
Problem: Colors in terminal window are not 100% correct.
Solution: Use g:terminal_ansi_colors as documented. (closes #10429,
closes #7227 closes #10347)
Files: src/job.c, src/option.c, src/proto/term.pro,
src/terminal.c, src/proto/terminal.pro, src/term.c,
src/testdir/test_functions.vim, src/testdir/test_terminal.vim


*** ../vim-8.2.4981/src/job.c 2022-05-09 20:09:19.286641426 +0100
--- src/job.c 2022-05-20 09:28:30.147063583 +0100
***************
*** 548,560 ****
break;

if (item == NULL || item->v_type != VAR_LIST
! || item->vval.v_list == NULL)
{
semsg(_(e_invalid_value_for_argument_str), "ansi_colors");
return FAIL;
}

- CHECK_LIST_MATERIALIZE(item->vval.v_list);
li = item->vval.v_list->lv_first;
for (; li != NULL && n < 16; li = li->li_next, n++)
{
--- 548,560 ----
break;

if (item == NULL || item->v_type != VAR_LIST
! || item->vval.v_list == NULL
! || item->vval.v_list->lv_first == &range_list_item)
{
semsg(_(e_invalid_value_for_argument_str), "ansi_colors");
return FAIL;
}

li = item->vval.v_list->lv_first;
for (; li != NULL && n < 16; li = li->li_next, n++)
{
*** ../vim-8.2.4981/src/option.c 2022-05-09 20:09:19.290641428 +0100
--- src/option.c 2022-05-20 09:34:38.504068577 +0100
***************
*** 3255,3260 ****
--- 3255,3261 ----
# endif
# ifdef FEAT_TERMINAL
term_update_colors_all();
+ term_update_palette_all();
term_update_wincolor_all();
# endif
}
*** ../vim-8.2.4981/src/proto/term.pro 2021-12-03 20:43:20.088234242 +0000
--- src/proto/term.pro 2022-05-20 09:32:40.535766493 +0100
***************
*** 84,89 ****
--- 84,90 ----
int show_one_termcode(char_u *name, char_u *code, int printit);
void update_tcap(int attr);
void swap_tcap(void);
+ void ansi_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx);
void cterm_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx);
void term_replace_bs_del_keycode(char_u *ta_buf, int ta_len, int len);
/* vim: set ft=c : */
*** ../vim-8.2.4981/src/terminal.c 2022-05-09 20:09:19.294641425 +0100
--- src/terminal.c 2022-05-20 09:34:36.096062524 +0100
***************
*** 162,167 ****
--- 162,169 ----
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,247 ****
--- 244,268 ----
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,710 ****
--- 726,743 ----
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,1123 ****
--- 1151,1157 ----
#endif
vim_free(term->tl_highlight_name);
vim_free(term->tl_cursor_color);
+ vim_free(term->tl_palette);
vim_free(term);
}
}
***************
*** 2795,2825 ****
int blue = color->blue;
int green = color->green;

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)
{
! 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
}
}

if (t_colors >= 256)
--- 2829,2852 ----
int blue = color->blue;
int green = color->green;

+ *boldp = FALSE;
+
if (VTERM_COLOR_IS_INVALID(color))
return 0;
+
if (VTERM_COLOR_IS_INDEXED(color))
{
! // 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)
{
! *boldp = TRUE;
! return (color->index & 7) + 1;
}
+ return 0;
}

if (t_colors >= 256)
***************
*** 4251,4261 ****
{
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))
semsg(_(e_invalid_argument_str), "g:terminal_ansi_colors");
}
#endif
--- 4278,4290 ----
{
dictitem_T *var = find_var((char_u *)"g:terminal_ansi_colors", NULL, TRUE);

! 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
***************
*** 4690,4695 ****
--- 4719,4780 ----
}

/*
+ * 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,6351 ****
--- 6431,6438 ----
{
buf_T *buf;
term_T *term;
+ listitem_T *li;
+ int n = 0;

if (in_vim9script()
&& (check_for_buffer_arg(argvars, 0) == FAIL
***************
*** 6364,6372 ****
emsg(_(e_list_required));
return;
}
!
! if (set_ansi_colors_list(term->tl_vterm, argvars[1].vval.v_list) == FAIL)
emsg(_(e_invalid_argument));
}
#endif

--- 6451,6488 ----
emsg(_(e_list_required));
return;
}
! 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,6834 ****
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

channel_set_job(channel, job, opt);
job_set_options(job, opt);
--- 6939,6951 ----
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
goto failed;

! 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,7165 ****
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

channel_set_job(channel, job, opt);
job_set_options(job, opt);
--- 7271,7283 ----
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
goto failed;

! 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,7424 ****
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

// This may change a string in "argvar".
term->tl_job = job_start(argvar, argv, opt, &term->tl_job);
--- 7531,7543 ----
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;

! 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);
*** ../vim-8.2.4981/src/proto/terminal.pro 2021-12-13 21:59:04.895993159 +0000
--- src/proto/terminal.pro 2022-05-20 09:34:11.155999571 +0100
***************
*** 34,39 ****
--- 34,40 ----
void term_reset_wincolor(win_T *wp);
void term_update_wincolor(win_T *wp);
void term_update_wincolor_all(void);
+ void term_update_palette_all(void);
void term_update_colors_all(void);
char_u *term_get_status_text(term_T *term);
void term_clear_status_text(term_T *term);
*** ../vim-8.2.4981/src/term.c 2022-05-09 20:09:19.294641425 +0100
--- src/term.c 2022-05-20 09:28:30.151063595 +0100
***************
*** 6730,6736 ****
0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE
};

! static char_u ansi_table[16][3] = {
// R G B
{ 0, 0, 0}, // black
{224, 0, 0}, // dark red
--- 6730,6736 ----
0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE
};

! static const char_u ansi_table[16][3] = {
// R G B
{ 0, 0, 0}, // black
{224, 0, 0}, // dark red
***************
*** 6761,6766 ****
--- 6761,6785 ----
#define ANSI_INDEX_NONE 0

void
+ ansi_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx)
+ {
+ if (nr < 16)
+ {
+ *r = ansi_table[nr][0];
+ *g = ansi_table[nr][1];
+ *b = ansi_table[nr][2];
+ *ansi_idx = nr;
+ }
+ else
+ {
+ *r = 0;
+ *g = 0;
+ *b = 0;
+ *ansi_idx = ANSI_INDEX_NONE;
+ }
+ }
+
+ void
cterm_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx)
{
int idx;
*** ../vim-8.2.4981/src/testdir/test_functions.vim 2022-05-05 20:18:12.408138480 +0100
--- src/testdir/test_functions.vim 2022-05-20 09:28:30.155063608 +0100
***************
*** 2679,2686 ****
else
let cmd = "ls"
endif
! call assert_fails('call term_start("' .. cmd .. '", #{term_finish: "close"})', 'E475:')
! unlet g:terminal_ansi_colors
endif

" type()
--- 2679,2686 ----
else
let cmd = "ls"
endif
! call assert_fails('call term_start("' .. cmd .. '", #{term_finish: "close"'
! \ .. ', ansi_colors: range(16)})', 'E475:')
endif

" type()
*** ../vim-8.2.4981/src/testdir/test_terminal.vim 2022-03-31 12:33:56.485701120 +0100
--- src/testdir/test_terminal.vim 2022-05-20 09:28:30.155063608 +0100
***************
*** 2012,2021 ****
--- 2012,2027 ----
CheckFeature termguicolors
CheckFunction term_getansicolors

+ if has('vtp') && !has('vcon') && !has('gui_running')
+ throw 'Skipped: does not support termguicolors'
+ endif
+
+ set tgc
let g:terminal_ansi_colors = reverse(copy(s:test_colors))
let buf = Run_shell_in_terminal({})
call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf))
call StopShellInTerminal(buf)
+ set tgc&

exe buf . 'bwipe'
unlet g:terminal_ansi_colors
***************
*** 2025,2030 ****
--- 2031,2041 ----
CheckFeature termguicolors
CheckFunction term_getansicolors

+ if has('vtp') && !has('vcon') && !has('gui_running')
+ throw 'Skipped: does not support termguicolors'
+ endif
+
+ set tgc
let g:terminal_ansi_colors = reverse(copy(s:test_colors))
let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors})
call assert_equal(s:test_colors, term_getansicolors(buf))
***************
*** 2047,2052 ****
--- 2058,2064 ----
let colors[4] = 'Invalid'
call assert_fails('call term_setansicolors(buf, colors)', 'E254:')
call assert_fails('call term_setansicolors(buf, {})', 'E714:')
+ set tgc&

call StopShellInTerminal(buf)
call assert_equal(0, term_setansicolors(buf, []))
*** ../vim-8.2.4981/src/version.c 2022-05-19 10:31:06.969630503 +0100
--- src/version.c 2022-05-20 09:30:53.815480276 +0100
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 4982,
/**/

--
hundred-and-one symptoms of being an internet addict:
237. You tattoo your email address on your forehead.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages