diff src/terminal.c @ 19797:d73d982499ae v8.2.0455

patch 8.2.0455: cannot set the highlight group for a specific terminal Commit: https://github.com/vim/vim/commit/83d4790a04780328c9c7ad22d18f404a27c11601 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 26 20:34:00 2020 +0100 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 https://github.com/vim/vim/issues/5818)
author Bram Moolenaar <Bram@vim.org>
date Thu, 26 Mar 2020 20:45:03 +0100
parents eb4887dd4b60
children b3f956c2ed3c
line wrap: on
line diff
--- a/src/terminal.c
+++ b/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, gu
 	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);
@@ -2618,6 +2635,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_r
 	    // 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, 
 	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 
     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 
 #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
     {
@@ -4387,16 +4461,6 @@ set_ref_in_term(int copyID)
 }
 
 /*
- * 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
  * with "where".
@@ -5745,7 +5809,7 @@ f_term_scrape(typval_T *argvars, typval_
 				     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
 		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;