Patch 8.0.1685
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)
Files:      runtime/doc/eval.txt, runtime/doc/terminal.txt, src/channel.c,
            src/evalfunc.c, src/proto/terminal.pro, src/structs.h,
            src/terminal.c, src/testdir/test_terminal.vim


*** ../vim-8.0.1684/runtime/doc/eval.txt        2018-03-29 15:55:30.862510255 
+0200
--- runtime/doc/eval.txt        2018-04-10 15:28:26.552370314 +0200
***************
*** 2418,2423 ****
--- 2423,2429 ----
  term_dumpwrite({buf}, {filename} [, {options}])
                                none    dump terminal window contents
  term_getaltscreen({buf})      Number  get the alternate screen flag
+ term_getansicolors({buf})     List    get ANSI palette in GUI color mode
  term_getattr({attr}, {what})  Number  get the value of attribute {what}
  term_getcursor({buf})         List    get the cursor position of a terminal
  term_getjob({buf})            Job     get the job associated with a terminal
***************
*** 2430,2435 ****
--- 2436,2443 ----
  term_list()                   List    get the list of terminal buffers
  term_scrape({buf}, {row})     List    get row of a terminal screen
  term_sendkeys({buf}, {keys})  none    send keystrokes to a terminal
+ term_setansicolors({buf}, {colors})
+                               none    set ANSI palette in GUI color mode
  term_setkill({buf}, {how})    none    set signal to stop job in terminal
  term_setrestore({buf}, {command}) none        set command to restore terminal
  term_start({cmd}, {options})  Job     open a terminal window and run a job
***************
*** 8190,8195 ****
--- 8251,8268 ----
                {buf} is used as with |term_getsize()|.
                {only available when compiled with the |+terminal| feature}
  
+ term_getansicolors({buf})                             *term_getansicolors()*
+               Get the ANSI color palette in use by terminal {buf}.
+               Returns a List of length 16 where each element is a String
+               representing a color in hexadecimal "#rrggbb" format.
+               Also see |term_setansicolors()| and |g:terminal_ansi_colors|.
+               If neither was used returns the default colors.
+ 
+               {buf} is used as with |term_getsize()|.  If the buffer does not
+               exist or is not a terminal window, an empty list is returned.
+               {only available when compiled with the |+terminal| feature and
+               with GUI enabled and/or the |+termguicolors| feature}
+ 
  term_getattr({attr}, {what})                          *term_getattr()*
                Given {attr}, a value returned by term_scrape() in the "attr"
                item, return whether {what} is on.  {what} can be one of:
***************
*** 8321,8326 ****
--- 8394,8412 ----
                means the character CTRL-X.
                {only available when compiled with the |+terminal| feature}
  
+ term_setansicolors({buf}, {colors})                   *term_setansicolors()*
+               Set the ANSI color palette used by terminal {buf}.
+               {colors} must be a List of 16 valid color names or hexadecimal
+               color codes, like those accepted by |highlight-guifg|.
+               Also see |term_getansicolors()| and |g:terminal_ansi_colors|.
+ 
+               These colors are used in the GUI and in the terminal when
+               'termguicolors' is set.  When not using GUI colors (GUI mode
+               or |termguicolors|), the terminal window always uses the 16
+               ANSI colors of the underlying terminal.
+               {only available when compiled with the |+terminal| feature and
+               with GUI enabled and/or the |+termguicolors| feature}
+ 
  term_setkill({buf}, {how})                            *term_setkill()*
                When exiting Vim or trying to close the terminal window in
                another way, {how} defines whether the job in the terminal can
***************
*** 8405,8410 ****
--- 8491,8499 ----
                                     CTRL-D is used on MS-Windows. For Python
                                     use CTRL-Z or "exit()". For a shell use
                                     "exit".  A CR is always added.
+                  "ansi_colors"     A list of 16 color names or hex codes
+                                    defining the ANSI palette used in GUI
+                                    color modes.  See |g:terminal_ansi_colors|.
  
                {only available when compiled with the |+terminal| feature}
  
*** ../vim-8.0.1684/runtime/doc/terminal.txt    2018-04-06 22:26:17.981196807 
+0200
--- runtime/doc/terminal.txt    2018-04-10 15:29:47.271797892 +0200
***************
*** 136,141 ****
--- 136,151 ----
  To use a different color the Terminal highlight group can be used, for
  example: >
      hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue
+ <
+                                                       *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
+ `g:terminal_ansi_colors`, which should be a list of 16 color names or
+ hexadecimal color codes, similar to those accepted by |highlight-guifg|.  When
+ not using GUI colors, the terminal window always uses the 16 ANSI colors of
+ the underlying terminal.
+ The |term_setansicolors()| function can be used to change the colors, and
+ |term_getansicolors()| to get the currently used colors.
  
  
  Syntax ~
*** ../vim-8.0.1684/src/channel.c       2018-04-10 12:42:41.027042171 +0200
--- src/channel.c       2018-04-10 15:19:04.308358494 +0200
***************
*** 4802,4807 ****
--- 4802,4851 ----
                opt->jo_set2 |= JO2_TERM_KILL;
                opt->jo_term_kill = get_tv_string_chk(item);
            }
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+           else if (STRCMP(hi->hi_key, "ansi_colors") == 0)
+           {
+               int             n = 0;
+               listitem_T      *li;
+               long_u          rgb[16];
+ 
+               if (!(supported2 & JO2_ANSI_COLORS))
+                   break;
+ 
+               if (item == NULL || item->v_type != VAR_LIST
+                       || item->vval.v_list == NULL)
+               {
+                   EMSG2(_(e_invargval), "ansi_colors");
+                   return FAIL;
+               }
+ 
+               li = item->vval.v_list->lv_first;
+               for (; li != NULL && n < 16; li = li->li_next, n++)
+               {
+                   char_u      *color_name;
+                   guicolor_T  guicolor;
+ 
+                   color_name = get_tv_string_chk(&li->li_tv);
+                   if (color_name == NULL)
+                       return FAIL;
+ 
+                   guicolor = GUI_GET_COLOR(color_name);
+                   if (guicolor == INVALCOLOR)
+                       return FAIL;
+ 
+                   rgb[n] = GUI_MCH_GET_RGB(guicolor);
+               }
+ 
+               if (n != 16 || li != NULL)
+               {
+                   EMSG2(_(e_invargval), "ansi_colors");
+                   return FAIL;
+               }
+ 
+               opt->jo_set2 |= JO2_ANSI_COLORS;
+               memcpy(opt->jo_ansi_colors, rgb, sizeof(rgb));
+           }
+ # endif
  #endif
            else if (STRCMP(hi->hi_key, "env") == 0)
            {
*** ../vim-8.0.1684/src/evalfunc.c      2018-04-05 22:44:33.771423818 +0200
--- src/evalfunc.c      2018-04-10 15:19:04.312358465 +0200
***************
*** 856,861 ****
--- 856,864 ----
      {"term_dumpload", 1, 2, f_term_dumpload},
      {"term_dumpwrite",        2, 3, f_term_dumpwrite},
      {"term_getaltscreen", 1, 1, f_term_getaltscreen},
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+     {"term_getansicolors", 1, 1, f_term_getansicolors},
+ # endif
      {"term_getattr",  2, 2, f_term_getattr},
      {"term_getcursor",        1, 1, f_term_getcursor},
      {"term_getjob",   1, 1, f_term_getjob},
***************
*** 868,873 ****
--- 871,879 ----
      {"term_list",     0, 0, f_term_list},
      {"term_scrape",   2, 2, f_term_scrape},
      {"term_sendkeys", 2, 2, f_term_sendkeys},
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+     {"term_setansicolors", 2, 2, f_term_setansicolors},
+ # endif
      {"term_setkill",  2, 2, f_term_setkill},
      {"term_setrestore",       2, 2, f_term_setrestore},
      {"term_start",    1, 2, f_term_start},
*** ../vim-8.0.1684/src/proto/terminal.pro      2018-03-16 20:46:52.670189987 
+0100
--- src/proto/terminal.pro      2018-04-10 15:19:04.312358465 +0200
***************
*** 32,37 ****
--- 32,38 ----
  void f_term_dumpdiff(typval_T *argvars, typval_T *rettv);
  void f_term_dumpload(typval_T *argvars, typval_T *rettv);
  void f_term_getaltscreen(typval_T *argvars, typval_T *rettv);
+ void f_term_getansicolors(typval_T *argvars, typval_T *rettv);
  void f_term_getattr(typval_T *argvars, typval_T *rettv);
  void f_term_getcursor(typval_T *argvars, typval_T *rettv);
  void f_term_getjob(typval_T *argvars, typval_T *rettv);
***************
*** 44,49 ****
--- 45,51 ----
  void f_term_list(typval_T *argvars, typval_T *rettv);
  void f_term_scrape(typval_T *argvars, typval_T *rettv);
  void f_term_sendkeys(typval_T *argvars, typval_T *rettv);
+ void f_term_setansicolors(typval_T *argvars, typval_T *rettv);
  void f_term_setrestore(typval_T *argvars, typval_T *rettv);
  void f_term_setkill(typval_T *argvars, typval_T *rettv);
  void f_term_start(typval_T *argvars, typval_T *rettv);
*** ../vim-8.0.1684/src/structs.h       2018-03-10 20:27:32.071757661 +0100
--- src/structs.h       2018-04-10 15:47:33.184279955 +0200
***************
*** 1708,1714 ****
  #define JO2_EOF_CHARS     0x1000      /* "eof_chars" */
  #define JO2_NORESTORE     0x2000      /* "norestore" */
  #define JO2_TERM_KILL     0x4000      /* "term_kill" */
! #define JO2_ALL                   0x7FFF
  
  #define JO_MODE_ALL   (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
  #define JO_CB_ALL \
--- 1708,1714 ----
  #define JO2_EOF_CHARS     0x1000      /* "eof_chars" */
  #define JO2_NORESTORE     0x2000      /* "norestore" */
  #define JO2_TERM_KILL     0x4000      /* "term_kill" */
! #define JO2_ANSI_COLORS           0x8000      /* "ansi_colors" */
  
  #define JO_MODE_ALL   (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
  #define JO_CB_ALL \
***************
*** 1777,1782 ****
--- 1777,1785 ----
      int               jo_term_finish;
      char_u    *jo_eof_chars;
      char_u    *jo_term_kill;
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+     long_u    jo_ansi_colors[16];
+ # endif
  #endif
  } jobopt_T;
  
*** ../vim-8.0.1684/src/terminal.c      2018-04-10 14:56:14.178103493 +0200
--- src/terminal.c      2018-04-10 15:36:41.076876925 +0200
***************
*** 38,48 ****
   * in tl_scrollback are no longer used.
   *
   * TODO:
-  * - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and 
in
-  *   the GUI. #2747
   * - Win32: Make terminal used for :!cmd in the GUI work better.  Allow for
   *   redirection.  Probably in call to channel_set_pipes().
   * - implement term_setsize()
   * - Copy text in the vterm to the Vim buffer once in a while, so that
   *   completion works.
   * - in GUI vertical split causes problems.  Cursor is flickering. (Hirohito
--- 38,48 ----
   * in tl_scrollback are no longer used.
   *
   * TODO:
   * - Win32: Make terminal used for :!cmd in the GUI work better.  Allow for
   *   redirection.  Probably in call to channel_set_pipes().
   * - implement term_setsize()
+  * - add an optional limit for the scrollback size.  When reaching it remove
+  *   10% at the start.
   * - Copy text in the vterm to the Vim buffer once in a while, so that
   *   completion works.
   * - in GUI vertical split causes problems.  Cursor is flickering. (Hirohito
***************
*** 64,71 ****
   *   
http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
   * - when 'encoding' is not utf-8, or the job is using another encoding, setup
   *   conversions.
-  * - add an optional limit for the scrollback size.  When reaching it remove
-  *   10% at the start.
   */
  
  #include "vim.h"
--- 64,69 ----
***************
*** 3141,3146 ****
--- 3139,3213 ----
      }
  }
  
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ /*
+  * Set the 16 ANSI colors from array of RGB values
+  */
+     static void
+ set_vterm_palette(VTerm *vterm, long_u *rgb)
+ {
+     int               index = 0;
+     VTermState        *state = vterm_obtain_state(vterm);
+     for (; index < 16; index++)
+     {
+       VTermColor      color;
+       color.red = (unsigned)(rgb[index] >> 16);
+       color.green = (unsigned)(rgb[index] >> 8) & 255;
+       color.blue = (unsigned)rgb[index] & 255;
+       vterm_state_set_palette_color(state, index, &color);
+     }
+ }
+ 
+ /*
+  * Set the ANSI color palette from a list of colors
+  */
+     static int
+ set_ansi_colors_list(VTerm *vterm, list_T *list)
+ {
+     int               n = 0;
+     long_u    rgb[16];
+     listitem_T        *li = list->lv_first;
+ 
+     for (; li != NULL && n < 16; li = li->li_next, n++)
+     {
+       char_u          *color_name;
+       guicolor_T      guicolor;
+ 
+       color_name = get_tv_string_chk(&li->li_tv);
+       if (color_name == NULL)
+           return FAIL;
+ 
+       guicolor = GUI_GET_COLOR(color_name);
+       if (guicolor == INVALCOLOR)
+           return FAIL;
+ 
+       rgb[n] = GUI_MCH_GET_RGB(guicolor);
+     }
+ 
+     if (n != 16 || li != NULL)
+       return FAIL;
+ 
+     set_vterm_palette(vterm, rgb);
+ 
+     return OK;
+ }
+ 
+ /*
+  * Initialize the ANSI color palette from g:terminal_ansi_colors[0:15]
+  */
+     static void
+ init_vterm_ansi_colors(VTerm *vterm)
+ {
+     dictitem_T        *var = find_var((char_u *)"g:terminal_ansi_colors", 
NULL, TRUE);
+ 
+     if (var != NULL
+           && (var->di_tv.v_type != VAR_LIST
+               || var->di_tv.vval.v_list == NULL
+               || set_ansi_colors_list(vterm, var->di_tv.vval.v_list) == FAIL))
+       EMSG2(_(e_invarg2), "g:terminal_ansi_colors");
+ }
+ #endif
+ 
  /*
   * Handles a "drop" command from the job in the terminal.
   * "item" is the file name, "item->li_next" may have options.
***************
*** 3372,3377 ****
--- 3439,3447 ----
            &term->tl_default_color.fg,
            &term->tl_default_color.bg);
  
+     if (t_colors >= 16)
+       vterm_state_set_bold_highbright(vterm_obtain_state(vterm), 1);
+ 
      /* Required to initialize most things. */
      vterm_screen_reset(screen, 1 /* hard */);
  
***************
*** 4762,4767 ****
--- 4832,4899 ----
      }
  }
  
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
+ /*
+  * "term_getansicolors(buf)" function
+  */
+     void
+ f_term_getansicolors(typval_T *argvars, typval_T *rettv)
+ {
+     buf_T     *buf = term_get_buf(argvars, "term_getansicolors()");
+     term_T    *term;
+     VTermState        *state;
+     VTermColor  color;
+     char_u    hexbuf[10];
+     int               index;
+     list_T    *list;
+ 
+     if (rettv_list_alloc(rettv) == FAIL)
+       return;
+ 
+     if (buf == NULL)
+       return;
+     term = buf->b_term;
+     if (term->tl_vterm == NULL)
+       return;
+ 
+     list = rettv->vval.v_list;
+     state = vterm_obtain_state(term->tl_vterm);
+     for (index = 0; index < 16; index++)
+     {
+       vterm_state_get_palette_color(state, index, &color);
+       sprintf((char *)hexbuf, "#%02x%02x%02x",
+               color.red, color.green, color.blue);
+       if (list_append_string(list, hexbuf, 7) == FAIL)
+           return;
+     }
+ }
+ 
+ /*
+  * "term_setansicolors(buf, list)" function
+  */
+     void
+ f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
+ {
+     buf_T     *buf = term_get_buf(argvars, "term_setansicolors()");
+     term_T    *term;
+ 
+     if (buf == NULL)
+       return;
+     term = buf->b_term;
+     if (term->tl_vterm == NULL)
+       return;
+ 
+     if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
+     {
+       EMSG(_(e_listreq));
+       return;
+     }
+ 
+     if (set_ansi_colors_list(term->tl_vterm, argvars[1].vval.v_list) == FAIL)
+       EMSG(_(e_invarg));
+ }
+ #endif
+ 
  /*
   * "term_setrestore(buf, command)" function
   */
***************
*** 4824,4830 ****
                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) == FAIL)
        return;
  
      buf = term_start(&argvars[0], NULL, &opt, 0);
--- 4956,4963 ----
                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_ANSI_COLORS) == FAIL)
        return;
  
      buf = term_start(&argvars[0], NULL, &opt, 0);
***************
*** 5152,5157 ****
--- 5285,5297 ----
  
      create_vterm(term, term->tl_rows, term->tl_cols);
  
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+     if (opt->jo_set2 & JO2_ANSI_COLORS)
+       set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
+     else
+       init_vterm_ansi_colors(term->tl_vterm);
+ #endif
+ 
      channel_set_job(channel, job, opt);
      job_set_options(job, opt);
  
***************
*** 5324,5329 ****
--- 5464,5476 ----
  {
      create_vterm(term, term->tl_rows, term->tl_cols);
  
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+     if (opt->jo_set2 & JO2_ANSI_COLORS)
+       set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
+     else
+       init_vterm_ansi_colors(term->tl_vterm);
+ #endif
+ 
      /* This may change a string in "argvar". */
      term->tl_job = job_start(argvar, argv, opt);
      if (term->tl_job != NULL)
*** ../vim-8.0.1684/src/testdir/test_terminal.vim       2018-04-07 
19:27:11.938983767 +0200
--- src/testdir/test_terminal.vim       2018-04-10 15:45:54.656975883 +0200
***************
*** 1255,1257 ****
--- 1255,1327 ----
    call ch_logfile('', '')
    call delete('Xlog')
  endfunc
+ 
+ func Test_terminal_ansicolors_default()
+   let colors = [
+       \ '#000000', '#e00000',
+       \ '#00e000', '#e0e000',
+       \ '#0000e0', '#e000e0',
+       \ '#00e0e0', '#e0e0e0',
+       \ '#808080', '#ff4040',
+       \ '#40ff40', '#ffff40',
+       \ '#4040ff', '#ff40ff',
+       \ '#40ffff', '#ffffff',
+       \]
+ 
+   let buf = Run_shell_in_terminal({})
+   call assert_equal(colors, term_getansicolors(buf))
+   call Stop_shell_in_terminal(buf)
+   call term_wait(buf)
+ 
+   exe buf . 'bwipe'
+ endfunc
+ 
+ let s:test_colors = [
+       \ '#616e64', '#0d0a79',
+       \ '#6d610d', '#0a7373',
+       \ '#690d0a', '#6d696e',
+       \ '#0d0a6f', '#616e0d',
+       \ '#0a6479', '#6d0d0a',
+       \ '#617373', '#0d0a69',
+       \ '#6d690d', '#0a6e6f',
+       \ '#610d0a', '#6e6479',
+       \]
+ 
+ func Test_terminal_ansicolors_global()
+   let g:terminal_ansi_colors = reverse(copy(s:test_colors))
+   let buf = Run_shell_in_terminal({})
+   call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf))
+   call Stop_shell_in_terminal(buf)
+   call term_wait(buf)
+ 
+   exe buf . 'bwipe'
+   unlet g:terminal_ansi_colors
+ endfunc
+ 
+ func Test_terminal_ansicolors_func()
+   let g:terminal_ansi_colors = reverse(copy(s:test_colors))
+   let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors})
+   call assert_equal(s:test_colors, term_getansicolors(buf))
+ 
+   call term_setansicolors(buf, g:terminal_ansi_colors)
+   call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf))
+ 
+   let colors = [
+       \ 'ivory', 'AliceBlue',
+       \ 'grey67', 'dark goldenrod',
+       \ 'SteelBlue3', 'PaleVioletRed4',
+       \ 'MediumPurple2', 'yellow2',
+       \ 'RosyBrown3', 'OrangeRed2',
+       \ 'white smoke', 'navy blue',
+       \ 'grey47', 'gray97',
+       \ 'MistyRose2', 'DodgerBlue4',
+       \]
+   call term_setansicolors(buf, colors)
+ 
+   let colors[4] = 'Invalid'
+   call assert_fails('call term_setansicolors(buf, colors)', 'E474:')
+ 
+   call Stop_shell_in_terminal(buf)
+   call term_wait(buf)
+   exe buf . 'bwipe'
+ endfunc
*** ../vim-8.0.1684/src/version.c       2018-04-10 14:56:14.178103493 +0200
--- src/version.c       2018-04-10 15:22:48.738766256 +0200
***************
*** 764,765 ****
--- 764,767 ----
  {   /* Add new patch number below this line */
+ /**/
+     1685,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
144. You eagerly await the update of the "Cool Site of the Day."

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui