Mercurial > vim
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) |