mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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)
This commit is contained in:
parent
3ed9efc2b1
commit
83d4790a04
@ -1,4 +1,4 @@
|
||||
*terminal.txt* For Vim version 8.2. Last change: 2020 Jan 30
|
||||
*terminal.txt* For Vim version 8.2. Last change: 2020 Mar 26
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -148,7 +148,12 @@ terminal window will start with a white or black background.
|
||||
To use a different color the Terminal highlight group can be used, for
|
||||
example: >
|
||||
hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue
|
||||
<
|
||||
The highlight needs to be defined before the terminal is created. Doing it
|
||||
later, or setting 'wincolor', will only have effect when the program running
|
||||
in the terminal displays text or clears the terminal.
|
||||
Instead of Terminal another group can be specified with the "term_highlight"
|
||||
option for `term_start()`.
|
||||
|
||||
*g:terminal_ansi_colors*
|
||||
In GUI mode or with 'termguicolors', the 16 ANSI colors used by default in new
|
||||
terminal windows may be configured using the variable
|
||||
@ -857,6 +862,8 @@ term_start({cmd} [, {options}]) *term_start()*
|
||||
have "%d" where the buffer number goes,
|
||||
e.g. "10split|buffer %d"; when not
|
||||
specified "botright sbuf %d" is used
|
||||
"term_highlight" highlight group to use instead of
|
||||
"Terminal"
|
||||
"eof_chars" Text to send after all buffer lines were
|
||||
written to the terminal. When not set
|
||||
CTRL-D is used on MS-Windows. For Python
|
||||
|
@ -5168,6 +5168,21 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
|
||||
memcpy(opt->jo_ansi_colors, rgb, sizeof(rgb));
|
||||
}
|
||||
# endif
|
||||
else if (STRCMP(hi->hi_key, "term_highlight") == 0)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (!(supported2 & JO2_TERM_HIGHLIGHT))
|
||||
break;
|
||||
opt->jo_set2 |= JO2_TERM_HIGHLIGHT;
|
||||
p = tv_get_string_buf_chk(item, opt->jo_term_highlight_buf);
|
||||
if (p == NULL || *p == NUL)
|
||||
{
|
||||
semsg(_(e_invargval), "term_highlight");
|
||||
return FAIL;
|
||||
}
|
||||
opt->jo_term_highlight = p;
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "term_api") == 0)
|
||||
{
|
||||
if (!(supported2 & JO2_TERM_API))
|
||||
|
@ -2071,6 +2071,7 @@ struct channel_S {
|
||||
#define JO2_TTY_TYPE 0x10000 // "tty_type"
|
||||
#define JO2_BUFNR 0x20000 // "bufnr"
|
||||
#define JO2_TERM_API 0x40000 // "term_api"
|
||||
#define JO2_TERM_HIGHLIGHT 0x80000 // "highlight"
|
||||
|
||||
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
|
||||
#define JO_CB_ALL \
|
||||
@ -2143,6 +2144,8 @@ typedef struct
|
||||
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
long_u jo_ansi_colors[16];
|
||||
# endif
|
||||
char_u jo_term_highlight_buf[NUMBUFLEN];
|
||||
char_u *jo_term_highlight;
|
||||
int jo_tty_type; // first character of "tty_type"
|
||||
char_u jo_term_api_buf[NUMBUFLEN];
|
||||
char_u *jo_term_api;
|
||||
|
124
src/terminal.c
124
src/terminal.c
@ -148,6 +148,8 @@ struct terminal_S {
|
||||
int tl_scrollback_scrolled;
|
||||
garray_T tl_scrollback_postponed;
|
||||
|
||||
char_u *tl_highlight_name; // replaces "Terminal"; allocated
|
||||
|
||||
cellattr_T tl_default_color;
|
||||
|
||||
linenr_T tl_top_diff_rows; // rows of top diff file or zero
|
||||
@ -665,6 +667,9 @@ term_start(
|
||||
else
|
||||
term->tl_api = vim_strsave((char_u *)"Tapi_");
|
||||
|
||||
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
|
||||
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
|
||||
|
||||
// System dependent: setup the vterm and maybe start the job in it.
|
||||
if (argv == NULL
|
||||
&& argvar->v_type == VAR_STRING
|
||||
@ -1024,6 +1029,7 @@ free_unused_terminals()
|
||||
if (term->tl_out_fd != NULL)
|
||||
fclose(term->tl_out_fd);
|
||||
#endif
|
||||
vim_free(term->tl_highlight_name);
|
||||
vim_free(term->tl_cursor_color);
|
||||
vim_free(term);
|
||||
}
|
||||
@ -2215,6 +2221,17 @@ terminal_is_active()
|
||||
return in_terminal_loop != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the highight group name for the terminal; "Terminal" if not set.
|
||||
*/
|
||||
static char_u *
|
||||
term_get_highlight_name(term_T *term)
|
||||
{
|
||||
if (term->tl_highlight_name == NULL)
|
||||
return (char_u *)"Terminal";
|
||||
return term->tl_highlight_name;
|
||||
}
|
||||
|
||||
#if defined(FEAT_GUI) || defined(PROTO)
|
||||
cursorentry_T *
|
||||
term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
|
||||
@ -2237,8 +2254,8 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
|
||||
entry.blinkoff = 250;
|
||||
}
|
||||
|
||||
// The "Terminal" highlight group overrules the defaults.
|
||||
id = syn_name2id((char_u *)"Terminal");
|
||||
// The highlight group overrules the defaults.
|
||||
id = syn_name2id(term_get_highlight_name(term));
|
||||
if (id != 0)
|
||||
{
|
||||
syn_id2colors(id, &term_fg, &term_bg);
|
||||
@ -2617,6 +2634,48 @@ may_toggle_cursor(term_T *term)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache "Terminal" highlight group colors.
|
||||
*/
|
||||
void
|
||||
set_terminal_default_colors(int cterm_fg, int cterm_bg)
|
||||
{
|
||||
term_default_cterm_fg = cterm_fg - 1;
|
||||
term_default_cterm_bg = cterm_bg - 1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_default_cterm_fg(term_T *term)
|
||||
{
|
||||
if (term->tl_highlight_name != NULL)
|
||||
{
|
||||
int id = syn_name2id(term->tl_highlight_name);
|
||||
int fg = -1;
|
||||
int bg = -1;
|
||||
|
||||
if (id > 0)
|
||||
syn_id2cterm_bg(id, &fg, &bg);
|
||||
return fg;
|
||||
}
|
||||
return term_default_cterm_fg;
|
||||
}
|
||||
|
||||
static int
|
||||
get_default_cterm_bg(term_T *term)
|
||||
{
|
||||
if (term->tl_highlight_name != NULL)
|
||||
{
|
||||
int id = syn_name2id(term->tl_highlight_name);
|
||||
int fg = -1;
|
||||
int bg = -1;
|
||||
|
||||
if (id > 0)
|
||||
syn_id2cterm_bg(id, &fg, &bg);
|
||||
return bg;
|
||||
}
|
||||
return term_default_cterm_bg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reverse engineer the RGB value into a cterm color index.
|
||||
* First color is 1. Return 0 if no match found (default color).
|
||||
@ -2738,6 +2797,7 @@ hl2vtermAttr(int attr, cellattr_T *cell)
|
||||
*/
|
||||
static int
|
||||
cell2attr(
|
||||
term_T *term,
|
||||
win_T *wp,
|
||||
VTermScreenCellAttrs cellattrs,
|
||||
VTermColor cellfg,
|
||||
@ -2792,15 +2852,25 @@ cell2attr(
|
||||
{
|
||||
if (wincolor_fg >= 0)
|
||||
fg = wincolor_fg + 1;
|
||||
else if (term_default_cterm_fg >= 0)
|
||||
fg = term_default_cterm_fg + 1;
|
||||
else
|
||||
{
|
||||
int cterm_fg = get_default_cterm_fg(term);
|
||||
|
||||
if (cterm_fg >= 0)
|
||||
fg = cterm_fg + 1;
|
||||
}
|
||||
}
|
||||
if (bg == 0)
|
||||
{
|
||||
if (wincolor_bg >= 0)
|
||||
bg = wincolor_bg + 1;
|
||||
else if (term_default_cterm_bg >= 0)
|
||||
bg = term_default_cterm_bg + 1;
|
||||
else
|
||||
{
|
||||
int cterm_bg = get_default_cterm_bg(term);
|
||||
|
||||
if (cterm_bg >= 0)
|
||||
bg = cterm_bg + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2856,7 +2926,7 @@ term_scroll_up(term_T *term, int start_row, int count)
|
||||
// Set the color to clear lines with.
|
||||
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
|
||||
&fg, &bg);
|
||||
clear_attr = cell2attr(wp, attr, fg, bg);
|
||||
clear_attr = cell2attr(term, wp, attr, fg, bg);
|
||||
win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
|
||||
}
|
||||
}
|
||||
@ -3416,6 +3486,7 @@ term_check_channel_closed_recently()
|
||||
*/
|
||||
static void
|
||||
term_line2screenline(
|
||||
term_T *term,
|
||||
win_T *wp,
|
||||
VTermScreen *screen,
|
||||
VTermPos *pos,
|
||||
@ -3484,7 +3555,7 @@ term_line2screenline(
|
||||
else
|
||||
ScreenLines[off] = c;
|
||||
}
|
||||
ScreenAttrs[off] = cell2attr(wp, cell.attrs, cell.fg, cell.bg);
|
||||
ScreenAttrs[off] = cell2attr(term, wp, cell.attrs, cell.fg, cell.bg);
|
||||
|
||||
++pos->col;
|
||||
++off;
|
||||
@ -3535,7 +3606,7 @@ update_system_term(term_T *term)
|
||||
{
|
||||
int max_col = MIN(Columns, term->tl_cols);
|
||||
|
||||
term_line2screenline(NULL, screen, &pos, max_col);
|
||||
term_line2screenline(term, NULL, screen, &pos, max_col);
|
||||
}
|
||||
else
|
||||
pos.col = 0;
|
||||
@ -3649,7 +3720,7 @@ term_update_window(win_T *wp)
|
||||
{
|
||||
int max_col = MIN(wp->w_width, term->tl_cols);
|
||||
|
||||
term_line2screenline(wp, screen, &pos, max_col);
|
||||
term_line2screenline(term, wp, screen, &pos, max_col);
|
||||
}
|
||||
else
|
||||
pos.col = 0;
|
||||
@ -3732,7 +3803,7 @@ term_get_attr(win_T *wp, linenr_T lnum, int col)
|
||||
else
|
||||
cellattr = line->sb_cells + col;
|
||||
}
|
||||
return cell2attr(wp, cellattr->attrs, cellattr->fg, cellattr->bg);
|
||||
return cell2attr(term, wp, cellattr->attrs, cellattr->fg, cellattr->bg);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3776,11 +3847,11 @@ init_default_colors(term_T *term, win_T *wp)
|
||||
bg->red = bg->green = bg->blue = bgval;
|
||||
fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT;
|
||||
|
||||
// The 'wincolor' or "Terminal" highlight group overrules the defaults.
|
||||
// The 'wincolor' or the highlight group overrules the defaults.
|
||||
if (wp != NULL && *wp->w_p_wcr != NUL)
|
||||
id = syn_name2id(wp->w_p_wcr);
|
||||
else
|
||||
id = syn_name2id((char_u *)"Terminal");
|
||||
id = syn_name2id(term_get_highlight_name(term));
|
||||
|
||||
// Use the actual color for the GUI and when 'termguicolors' is set.
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
@ -3844,10 +3915,13 @@ init_default_colors(term_T *term, win_T *wp)
|
||||
#endif
|
||||
if (id != 0 && t_colors >= 16)
|
||||
{
|
||||
if (term_default_cterm_fg >= 0)
|
||||
cterm_color2vterm(term_default_cterm_fg, fg);
|
||||
if (term_default_cterm_bg >= 0)
|
||||
cterm_color2vterm(term_default_cterm_bg, bg);
|
||||
int cterm_fg = get_default_cterm_fg(term);
|
||||
int cterm_bg = get_default_cterm_bg(term);
|
||||
|
||||
if (cterm_fg >= 0)
|
||||
cterm_color2vterm(cterm_fg, fg);
|
||||
if (cterm_bg >= 0)
|
||||
cterm_color2vterm(cterm_bg, bg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4386,16 +4460,6 @@ set_ref_in_term(int copyID)
|
||||
return abort;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache "Terminal" highlight group colors.
|
||||
*/
|
||||
void
|
||||
set_terminal_default_colors(int cterm_fg, int cterm_bg)
|
||||
{
|
||||
term_default_cterm_fg = cterm_fg - 1;
|
||||
term_default_cterm_bg = cterm_bg - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the buffer from the first argument in "argvars".
|
||||
* 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)
|
||||
bg.red, bg.green, bg.blue);
|
||||
dict_add_string(dcell, "bg", rgb);
|
||||
|
||||
dict_add_number(dcell, "attr", cell2attr(NULL, attrs, fg, bg));
|
||||
dict_add_number(dcell, "attr", cell2attr(term, NULL, attrs, fg, bg));
|
||||
dict_add_number(dcell, "width", width);
|
||||
|
||||
++pos.col;
|
||||
@ -5937,7 +6001,7 @@ f_term_start(typval_T *argvars, typval_T *rettv)
|
||||
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
|
||||
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
|
||||
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS
|
||||
+ JO2_NORESTORE + JO2_TERM_KILL
|
||||
+ JO2_NORESTORE + JO2_TERM_KILL + JO2_TERM_HIGHLIGHT
|
||||
+ JO2_ANSI_COLORS + JO2_TTY_TYPE + JO2_TERM_API) == FAIL)
|
||||
return;
|
||||
|
||||
@ -6861,6 +6925,8 @@ term_and_job_init(
|
||||
jobopt_T *orig_opt UNUSED)
|
||||
{
|
||||
term->tl_arg0_cmd = NULL;
|
||||
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
|
||||
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
|
||||
|
||||
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
|
||||
return FAIL;
|
||||
|
15
src/testdir/dumps/Test_terminal_popup_MyTermCol.dump
Normal file
15
src/testdir/dumps/Test_terminal_popup_MyTermCol.dump
Normal file
@ -0,0 +1,15 @@
|
||||
|0+0&#ffffff0| @73
|
||||
|1| @73
|
||||
|2| @73
|
||||
|3| @73
|
||||
|4| @24|╔+0#0000001#ffd7ff255|═@19|╗| +0#0000000#ffffff0@26
|
||||
|5| @24|║+0#0000001#ffd7ff255|h+0#00e0003#5fd7ff255|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|6| @24|║+0#0000001#ffd7ff255|h+0#00e0003#5fd7ff255|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|7| @24|║+0#0000001#ffd7ff255> +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|8| @24|║+0#0000001#ffd7ff255| +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|9| @24|║+0#0000001#ffd7ff255| +0#00e0003#5fd7ff255@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|1|0| @23|╚+0#0000001#ffd7ff255|═@19|╝| +0#0000000#ffffff0@26
|
||||
|1@1| @72
|
||||
|1|2| @72
|
||||
|1|3| @72
|
||||
@75
|
15
src/testdir/dumps/Test_terminal_popup_Terminal.dump
Normal file
15
src/testdir/dumps/Test_terminal_popup_Terminal.dump
Normal file
@ -0,0 +1,15 @@
|
||||
|0+0&#ffffff0| @73
|
||||
|1| @73
|
||||
|2| @73
|
||||
|3| @73
|
||||
|4| @24|╔+0#0000001#ffd7ff255|═@19|╗| +0#0000000#ffffff0@26
|
||||
|5| @24|║+0#0000001#ffd7ff255|h+0#4040ff13#ffff4012|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|6| @24|║+0#0000001#ffd7ff255|h+0#4040ff13#ffff4012|e|l@1|o| @14|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|7| @24|║+0#0000001#ffd7ff255> +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|8| @24|║+0#0000001#ffd7ff255| +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|9| @24|║+0#0000001#ffd7ff255| +0#4040ff13#ffff4012@19|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26
|
||||
|1|0| @23|╚+0#0000001#ffd7ff255|═@19|╝| +0#0000000#ffffff0@26
|
||||
|1@1| @72
|
||||
|1|2| @72
|
||||
|1|3| @72
|
||||
@75
|
@ -2434,7 +2434,6 @@ func Test_terminal_in_popup_min_size()
|
||||
let lines = [
|
||||
\ 'set t_u7=',
|
||||
\ 'call setline(1, range(20))',
|
||||
\ 'hi PopTerm ctermbg=grey',
|
||||
\ 'func OpenTerm()',
|
||||
\ " let s:buf = term_start('cat Xtext', #{hidden: 1})",
|
||||
\ ' let g:winid = popup_create(s:buf, #{ border: []})',
|
||||
@ -2457,6 +2456,46 @@ func Test_terminal_in_popup_min_size()
|
||||
call delete('XtermPopup')
|
||||
endfunc
|
||||
|
||||
" Check a terminal in popup window with different colors
|
||||
func Terminal_in_popup_colored(group_name, highlight_cmd, highlight_opt)
|
||||
CheckRunVimInTerminal
|
||||
CheckUnix
|
||||
|
||||
let lines = [
|
||||
\ 'set t_u7=',
|
||||
\ 'call setline(1, range(20))',
|
||||
\ 'func OpenTerm()',
|
||||
\ " let s:buf = term_start('cat', #{hidden: 1, "
|
||||
\ .. a:highlight_opt .. "})",
|
||||
\ ' let g:winid = popup_create(s:buf, #{ border: []})',
|
||||
\ 'endfunc',
|
||||
\ a:highlight_cmd,
|
||||
\ ]
|
||||
call writefile(lines, 'XtermPopup')
|
||||
let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15})
|
||||
call term_wait(buf, 200)
|
||||
call term_sendkeys(buf, ":set noruler\<CR>")
|
||||
call term_sendkeys(buf, ":call OpenTerm()\<CR>")
|
||||
call term_wait(buf, 100)
|
||||
call term_sendkeys(buf, "hello\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_terminal_popup_' .. a:group_name, {})
|
||||
|
||||
call term_sendkeys(buf, "\<C-D>")
|
||||
call term_wait(buf, 100)
|
||||
call term_sendkeys(buf, ":q\<CR>")
|
||||
call term_wait(buf, 100) " wait for terminal to vanish
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XtermPopup')
|
||||
endfunc
|
||||
|
||||
func Test_terminal_in_popup_colored_Terminal()
|
||||
call Terminal_in_popup_colored("Terminal", "highlight Terminal ctermfg=blue ctermbg=yellow", "")
|
||||
endfunc
|
||||
|
||||
func Test_terminal_in_popup_colored_group()
|
||||
call Terminal_in_popup_colored("MyTermCol", "highlight MyTermCol ctermfg=darkgreen ctermbg=lightblue", "term_highlight: 'MyTermCol',")
|
||||
endfunc
|
||||
|
||||
func Test_double_popup_terminal()
|
||||
let buf1 = term_start(&shell, #{hidden: 1})
|
||||
let win1 = popup_create(buf1, {})
|
||||
|
@ -738,6 +738,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
455,
|
||||
/**/
|
||||
454,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user