Skip to content

Commit 83d4790

Browse files
committed
patch 8.2.0455: cannot set the highlight group for a specific terminal
Problem: Cannot set the highlight group for a specific terminal. Solution: Add the "highlight" option to term_start(). (closes #5818)
1 parent 3ed9efc commit 83d4790

8 files changed

Lines changed: 194 additions & 32 deletions

File tree

runtime/doc/terminal.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*terminal.txt* For Vim version 8.2. Last change: 2020 Jan 30
1+
*terminal.txt* For Vim version 8.2. Last change: 2020 Mar 26
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -148,7 +148,12 @@ terminal window will start with a white or black background.
148148
To use a different color the Terminal highlight group can be used, for
149149
example: >
150150
hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue
151-
<
151+
The highlight needs to be defined before the terminal is created. Doing it
152+
later, or setting 'wincolor', will only have effect when the program running
153+
in the terminal displays text or clears the terminal.
154+
Instead of Terminal another group can be specified with the "term_highlight"
155+
option for `term_start()`.
156+
152157
*g:terminal_ansi_colors*
153158
In GUI mode or with 'termguicolors', the 16 ANSI colors used by default in new
154159
terminal windows may be configured using the variable
@@ -857,6 +862,8 @@ term_start({cmd} [, {options}]) *term_start()*
857862
have "%d" where the buffer number goes,
858863
e.g. "10split|buffer %d"; when not
859864
specified "botright sbuf %d" is used
865+
"term_highlight" highlight group to use instead of
866+
"Terminal"
860867
"eof_chars" Text to send after all buffer lines were
861868
written to the terminal. When not set
862869
CTRL-D is used on MS-Windows. For Python

src/channel.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5168,6 +5168,21 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
51685168
memcpy(opt->jo_ansi_colors, rgb, sizeof(rgb));
51695169
}
51705170
# endif
5171+
else if (STRCMP(hi->hi_key, "term_highlight") == 0)
5172+
{
5173+
char_u *p;
5174+
5175+
if (!(supported2 & JO2_TERM_HIGHLIGHT))
5176+
break;
5177+
opt->jo_set2 |= JO2_TERM_HIGHLIGHT;
5178+
p = tv_get_string_buf_chk(item, opt->jo_term_highlight_buf);
5179+
if (p == NULL || *p == NUL)
5180+
{
5181+
semsg(_(e_invargval), "term_highlight");
5182+
return FAIL;
5183+
}
5184+
opt->jo_term_highlight = p;
5185+
}
51715186
else if (STRCMP(hi->hi_key, "term_api") == 0)
51725187
{
51735188
if (!(supported2 & JO2_TERM_API))

src/structs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,6 +2071,7 @@ struct channel_S {
20712071
#define JO2_TTY_TYPE 0x10000 // "tty_type"
20722072
#define JO2_BUFNR 0x20000 // "bufnr"
20732073
#define JO2_TERM_API 0x40000 // "term_api"
2074+
#define JO2_TERM_HIGHLIGHT 0x80000 // "highlight"
20742075

20752076
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
20762077
#define JO_CB_ALL \
@@ -2143,6 +2144,8 @@ typedef struct
21432144
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
21442145
long_u jo_ansi_colors[16];
21452146
# endif
2147+
char_u jo_term_highlight_buf[NUMBUFLEN];
2148+
char_u *jo_term_highlight;
21462149
int jo_tty_type; // first character of "tty_type"
21472150
char_u jo_term_api_buf[NUMBUFLEN];
21482151
char_u *jo_term_api;

src/terminal.c

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ struct terminal_S {
148148
int tl_scrollback_scrolled;
149149
garray_T tl_scrollback_postponed;
150150

151+
char_u *tl_highlight_name; // replaces "Terminal"; allocated
152+
151153
cellattr_T tl_default_color;
152154

153155
linenr_T tl_top_diff_rows; // rows of top diff file or zero
@@ -665,6 +667,9 @@ term_start(
665667
else
666668
term->tl_api = vim_strsave((char_u *)"Tapi_");
667669

670+
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
671+
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
672+
668673
// System dependent: setup the vterm and maybe start the job in it.
669674
if (argv == NULL
670675
&& argvar->v_type == VAR_STRING
@@ -1024,6 +1029,7 @@ free_unused_terminals()
10241029
if (term->tl_out_fd != NULL)
10251030
fclose(term->tl_out_fd);
10261031
#endif
1032+
vim_free(term->tl_highlight_name);
10271033
vim_free(term->tl_cursor_color);
10281034
vim_free(term);
10291035
}
@@ -2215,6 +2221,17 @@ terminal_is_active()
22152221
return in_terminal_loop != NULL;
22162222
}
22172223

2224+
/*
2225+
* Return the highight group name for the terminal; "Terminal" if not set.
2226+
*/
2227+
static char_u *
2228+
term_get_highlight_name(term_T *term)
2229+
{
2230+
if (term->tl_highlight_name == NULL)
2231+
return (char_u *)"Terminal";
2232+
return term->tl_highlight_name;
2233+
}
2234+
22182235
#if defined(FEAT_GUI) || defined(PROTO)
22192236
cursorentry_T *
22202237
term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
@@ -2237,8 +2254,8 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
22372254
entry.blinkoff = 250;
22382255
}
22392256

2240-
// The "Terminal" highlight group overrules the defaults.
2241-
id = syn_name2id((char_u *)"Terminal");
2257+
// The highlight group overrules the defaults.
2258+
id = syn_name2id(term_get_highlight_name(term));
22422259
if (id != 0)
22432260
{
22442261
syn_id2colors(id, &term_fg, &term_bg);
@@ -2617,6 +2634,48 @@ may_toggle_cursor(term_T *term)
26172634
}
26182635
}
26192636

2637+
/*
2638+
* Cache "Terminal" highlight group colors.
2639+
*/
2640+
void
2641+
set_terminal_default_colors(int cterm_fg, int cterm_bg)
2642+
{
2643+
term_default_cterm_fg = cterm_fg - 1;
2644+
term_default_cterm_bg = cterm_bg - 1;
2645+
}
2646+
2647+
static int
2648+
get_default_cterm_fg(term_T *term)
2649+
{
2650+
if (term->tl_highlight_name != NULL)
2651+
{
2652+
int id = syn_name2id(term->tl_highlight_name);
2653+
int fg = -1;
2654+
int bg = -1;
2655+
2656+
if (id > 0)
2657+
syn_id2cterm_bg(id, &fg, &bg);
2658+
return fg;
2659+
}
2660+
return term_default_cterm_fg;
2661+
}
2662+
2663+
static int
2664+
get_default_cterm_bg(term_T *term)
2665+
{
2666+
if (term->tl_highlight_name != NULL)
2667+
{
2668+
int id = syn_name2id(term->tl_highlight_name);
2669+
int fg = -1;
2670+
int bg = -1;
2671+
2672+
if (id > 0)
2673+
syn_id2cterm_bg(id, &fg, &bg);
2674+
return bg;
2675+
}
2676+
return term_default_cterm_bg;
2677+
}
2678+
26202679
/*
26212680
* Reverse engineer the RGB value into a cterm color index.
26222681
* First color is 1. Return 0 if no match found (default color).
@@ -2738,6 +2797,7 @@ hl2vtermAttr(int attr, cellattr_T *cell)
27382797
*/
27392798
static int
27402799
cell2attr(
2800+
term_T *term,
27412801
win_T *wp,
27422802
VTermScreenCellAttrs cellattrs,
27432803
VTermColor cellfg,
@@ -2792,15 +2852,25 @@ cell2attr(
27922852
{
27932853
if (wincolor_fg >= 0)
27942854
fg = wincolor_fg + 1;
2795-
else if (term_default_cterm_fg >= 0)
2796-
fg = term_default_cterm_fg + 1;
2855+
else
2856+
{
2857+
int cterm_fg = get_default_cterm_fg(term);
2858+
2859+
if (cterm_fg >= 0)
2860+
fg = cterm_fg + 1;
2861+
}
27972862
}
27982863
if (bg == 0)
27992864
{
28002865
if (wincolor_bg >= 0)
28012866
bg = wincolor_bg + 1;
2802-
else if (term_default_cterm_bg >= 0)
2803-
bg = term_default_cterm_bg + 1;
2867+
else
2868+
{
2869+
int cterm_bg = get_default_cterm_bg(term);
2870+
2871+
if (cterm_bg >= 0)
2872+
bg = cterm_bg + 1;
2873+
}
28042874
}
28052875
}
28062876

@@ -2856,7 +2926,7 @@ term_scroll_up(term_T *term, int start_row, int count)
28562926
// Set the color to clear lines with.
28572927
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
28582928
&fg, &bg);
2859-
clear_attr = cell2attr(wp, attr, fg, bg);
2929+
clear_attr = cell2attr(term, wp, attr, fg, bg);
28602930
win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
28612931
}
28622932
}
@@ -3416,6 +3486,7 @@ term_check_channel_closed_recently()
34163486
*/
34173487
static void
34183488
term_line2screenline(
3489+
term_T *term,
34193490
win_T *wp,
34203491
VTermScreen *screen,
34213492
VTermPos *pos,
@@ -3484,7 +3555,7 @@ term_line2screenline(
34843555
else
34853556
ScreenLines[off] = c;
34863557
}
3487-
ScreenAttrs[off] = cell2attr(wp, cell.attrs, cell.fg, cell.bg);
3558+
ScreenAttrs[off] = cell2attr(term, wp, cell.attrs, cell.fg, cell.bg);
34883559

34893560
++pos->col;
34903561
++off;
@@ -3535,7 +3606,7 @@ update_system_term(term_T *term)
35353606
{
35363607
int max_col = MIN(Columns, term->tl_cols);
35373608

3538-
term_line2screenline(NULL, screen, &pos, max_col);
3609+
term_line2screenline(term, NULL, screen, &pos, max_col);
35393610
}
35403611
else
35413612
pos.col = 0;
@@ -3649,7 +3720,7 @@ term_update_window(win_T *wp)
36493720
{
36503721
int max_col = MIN(wp->w_width, term->tl_cols);
36513722

3652-
term_line2screenline(wp, screen, &pos, max_col);
3723+
term_line2screenline(term, wp, screen, &pos, max_col);
36533724
}
36543725
else
36553726
pos.col = 0;
@@ -3732,7 +3803,7 @@ term_get_attr(win_T *wp, linenr_T lnum, int col)
37323803
else
37333804
cellattr = line->sb_cells + col;
37343805
}
3735-
return cell2attr(wp, cellattr->attrs, cellattr->fg, cellattr->bg);
3806+
return cell2attr(term, wp, cellattr->attrs, cellattr->fg, cellattr->bg);
37363807
}
37373808

37383809
/*
@@ -3776,11 +3847,11 @@ init_default_colors(term_T *term, win_T *wp)
37763847
bg->red = bg->green = bg->blue = bgval;
37773848
fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT;
37783849

3779-
// The 'wincolor' or "Terminal" highlight group overrules the defaults.
3850+
// The 'wincolor' or the highlight group overrules the defaults.
37803851
if (wp != NULL && *wp->w_p_wcr != NUL)
37813852
id = syn_name2id(wp->w_p_wcr);
37823853
else
3783-
id = syn_name2id((char_u *)"Terminal");
3854+
id = syn_name2id(term_get_highlight_name(term));
37843855

37853856
// Use the actual color for the GUI and when 'termguicolors' is set.
37863857
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
@@ -3844,10 +3915,13 @@ init_default_colors(term_T *term, win_T *wp)
38443915
#endif
38453916
if (id != 0 && t_colors >= 16)
38463917
{
3847-
if (term_default_cterm_fg >= 0)
3848-
cterm_color2vterm(term_default_cterm_fg, fg);
3849-
if (term_default_cterm_bg >= 0)
3850-
cterm_color2vterm(term_default_cterm_bg, bg);
3918+
int cterm_fg = get_default_cterm_fg(term);
3919+
int cterm_bg = get_default_cterm_bg(term);
3920+
3921+
if (cterm_fg >= 0)
3922+
cterm_color2vterm(cterm_fg, fg);
3923+
if (cterm_bg >= 0)
3924+
cterm_color2vterm(cterm_bg, bg);
38513925
}
38523926
else
38533927
{
@@ -4386,16 +4460,6 @@ set_ref_in_term(int copyID)
43864460
return abort;
43874461
}
43884462

4389-
/*
4390-
* Cache "Terminal" highlight group colors.
4391-
*/
4392-
void
4393-
set_terminal_default_colors(int cterm_fg, int cterm_bg)
4394-
{
4395-
term_default_cterm_fg = cterm_fg - 1;
4396-
term_default_cterm_bg = cterm_bg - 1;
4397-
}
4398-
43994463
/*
44004464
* Get the buffer from the first argument in "argvars".
44014465
* Returns NULL when the buffer is not for a terminal window and logs a message
@@ -5745,7 +5809,7 @@ f_term_scrape(typval_T *argvars, typval_T *rettv)
57455809
bg.red, bg.green, bg.blue);
57465810
dict_add_string(dcell, "bg", rgb);
57475811

5748-
dict_add_number(dcell, "attr", cell2attr(NULL, attrs, fg, bg));
5812+
dict_add_number(dcell, "attr", cell2attr(term, NULL, attrs, fg, bg));
57495813
dict_add_number(dcell, "width", width);
57505814

57515815
++pos.col;
@@ -5937,7 +6001,7 @@ f_term_start(typval_T *argvars, typval_T *rettv)
59376001
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
59386002
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
59396003
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS
5940-
+ JO2_NORESTORE + JO2_TERM_KILL
6004+
+ JO2_NORESTORE + JO2_TERM_KILL + JO2_TERM_HIGHLIGHT
59416005
+ JO2_ANSI_COLORS + JO2_TTY_TYPE + JO2_TERM_API) == FAIL)
59426006
return;
59436007

@@ -6861,6 +6925,8 @@ term_and_job_init(
68616925
jobopt_T *orig_opt UNUSED)
68626926
{
68636927
term->tl_arg0_cmd = NULL;
6928+
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
6929+
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
68646930

68656931
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
68666932
return FAIL;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
|0+0&#ffffff0| @73
2+
|1| @73
3+
|2| @73
4+
|3| @73
5+
|4| @24|╔+0#0000001#ffd7ff255|═@19|╗| +0#0000000#ffffff0@26
6+
|5| @24|║+0#0000001#ffd7ff255|h+0#00e0003#5fd7ff255|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
7+
|6| @24|║+0#0000001#ffd7ff255|h+0#00e0003#5fd7ff255|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
8+
|7| @24|║+0#0000001#ffd7ff255> +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
9+
|8| @24|║+0#0000001#ffd7ff255| +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
10+
|9| @24|║+0#0000001#ffd7ff255| +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
11+
|1|0| @23|╚+0#0000001#ffd7ff255|═@19|╝| +0#0000000#ffffff0@26
12+
|1@1| @72
13+
|1|2| @72
14+
|1|3| @72
15+
@75
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
|0+0&#ffffff0| @73
2+
|1| @73
3+
|2| @73
4+
|3| @73
5+
|4| @24|╔+0#0000001#ffd7ff255|═@19|╗| +0#0000000#ffffff0@26
6+
|5| @24|║+0#0000001#ffd7ff255|h+0#4040ff13#ffff4012|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
7+
|6| @24|║+0#0000001#ffd7ff255|h+0#4040ff13#ffff4012|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
8+
|7| @24|║+0#0000001#ffd7ff255> +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
9+
|8| @24|║+0#0000001#ffd7ff255| +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
10+
|9| @24|║+0#0000001#ffd7ff255| +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
11+
|1|0| @23|╚+0#0000001#ffd7ff255|═@19|╝| +0#0000000#ffffff0@26
12+
|1@1| @72
13+
|1|2| @72
14+
|1|3| @72
15+
@75

0 commit comments

Comments
 (0)