Skip to content

Commit

Permalink
patch 8.0.1685: can't set ANSI colors of a terminal window
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
brammool committed Apr 10, 2018
1 parent 07b46af commit f59c6e8
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 6 deletions.
31 changes: 31 additions & 0 deletions runtime/doc/eval.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,7 @@ term_dumpload({filename} [, {options}])
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
Expand All @@ -2435,6 +2436,8 @@ term_gettty({buf}, [{input}]) String get the tty name of a terminal
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
Expand Down Expand Up @@ -8248,6 +8251,18 @@ term_getaltscreen({buf}) *term_getaltscreen()*
{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:
Expand Down Expand Up @@ -8379,6 +8394,19 @@ term_sendkeys({buf}, {keys}) *term_sendkeys()*
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}

This comment has been minimized.

Copy link
@chdiza

chdiza Apr 11, 2018

It would be nice if somewhere it's documented which positions in the list correspond to which colors. E.g., if I want to change the blue, I have no way of knowing which of the 16 I should change.

Also, the two new functions need to appear under :h function-list; currently they don't.

This comment has been minimized.

Copy link
@brammool

brammool via email Apr 11, 2018

Author Contributor
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
Expand Down Expand Up @@ -8463,6 +8491,9 @@ term_start({cmd}, {options}) *term_start()*
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}

Expand Down
10 changes: 10 additions & 0 deletions runtime/doc/terminal.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ 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
<
*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 ~
Expand Down
44 changes: 44 additions & 0 deletions src/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -4802,6 +4802,50 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
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)
{
Expand Down
6 changes: 6 additions & 0 deletions src/evalfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,9 @@ static struct fst
{"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},
Expand All @@ -868,6 +871,9 @@ static struct fst
{"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},
Expand Down
2 changes: 2 additions & 0 deletions src/proto/terminal.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ int term_swap_diff(void);
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);
Expand All @@ -44,6 +45,7 @@ void f_term_gettty(typval_T *argvars, typval_T *rettv);
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);
Expand Down
5 changes: 4 additions & 1 deletion src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,7 @@ struct channel_S {
#define JO2_EOF_CHARS 0x1000 /* "eof_chars" */
#define JO2_NORESTORE 0x2000 /* "norestore" */
#define JO2_TERM_KILL 0x4000 /* "term_kill" */
#define JO2_ALL 0x7FFF
#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 \
Expand Down Expand Up @@ -1777,6 +1777,9 @@ typedef struct
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;

Expand Down
Loading

0 comments on commit f59c6e8

Please sign in to comment.