comparison src/terminal.c @ 13626:ab89131d30e0 v8.0.1685

patch 8.0.1685: can't set ANSI colors of a terminal window commit https://github.com/vim/vim/commit/f59c6e8cee092433d325ba21a107654a8d84f776 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 10 15:59:11 2018 +0200 patch 8.0.1685: can't set ANSI colors of a terminal window Problem: Can't set ANSI colors of a terminal window. Solution: Add term_setansicolors(), term_getansicolors() and g:term_ansi_colors. (Andy Massimino, closes #2747)
author Christian Brabandt <cb@256bit.org>
date Tue, 10 Apr 2018 16:00:09 +0200
parents 429f0eb87d6f
children fd3389d64825
comparison
equal deleted inserted replaced
13625:2caac884de74 13626:ab89131d30e0
36 * that buffer, attributes come from the scrollback buffer tl_scrollback. 36 * that buffer, attributes come from the scrollback buffer tl_scrollback.
37 * When the buffer is changed it is turned into a normal buffer, the attributes 37 * When the buffer is changed it is turned into a normal buffer, the attributes
38 * in tl_scrollback are no longer used. 38 * in tl_scrollback are no longer used.
39 * 39 *
40 * TODO: 40 * TODO:
41 * - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and in
42 * the GUI. #2747
43 * - Win32: Make terminal used for :!cmd in the GUI work better. Allow for 41 * - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
44 * redirection. Probably in call to channel_set_pipes(). 42 * redirection. Probably in call to channel_set_pipes().
45 * - implement term_setsize() 43 * - implement term_setsize()
44 * - add an optional limit for the scrollback size. When reaching it remove
45 * 10% at the start.
46 * - Copy text in the vterm to the Vim buffer once in a while, so that 46 * - Copy text in the vterm to the Vim buffer once in a while, so that
47 * completion works. 47 * completion works.
48 * - in GUI vertical split causes problems. Cursor is flickering. (Hirohito 48 * - in GUI vertical split causes problems. Cursor is flickering. (Hirohito
49 * Higashi, 2017 Sep 19) 49 * Higashi, 2017 Sep 19)
50 * - after resizing windows overlap. (Boris Staletic, #2164) 50 * - after resizing windows overlap. (Boris Staletic, #2164)
62 * - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed) 62 * - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed)
63 * - For the GUI fill termios with default values, perhaps like pangoterm: 63 * - For the GUI fill termios with default values, perhaps like pangoterm:
64 * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 64 * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
65 * - when 'encoding' is not utf-8, or the job is using another encoding, setup 65 * - when 'encoding' is not utf-8, or the job is using another encoding, setup
66 * conversions. 66 * conversions.
67 * - add an optional limit for the scrollback size. When reaching it remove
68 * 10% at the start.
69 */ 67 */
70 68
71 #include "vim.h" 69 #include "vim.h"
72 70
73 #if defined(FEAT_TERMINAL) || defined(PROTO) 71 #if defined(FEAT_TERMINAL) || defined(PROTO)
3139 term_get_bg_color(&bg->red, &bg->green, &bg->blue); 3137 term_get_bg_color(&bg->red, &bg->green, &bg->blue);
3140 # endif 3138 # endif
3141 } 3139 }
3142 } 3140 }
3143 3141
3142 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
3143 /*
3144 * Set the 16 ANSI colors from array of RGB values
3145 */
3146 static void
3147 set_vterm_palette(VTerm *vterm, long_u *rgb)
3148 {
3149 int index = 0;
3150 VTermState *state = vterm_obtain_state(vterm);
3151 for (; index < 16; index++)
3152 {
3153 VTermColor color;
3154 color.red = (unsigned)(rgb[index] >> 16);
3155 color.green = (unsigned)(rgb[index] >> 8) & 255;
3156 color.blue = (unsigned)rgb[index] & 255;
3157 vterm_state_set_palette_color(state, index, &color);
3158 }
3159 }
3160
3161 /*
3162 * Set the ANSI color palette from a list of colors
3163 */
3164 static int
3165 set_ansi_colors_list(VTerm *vterm, list_T *list)
3166 {
3167 int n = 0;
3168 long_u rgb[16];
3169 listitem_T *li = list->lv_first;
3170
3171 for (; li != NULL && n < 16; li = li->li_next, n++)
3172 {
3173 char_u *color_name;
3174 guicolor_T guicolor;
3175
3176 color_name = get_tv_string_chk(&li->li_tv);
3177 if (color_name == NULL)
3178 return FAIL;
3179
3180 guicolor = GUI_GET_COLOR(color_name);
3181 if (guicolor == INVALCOLOR)
3182 return FAIL;
3183
3184 rgb[n] = GUI_MCH_GET_RGB(guicolor);
3185 }
3186
3187 if (n != 16 || li != NULL)
3188 return FAIL;
3189
3190 set_vterm_palette(vterm, rgb);
3191
3192 return OK;
3193 }
3194
3195 /*
3196 * Initialize the ANSI color palette from g:terminal_ansi_colors[0:15]
3197 */
3198 static void
3199 init_vterm_ansi_colors(VTerm *vterm)
3200 {
3201 dictitem_T *var = find_var((char_u *)"g:terminal_ansi_colors", NULL, TRUE);
3202
3203 if (var != NULL
3204 && (var->di_tv.v_type != VAR_LIST
3205 || var->di_tv.vval.v_list == NULL
3206 || set_ansi_colors_list(vterm, var->di_tv.vval.v_list) == FAIL))
3207 EMSG2(_(e_invarg2), "g:terminal_ansi_colors");
3208 }
3209 #endif
3210
3144 /* 3211 /*
3145 * Handles a "drop" command from the job in the terminal. 3212 * Handles a "drop" command from the job in the terminal.
3146 * "item" is the file name, "item->li_next" may have options. 3213 * "item" is the file name, "item->li_next" may have options.
3147 */ 3214 */
3148 static void 3215 static void
3369 3436
3370 vterm_state_set_default_colors( 3437 vterm_state_set_default_colors(
3371 vterm_obtain_state(vterm), 3438 vterm_obtain_state(vterm),
3372 &term->tl_default_color.fg, 3439 &term->tl_default_color.fg,
3373 &term->tl_default_color.bg); 3440 &term->tl_default_color.bg);
3441
3442 if (t_colors >= 16)
3443 vterm_state_set_bold_highbright(vterm_obtain_state(vterm), 1);
3374 3444
3375 /* Required to initialize most things. */ 3445 /* Required to initialize most things. */
3376 vterm_screen_reset(screen, 1 /* hard */); 3446 vterm_screen_reset(screen, 1 /* hard */);
3377 3447
3378 /* Allow using alternate screen. */ 3448 /* Allow using alternate screen. */
4760 send_keys_to_term(term, PTR2CHAR(msg), FALSE); 4830 send_keys_to_term(term, PTR2CHAR(msg), FALSE);
4761 msg += MB_CPTR2LEN(msg); 4831 msg += MB_CPTR2LEN(msg);
4762 } 4832 }
4763 } 4833 }
4764 4834
4835 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
4836 /*
4837 * "term_getansicolors(buf)" function
4838 */
4839 void
4840 f_term_getansicolors(typval_T *argvars, typval_T *rettv)
4841 {
4842 buf_T *buf = term_get_buf(argvars, "term_getansicolors()");
4843 term_T *term;
4844 VTermState *state;
4845 VTermColor color;
4846 char_u hexbuf[10];
4847 int index;
4848 list_T *list;
4849
4850 if (rettv_list_alloc(rettv) == FAIL)
4851 return;
4852
4853 if (buf == NULL)
4854 return;
4855 term = buf->b_term;
4856 if (term->tl_vterm == NULL)
4857 return;
4858
4859 list = rettv->vval.v_list;
4860 state = vterm_obtain_state(term->tl_vterm);
4861 for (index = 0; index < 16; index++)
4862 {
4863 vterm_state_get_palette_color(state, index, &color);
4864 sprintf((char *)hexbuf, "#%02x%02x%02x",
4865 color.red, color.green, color.blue);
4866 if (list_append_string(list, hexbuf, 7) == FAIL)
4867 return;
4868 }
4869 }
4870
4871 /*
4872 * "term_setansicolors(buf, list)" function
4873 */
4874 void
4875 f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
4876 {
4877 buf_T *buf = term_get_buf(argvars, "term_setansicolors()");
4878 term_T *term;
4879
4880 if (buf == NULL)
4881 return;
4882 term = buf->b_term;
4883 if (term->tl_vterm == NULL)
4884 return;
4885
4886 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
4887 {
4888 EMSG(_(e_listreq));
4889 return;
4890 }
4891
4892 if (set_ansi_colors_list(term->tl_vterm, argvars[1].vval.v_list) == FAIL)
4893 EMSG(_(e_invarg));
4894 }
4895 #endif
4896
4765 /* 4897 /*
4766 * "term_setrestore(buf, command)" function 4898 * "term_setrestore(buf, command)" function
4767 */ 4899 */
4768 void 4900 void
4769 f_term_setrestore(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 4901 f_term_setrestore(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
4822 + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK 4954 + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK
4823 + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO, 4955 + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
4824 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD 4956 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
4825 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN 4957 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
4826 + JO2_CWD + JO2_ENV + JO2_EOF_CHARS 4958 + JO2_CWD + JO2_ENV + JO2_EOF_CHARS
4827 + JO2_NORESTORE + JO2_TERM_KILL) == FAIL) 4959 + JO2_NORESTORE + JO2_TERM_KILL
4960 + JO2_ANSI_COLORS) == FAIL)
4828 return; 4961 return;
4829 4962
4830 buf = term_start(&argvars[0], NULL, &opt, 0); 4963 buf = term_start(&argvars[0], NULL, &opt, 0);
4831 4964
4832 if (buf != NULL && buf->b_term != NULL) 4965 if (buf != NULL && buf->b_term != NULL)
5150 vim_free(cwd_wchar); 5283 vim_free(cwd_wchar);
5151 vim_free(env_wchar); 5284 vim_free(env_wchar);
5152 5285
5153 create_vterm(term, term->tl_rows, term->tl_cols); 5286 create_vterm(term, term->tl_rows, term->tl_cols);
5154 5287
5288 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
5289 if (opt->jo_set2 & JO2_ANSI_COLORS)
5290 set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
5291 else
5292 init_vterm_ansi_colors(term->tl_vterm);
5293 #endif
5294
5155 channel_set_job(channel, job, opt); 5295 channel_set_job(channel, job, opt);
5156 job_set_options(job, opt); 5296 job_set_options(job, opt);
5157 5297
5158 job->jv_channel = channel; 5298 job->jv_channel = channel;
5159 job->jv_proc_info.hProcess = child_process_handle; 5299 job->jv_proc_info.hProcess = child_process_handle;
5322 char **argv, 5462 char **argv,
5323 jobopt_T *opt) 5463 jobopt_T *opt)
5324 { 5464 {
5325 create_vterm(term, term->tl_rows, term->tl_cols); 5465 create_vterm(term, term->tl_rows, term->tl_cols);
5326 5466
5467 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
5468 if (opt->jo_set2 & JO2_ANSI_COLORS)
5469 set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
5470 else
5471 init_vterm_ansi_colors(term->tl_vterm);
5472 #endif
5473
5327 /* This may change a string in "argvar". */ 5474 /* This may change a string in "argvar". */
5328 term->tl_job = job_start(argvar, argv, opt); 5475 term->tl_job = job_start(argvar, argv, opt);
5329 if (term->tl_job != NULL) 5476 if (term->tl_job != NULL)
5330 ++term->tl_job->jv_refcount; 5477 ++term->tl_job->jv_refcount;
5331 5478