]> granicus.if.org Git - vim/commitdiff
patch 8.2.0455: cannot set the highlight group for a specific terminal v8.2.0455
authorBram Moolenaar <Bram@vim.org>
Thu, 26 Mar 2020 19:34:00 +0000 (20:34 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 26 Mar 2020 19:34:00 +0000 (20:34 +0100)
Problem:    Cannot set the highlight group for a specific terminal.
Solution:   Add the "highlight" option to term_start(). (closes #5818)

runtime/doc/terminal.txt
src/channel.c
src/structs.h
src/terminal.c
src/testdir/dumps/Test_terminal_popup_MyTermCol.dump [new file with mode: 0644]
src/testdir/dumps/Test_terminal_popup_Terminal.dump [new file with mode: 0644]
src/testdir/test_terminal.vim
src/version.c

index 5c44cd182242d1d12b645e13c3eb6a5670663eb6..ac9d65841218fbe1017e8b104d62f1ed2c8af2b2 100644 (file)
@@ -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
index 15ee0b775232d376ca23a2178dc1b97210d06c6b..d3be7ecd38cdedf533d3fac738ec289a8373119f 100644 (file)
@@ -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))
index ff32cb2c8ebcbbaf34d705320b5ba654ae692d63..9f3628e3ce4b67ea283e9b735ce1e380ebfe5243 100644 (file)
@@ -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;
index 638c27ea65f4db2a9ba9f2bf63fb9321c63c19c3..bc4532900f9c9fa2071acb1c73f224eaa614d806 100644 (file)
@@ -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;
diff --git a/src/testdir/dumps/Test_terminal_popup_MyTermCol.dump b/src/testdir/dumps/Test_terminal_popup_MyTermCol.dump
new file mode 100644 (file)
index 0000000..82fcec7
--- /dev/null
@@ -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
diff --git a/src/testdir/dumps/Test_terminal_popup_Terminal.dump b/src/testdir/dumps/Test_terminal_popup_Terminal.dump
new file mode 100644 (file)
index 0000000..938b419
--- /dev/null
@@ -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
index f3571d4e4bc4f2b091c38ce98681d4a0662c8eb9..c48ff4e26bda16ab1ac78cd961687e9f4b853a95 100644 (file)
@@ -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, {})
index b1e6470ea56d68b0af61fc07c96e8d9042d39e0a..51e9e37062435ccf5fa1d0694b6430f0e2056307 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    455,
 /**/
     454,
 /**/