comparison 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
comparison
equal deleted inserted replaced
19796:dd865be96964 19797:d73d982499ae
146 146
147 garray_T tl_scrollback; 147 garray_T tl_scrollback;
148 int tl_scrollback_scrolled; 148 int tl_scrollback_scrolled;
149 garray_T tl_scrollback_postponed; 149 garray_T tl_scrollback_postponed;
150 150
151 char_u *tl_highlight_name; // replaces "Terminal"; allocated
152
151 cellattr_T tl_default_color; 153 cellattr_T tl_default_color;
152 154
153 linenr_T tl_top_diff_rows; // rows of top diff file or zero 155 linenr_T tl_top_diff_rows; // rows of top diff file or zero
154 linenr_T tl_bot_diff_rows; // rows of bottom diff file 156 linenr_T tl_bot_diff_rows; // rows of bottom diff file
155 157
662 664
663 term->tl_api = vim_strnsave(opt->jo_term_api, p - opt->jo_term_api); 665 term->tl_api = vim_strnsave(opt->jo_term_api, p - opt->jo_term_api);
664 } 666 }
665 else 667 else
666 term->tl_api = vim_strsave((char_u *)"Tapi_"); 668 term->tl_api = vim_strsave((char_u *)"Tapi_");
669
670 if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
671 term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
667 672
668 // System dependent: setup the vterm and maybe start the job in it. 673 // System dependent: setup the vterm and maybe start the job in it.
669 if (argv == NULL 674 if (argv == NULL
670 && argvar->v_type == VAR_STRING 675 && argvar->v_type == VAR_STRING
671 && argvar->vval.v_string != NULL 676 && argvar->vval.v_string != NULL
1022 vim_free(term->tl_arg0_cmd); 1027 vim_free(term->tl_arg0_cmd);
1023 #ifdef MSWIN 1028 #ifdef MSWIN
1024 if (term->tl_out_fd != NULL) 1029 if (term->tl_out_fd != NULL)
1025 fclose(term->tl_out_fd); 1030 fclose(term->tl_out_fd);
1026 #endif 1031 #endif
1032 vim_free(term->tl_highlight_name);
1027 vim_free(term->tl_cursor_color); 1033 vim_free(term->tl_cursor_color);
1028 vim_free(term); 1034 vim_free(term);
1029 } 1035 }
1030 } 1036 }
1031 1037
2213 terminal_is_active() 2219 terminal_is_active()
2214 { 2220 {
2215 return in_terminal_loop != NULL; 2221 return in_terminal_loop != NULL;
2216 } 2222 }
2217 2223
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
2218 #if defined(FEAT_GUI) || defined(PROTO) 2235 #if defined(FEAT_GUI) || defined(PROTO)
2219 cursorentry_T * 2236 cursorentry_T *
2220 term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg) 2237 term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
2221 { 2238 {
2222 term_T *term = in_terminal_loop; 2239 term_T *term = in_terminal_loop;
2235 entry.blinkwait = 700; 2252 entry.blinkwait = 700;
2236 entry.blinkon = 400; 2253 entry.blinkon = 400;
2237 entry.blinkoff = 250; 2254 entry.blinkoff = 250;
2238 } 2255 }
2239 2256
2240 // The "Terminal" highlight group overrules the defaults. 2257 // The highlight group overrules the defaults.
2241 id = syn_name2id((char_u *)"Terminal"); 2258 id = syn_name2id(term_get_highlight_name(term));
2242 if (id != 0) 2259 if (id != 0)
2243 { 2260 {
2244 syn_id2colors(id, &term_fg, &term_bg); 2261 syn_id2colors(id, &term_fg, &term_bg);
2245 *fg = term_bg; 2262 *fg = term_bg;
2246 } 2263 }
2616 cursor_off(); 2633 cursor_off();
2617 } 2634 }
2618 } 2635 }
2619 2636
2620 /* 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
2679 /*
2621 * Reverse engineer the RGB value into a cterm color index. 2680 * Reverse engineer the RGB value into a cterm color index.
2622 * First color is 1. Return 0 if no match found (default color). 2681 * First color is 1. Return 0 if no match found (default color).
2623 */ 2682 */
2624 static int 2683 static int
2625 color2index(VTermColor *color, int fg, int *boldp) 2684 color2index(VTermColor *color, int fg, int *boldp)
2736 /* 2795 /*
2737 * Convert the attributes of a vterm cell into an attribute index. 2796 * Convert the attributes of a vterm cell into an attribute index.
2738 */ 2797 */
2739 static int 2798 static int
2740 cell2attr( 2799 cell2attr(
2800 term_T *term,
2741 win_T *wp, 2801 win_T *wp,
2742 VTermScreenCellAttrs cellattrs, 2802 VTermScreenCellAttrs cellattrs,
2743 VTermColor cellfg, 2803 VTermColor cellfg,
2744 VTermColor cellbg) 2804 VTermColor cellbg)
2745 { 2805 {
2790 } 2850 }
2791 if (fg == 0) 2851 if (fg == 0)
2792 { 2852 {
2793 if (wincolor_fg >= 0) 2853 if (wincolor_fg >= 0)
2794 fg = wincolor_fg + 1; 2854 fg = wincolor_fg + 1;
2795 else if (term_default_cterm_fg >= 0) 2855 else
2796 fg = term_default_cterm_fg + 1; 2856 {
2857 int cterm_fg = get_default_cterm_fg(term);
2858
2859 if (cterm_fg >= 0)
2860 fg = cterm_fg + 1;
2861 }
2797 } 2862 }
2798 if (bg == 0) 2863 if (bg == 0)
2799 { 2864 {
2800 if (wincolor_bg >= 0) 2865 if (wincolor_bg >= 0)
2801 bg = wincolor_bg + 1; 2866 bg = wincolor_bg + 1;
2802 else if (term_default_cterm_bg >= 0) 2867 else
2803 bg = term_default_cterm_bg + 1; 2868 {
2869 int cterm_bg = get_default_cterm_bg(term);
2870
2871 if (cterm_bg >= 0)
2872 bg = cterm_bg + 1;
2873 }
2804 } 2874 }
2805 } 2875 }
2806 2876
2807 // with 8 colors set the bold attribute to get a bright foreground 2877 // with 8 colors set the bold attribute to get a bright foreground
2808 if (bold == TRUE) 2878 if (bold == TRUE)
2854 if (wp->w_buffer == term->tl_buffer) 2924 if (wp->w_buffer == term->tl_buffer)
2855 { 2925 {
2856 // Set the color to clear lines with. 2926 // Set the color to clear lines with.
2857 vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), 2927 vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
2858 &fg, &bg); 2928 &fg, &bg);
2859 clear_attr = cell2attr(wp, attr, fg, bg); 2929 clear_attr = cell2attr(term, wp, attr, fg, bg);
2860 win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr); 2930 win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
2861 } 2931 }
2862 } 2932 }
2863 } 2933 }
2864 2934
3414 * Fill one screen line from a line of the terminal. 3484 * Fill one screen line from a line of the terminal.
3415 * Advances "pos" to past the last column. 3485 * Advances "pos" to past the last column.
3416 */ 3486 */
3417 static void 3487 static void
3418 term_line2screenline( 3488 term_line2screenline(
3489 term_T *term,
3419 win_T *wp, 3490 win_T *wp,
3420 VTermScreen *screen, 3491 VTermScreen *screen,
3421 VTermPos *pos, 3492 VTermPos *pos,
3422 int max_col) 3493 int max_col)
3423 { 3494 {
3482 } 3553 }
3483 #endif 3554 #endif
3484 else 3555 else
3485 ScreenLines[off] = c; 3556 ScreenLines[off] = c;
3486 } 3557 }
3487 ScreenAttrs[off] = cell2attr(wp, cell.attrs, cell.fg, cell.bg); 3558 ScreenAttrs[off] = cell2attr(term, wp, cell.attrs, cell.fg, cell.bg);
3488 3559
3489 ++pos->col; 3560 ++pos->col;
3490 ++off; 3561 ++off;
3491 if (cell.width == 2) 3562 if (cell.width == 2)
3492 { 3563 {
3533 { 3604 {
3534 if (pos.row < term->tl_rows) 3605 if (pos.row < term->tl_rows)
3535 { 3606 {
3536 int max_col = MIN(Columns, term->tl_cols); 3607 int max_col = MIN(Columns, term->tl_cols);
3537 3608
3538 term_line2screenline(NULL, screen, &pos, max_col); 3609 term_line2screenline(term, NULL, screen, &pos, max_col);
3539 } 3610 }
3540 else 3611 else
3541 pos.col = 0; 3612 pos.col = 0;
3542 3613
3543 screen_line(term->tl_toprow + pos.row, 0, pos.col, Columns, 0); 3614 screen_line(term->tl_toprow + pos.row, 0, pos.col, Columns, 0);
3647 { 3718 {
3648 if (pos.row < term->tl_rows) 3719 if (pos.row < term->tl_rows)
3649 { 3720 {
3650 int max_col = MIN(wp->w_width, term->tl_cols); 3721 int max_col = MIN(wp->w_width, term->tl_cols);
3651 3722
3652 term_line2screenline(wp, screen, &pos, max_col); 3723 term_line2screenline(term, wp, screen, &pos, max_col);
3653 } 3724 }
3654 else 3725 else
3655 pos.col = 0; 3726 pos.col = 0;
3656 3727
3657 screen_line(wp->w_winrow + pos.row 3728 screen_line(wp->w_winrow + pos.row
3730 if (col < 0 || col >= line->sb_cols) 3801 if (col < 0 || col >= line->sb_cols)
3731 cellattr = &line->sb_fill_attr; 3802 cellattr = &line->sb_fill_attr;
3732 else 3803 else
3733 cellattr = line->sb_cells + col; 3804 cellattr = line->sb_cells + col;
3734 } 3805 }
3735 return cell2attr(wp, cellattr->attrs, cellattr->fg, cellattr->bg); 3806 return cell2attr(term, wp, cellattr->attrs, cellattr->fg, cellattr->bg);
3736 } 3807 }
3737 3808
3738 /* 3809 /*
3739 * Convert a cterm color number 0 - 255 to RGB. 3810 * Convert a cterm color number 0 - 255 to RGB.
3740 * This is compatible with xterm. 3811 * This is compatible with xterm.
3774 } 3845 }
3775 fg->red = fg->green = fg->blue = fgval; 3846 fg->red = fg->green = fg->blue = fgval;
3776 bg->red = bg->green = bg->blue = bgval; 3847 bg->red = bg->green = bg->blue = bgval;
3777 fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT; 3848 fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT;
3778 3849
3779 // The 'wincolor' or "Terminal" highlight group overrules the defaults. 3850 // The 'wincolor' or the highlight group overrules the defaults.
3780 if (wp != NULL && *wp->w_p_wcr != NUL) 3851 if (wp != NULL && *wp->w_p_wcr != NUL)
3781 id = syn_name2id(wp->w_p_wcr); 3852 id = syn_name2id(wp->w_p_wcr);
3782 else 3853 else
3783 id = syn_name2id((char_u *)"Terminal"); 3854 id = syn_name2id(term_get_highlight_name(term));
3784 3855
3785 // Use the actual color for the GUI and when 'termguicolors' is set. 3856 // Use the actual color for the GUI and when 'termguicolors' is set.
3786 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 3857 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
3787 if (0 3858 if (0
3788 # ifdef FEAT_GUI 3859 # ifdef FEAT_GUI
3842 } 3913 }
3843 else 3914 else
3844 #endif 3915 #endif
3845 if (id != 0 && t_colors >= 16) 3916 if (id != 0 && t_colors >= 16)
3846 { 3917 {
3847 if (term_default_cterm_fg >= 0) 3918 int cterm_fg = get_default_cterm_fg(term);
3848 cterm_color2vterm(term_default_cterm_fg, fg); 3919 int cterm_bg = get_default_cterm_bg(term);
3849 if (term_default_cterm_bg >= 0) 3920
3850 cterm_color2vterm(term_default_cterm_bg, bg); 3921 if (cterm_fg >= 0)
3922 cterm_color2vterm(cterm_fg, fg);
3923 if (cterm_bg >= 0)
3924 cterm_color2vterm(cterm_bg, bg);
3851 } 3925 }
3852 else 3926 else
3853 { 3927 {
3854 #if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) 3928 #if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))
3855 int tmp; 3929 int tmp;
4382 tv.v_type = VAR_JOB; 4456 tv.v_type = VAR_JOB;
4383 tv.vval.v_job = term->tl_job; 4457 tv.vval.v_job = term->tl_job;
4384 abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); 4458 abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
4385 } 4459 }
4386 return abort; 4460 return abort;
4387 }
4388
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 } 4461 }
4398 4462
4399 /* 4463 /*
4400 * Get the buffer from the first argument in "argvars". 4464 * Get the buffer from the first argument in "argvars".
4401 * Returns NULL when the buffer is not for a terminal window and logs a message 4465 * Returns NULL when the buffer is not for a terminal window and logs a message
5743 dict_add_string(dcell, "fg", rgb); 5807 dict_add_string(dcell, "fg", rgb);
5744 vim_snprintf((char *)rgb, 8, "#%02x%02x%02x", 5808 vim_snprintf((char *)rgb, 8, "#%02x%02x%02x",
5745 bg.red, bg.green, bg.blue); 5809 bg.red, bg.green, bg.blue);
5746 dict_add_string(dcell, "bg", rgb); 5810 dict_add_string(dcell, "bg", rgb);
5747 5811
5748 dict_add_number(dcell, "attr", cell2attr(NULL, attrs, fg, bg)); 5812 dict_add_number(dcell, "attr", cell2attr(term, NULL, attrs, fg, bg));
5749 dict_add_number(dcell, "width", width); 5813 dict_add_number(dcell, "width", width);
5750 5814
5751 ++pos.col; 5815 ++pos.col;
5752 if (width == 2) 5816 if (width == 2)
5753 ++pos.col; 5817 ++pos.col;
5935 + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK 5999 + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK
5936 + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO, 6000 + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
5937 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD 6001 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
5938 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN 6002 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
5939 + JO2_CWD + JO2_ENV + JO2_EOF_CHARS 6003 + JO2_CWD + JO2_ENV + JO2_EOF_CHARS
5940 + JO2_NORESTORE + JO2_TERM_KILL 6004 + JO2_NORESTORE + JO2_TERM_KILL + JO2_TERM_HIGHLIGHT
5941 + JO2_ANSI_COLORS + JO2_TTY_TYPE + JO2_TERM_API) == FAIL) 6005 + JO2_ANSI_COLORS + JO2_TTY_TYPE + JO2_TERM_API) == FAIL)
5942 return; 6006 return;
5943 6007
5944 buf = term_start(&argvars[0], NULL, &opt, 0); 6008 buf = term_start(&argvars[0], NULL, &opt, 0);
5945 6009
6859 char **argv, 6923 char **argv,
6860 jobopt_T *opt, 6924 jobopt_T *opt,
6861 jobopt_T *orig_opt UNUSED) 6925 jobopt_T *orig_opt UNUSED)
6862 { 6926 {
6863 term->tl_arg0_cmd = NULL; 6927 term->tl_arg0_cmd = NULL;
6928 if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
6929 term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
6864 6930
6865 if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL) 6931 if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
6866 return FAIL; 6932 return FAIL;
6867 6933
6868 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 6934 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)