# HG changeset patch # User Christian Brabandt # Date 1461266107 -7200 # Node ID c83e2c1e7f2babe732361d1b494a9e648ec83597 # Parent 4794235d1bb03a1e8f7742cc9bb0144b5f479c29 commit https://github.com/vim/vim/commit/8a633e3427b47286869aa4b96f2bfc1fe65b25cd Author: Bram Moolenaar Date: Thu Apr 21 21:10:14 2016 +0200 patch 7.4.1770 Problem: Cannot use true color in the terminal. Solution: Add the 'guicolors' option. (Nikolai Pavlov) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 7.4. Last change: 2016 Apr 20 +*options.txt* For Vim version 7.4. Last change: 2016 Apr 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -3477,6 +3477,18 @@ A jump table for the options with a shor This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. + *'guicolors'* *'gcol'* +'guicolors' 'gcol' boolean (default off) + global + {not in Vi} + {not available when compiled without the + |+termtruecolor| feature} + When on, uses |highlight-guifg| and |highlight-guibg| attributes in + the terminal (thus using 24-bit color). Requires a ISO-8613-3 + compatible terminal. + If setting this option does not work (produces a colorless UI) + reading |xterm-true-color| might help. + *'guicursor'* *'gcr'* *E545* *E546* *E548* *E549* 'guicursor' 'gcr' string (default "n-v-c:block-Cursor/lCursor, ve:ver35-Cursor, diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -1,4 +1,4 @@ -*term.txt* For Vim version 7.4. Last change: 2015 Nov 24 +*term.txt* For Vim version 7.4. Last change: 2016 Apr 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -303,6 +303,10 @@ Added by Vim (there are no standard code see |'ambiwidth'| t_RB request terminal background color *t_RB* *'t_RB'* see |'ambiwidth'| + t_8f set foreground color (R, G, B) *t_8f* *'t_8f'* + |xterm-true-color| + t_8b set background color (R, G, B) *t_8b* *'t_8b'* + |xterm-true-color| KEY CODES Note: Use the <> form if possible @@ -419,6 +423,22 @@ VT220, etc.). The result is that codes Note: This is only done on startup. If the xterm options are changed after Vim has started, the escape sequences may not be recognized anymore. + *xterm-true-color* +Vim supports using true colors in the terminal (taken from |highlight-guifg| +and |highlight-guibg|), given that terminal supports this. To make this +work, 'guicolors' option needs to be set. + +Sometimes setting 'guicolors' is not enough and one has to set the |t_8f| and +|t_8b| options explicitly. Default values of these options are +`^[[38;2;%lu;%lu;%lum` and `^[[48;2;%lu;%lu;%lum` (replace `^[` with real +escape) respectively, but it is only set when `$TERM` is `xterm`. Some +terminals accept the same sequences, but with all semicolons replaced by +colons (this is actually more compatible, but less widely supported). These +options contain printf strings, with |printf()| (actually, its C equivalent +hence `l` modifier) invoked with the t_ option value and three unsigned long +integers that may have any value between 0 and 255 (inclusive) representing +red, green and blue colors respectively. + *xterm-resize* Window resizing with xterm only works if the allowWindowOps resource is enabled. On some systems and versions of xterm it's disabled by default diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -424,6 +424,7 @@ m *+tcl* Tcl interface |tcl| m *+tcl/dyn* Tcl interface |tcl-dynamic| |/dyn| *+terminfo* uses |terminfo| instead of termcap N *+termresponse* support for |t_RV| and |v:termresponse| +m *+termtruecolor* 24-bit color in xterm-compatible terminals support N *+textobjects* |text-objects| selection *+tgetent* non-Unix only: able to use external termcap N *+timers* the |timer_start()| function diff --git a/src/auto/configure b/src/auto/configure --- a/src/auto/configure +++ b/src/auto/configure @@ -810,6 +810,7 @@ with_tclsh enable_rubyinterp with_ruby_command enable_cscope +enable_termtruecolor enable_workshop enable_netbeans enable_channel @@ -1476,6 +1477,7 @@ Optional Features: --enable-tclinterp=OPTS Include Tcl interpreter. default=no OPTS=no/yes/dynamic --enable-rubyinterp=OPTS Include Ruby interpreter. default=no OPTS=no/yes/dynamic --enable-cscope Include cscope interface. + --enable-termtruecolor Include support for 24-bit colors in ISO-8613-3 compatible terminals --enable-workshop Include Sun Visual Workshop support. --disable-netbeans Disable NetBeans integration support. --disable-channel Disable process communication support. @@ -7216,6 +7218,22 @@ if test "$enable_cscope" = "yes"; then fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --enable-termtruecolor argument" >&5 +$as_echo_n "checking --enable-termtruecolor argument... " >&6; } +# Check whether --enable-termtruecolor was given. +if test "${enable_termtruecolor+set}" = set; then : + enableval=$enable_termtruecolor; +else + enable_termtruecolor="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_termtruecolor" >&5 +$as_echo "$enable_termtruecolor" >&6; } +if test "$enable_termtruecolor" = "yes"; then + $as_echo "#define FEAT_TERMTRUECOLOR 1" >>confdefs.h + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking --enable-workshop argument" >&5 $as_echo_n "checking --enable-workshop argument... " >&6; } # Check whether --enable-workshop was given. diff --git a/src/config.h.in b/src/config.h.in --- a/src/config.h.in +++ b/src/config.h.in @@ -362,6 +362,9 @@ /* Define for linking via dlopen() or LoadLibrary() */ #undef DYNAMIC_TCL +/* Define if you want 24-bit colors in ISO-8613-3 compatible terminals. */ +#undef FEAT_TERMTRUECOLOR + /* Define if you want to add support for ACL */ #undef HAVE_POSIX_ACL #undef HAVE_SOLARIS_ZFS_ACL diff --git a/src/configure.in b/src/configure.in --- a/src/configure.in +++ b/src/configure.in @@ -1926,6 +1926,15 @@ if test "$enable_cscope" = "yes"; then AC_DEFINE(FEAT_CSCOPE) fi +AC_MSG_CHECKING(--enable-termtruecolor argument) +AC_ARG_ENABLE(termtruecolor, + [ --enable-termtruecolor Include support for 24-bit colors in ISO-8613-3 compatible terminals], , + [enable_termtruecolor="no"]) +AC_MSG_RESULT($enable_termtruecolor) +if test "$enable_termtruecolor" = "yes"; then + AC_DEFINE(FEAT_TERMTRUECOLOR) +fi + AC_MSG_CHECKING(--enable-workshop argument) AC_ARG_ENABLE(workshop, [ --enable-workshop Include Sun Visual Workshop support.], , diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -14044,6 +14044,9 @@ f_has(typval_T *argvars, typval_T *rettv #ifdef FEAT_TERMRESPONSE "termresponse", #endif +#ifdef FEAT_TERMTRUECOLOR + "termtruecolor", +#endif #ifdef FEAT_TEXTOBJ "textobjects", #endif diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -369,6 +369,10 @@ EXTERN char_u *use_gvimrc INIT(= NULL); EXTERN int cterm_normal_fg_color INIT(= 0); EXTERN int cterm_normal_fg_bold INIT(= 0); EXTERN int cterm_normal_bg_color INIT(= 0); +#ifdef FEAT_TERMTRUECOLOR +EXTERN long_u cterm_normal_fg_gui_color INIT(= INVALCOLOR); +EXTERN long_u cterm_normal_bg_gui_color INIT(= INVALCOLOR); +#endif #ifdef FEAT_AUTOCMD EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */ diff --git a/src/hardcopy.c b/src/hardcopy.c --- a/src/hardcopy.c +++ b/src/hardcopy.c @@ -164,7 +164,7 @@ parse_printoptions(void) #if (defined(FEAT_MBYTE) && defined(FEAT_POSTSCRIPT)) || defined(PROTO) /* - * Parse 'printoptions' and set the flags in "printer_opts". + * Parse 'printmbfont' and set the flags in "mbfont_opts". * Returns an error message or NULL; */ char_u * @@ -307,8 +307,8 @@ prt_get_attr( pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL); pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL); -# ifdef FEAT_GUI - if (gui.in_use) +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) + if (USE_24BIT) { bg_color = highlight_gui_color_rgb(hl_id, FALSE); if (bg_color == PRCOLOR_BLACK) diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -1305,7 +1305,16 @@ static struct vimoption options[] = {(char_u *)NULL, (char_u *)0L} #endif SCRIPTID_INIT}, - {"guicursor", "gcr", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, + {"guicolors", "gcol", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, +#ifdef FEAT_TERMTRUECOLOR + (char_u *)&p_guicolors, PV_NONE, + {(char_u *)FALSE, (char_u *)FALSE} +#else + (char_u*)NULL, PV_NONE, + {(char_u *)FALSE, (char_u *)FALSE} +#endif + SCRIPTID_INIT}, + {"guicursor", "gcr", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef CURSOR_SHAPE (char_u *)&p_guicursor, PV_NONE, { @@ -3011,6 +3020,8 @@ static struct vimoption options[] = p_term("t_xs", T_XS) p_term("t_ZH", T_CZH) p_term("t_ZR", T_CZR) + p_term("t_8f", T_8F) + p_term("t_8b", T_8B) /* terminal key codes are not in here */ @@ -8353,6 +8364,17 @@ set_bool_option( #endif +#ifdef FEAT_TERMTRUECOLOR + /* 'guicolors' */ + else if ((int *)varp == &p_guicolors) + { +# ifdef FEAT_GUI + if (!gui.in_use && !gui.starting) +# endif + highlight_gui_started(); + } +#endif + /* * End of handling side effects for bool options. */ diff --git a/src/option.h b/src/option.h --- a/src/option.h +++ b/src/option.h @@ -527,6 +527,9 @@ EXTERN char_u *p_popt; /* 'printoptions' EXTERN char_u *p_header; /* 'printheader' */ #endif EXTERN int p_prompt; /* 'prompt' */ +#ifdef FEAT_TERMTRUECOLOR +EXTERN int p_guicolors; /* 'guicolors' */ +#endif #ifdef FEAT_GUI EXTERN char_u *p_guifont; /* 'guifont' */ # ifdef FEAT_XFONTSET diff --git a/src/proto/term.pro b/src/proto/term.pro --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -1,4 +1,7 @@ /* term.c */ +guicolor_T termtrue_mch_get_color(char_u *name); +guicolor_T termtrue_get_color(char_u *name); +long_u termtrue_mch_get_rgb(guicolor_T color); int set_termname(char_u *term); void set_mouse_termcode(int n, char_u *s); void del_mouse_termcode(int n); @@ -22,6 +25,8 @@ void term_set_winpos(int x, int y); void term_set_winsize(int width, int height); void term_fg_color(int n); void term_bg_color(int n); +void term_fg_rgb_color(long_u rgb); +void term_bg_rgb_color(long_u rgb); void term_settitle(char_u *title); void ttest(int pairs); void add_long_to_buf(long_u val, char_u *dst); diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -7828,7 +7828,7 @@ screen_start_highlight(int attr) { if (attr > HL_ALL) /* special HL attr. */ { - if (t_colors > 1) + if (IS_CTERM) aep = syn_cterm_attr2entry(attr); else aep = syn_term_attr2entry(attr); @@ -7839,8 +7839,16 @@ screen_start_highlight(int attr) } if ((attr & HL_BOLD) && T_MD != NULL) /* bold */ out_str(T_MD); - else if (aep != NULL && t_colors > 1 && aep->ae_u.cterm.fg_color - && cterm_normal_fg_bold) + else if (aep != NULL && cterm_normal_fg_bold && +#ifdef FEAT_TERMTRUECOLOR + (p_guicolors ? + (aep->ae_u.cterm.fg_rgb != INVALCOLOR): +#endif + (t_colors > 1 && aep->ae_u.cterm.fg_color) +#ifdef FEAT_TERMTRUECOLOR + ) +#endif + ) /* If the Normal FG color has BOLD attribute and the new HL * has a FG color defined, clear BOLD. */ out_str(T_ME); @@ -7860,17 +7868,29 @@ screen_start_highlight(int attr) */ if (aep != NULL) { - if (t_colors > 1) - { - if (aep->ae_u.cterm.fg_color) - term_fg_color(aep->ae_u.cterm.fg_color - 1); - if (aep->ae_u.cterm.bg_color) - term_bg_color(aep->ae_u.cterm.bg_color - 1); +#ifdef FEAT_TERMTRUECOLOR + if (p_guicolors) + { + if (aep->ae_u.cterm.fg_rgb != INVALCOLOR) + term_fg_rgb_color(aep->ae_u.cterm.fg_rgb); + if (aep->ae_u.cterm.bg_rgb != INVALCOLOR) + term_bg_rgb_color(aep->ae_u.cterm.bg_rgb); } else - { - if (aep->ae_u.term.start != NULL) - out_str(aep->ae_u.term.start); +#endif + { + if (t_colors > 1) + { + if (aep->ae_u.cterm.fg_color) + term_fg_color(aep->ae_u.cterm.fg_color - 1); + if (aep->ae_u.cterm.bg_color) + term_bg_color(aep->ae_u.cterm.bg_color - 1); + } + else + { + if (aep->ae_u.term.start != NULL) + out_str(aep->ae_u.term.start); + } } } } @@ -7904,14 +7924,23 @@ screen_stop_highlight(void) { attrentry_T *aep; - if (t_colors > 1) + if (IS_CTERM) { /* * Assume that t_me restores the original colors! */ aep = syn_cterm_attr2entry(screen_attr); - if (aep != NULL && (aep->ae_u.cterm.fg_color - || aep->ae_u.cterm.bg_color)) + if (aep != NULL && +#ifdef FEAT_TERMTRUECOLOR + (p_guicolors ? + (aep->ae_u.cterm.fg_rgb != INVALCOLOR || + aep->ae_u.cterm.bg_rgb != INVALCOLOR): +#endif + (aep->ae_u.cterm.fg_color || aep->ae_u.cterm.bg_color) +#ifdef FEAT_TERMTRUECOLOR + ) +#endif + ) do_ME = TRUE; } else @@ -7959,15 +7988,27 @@ screen_stop_highlight(void) if (do_ME || (screen_attr & (HL_BOLD | HL_INVERSE))) out_str(T_ME); - if (t_colors > 1) - { - /* set Normal cterm colors */ - if (cterm_normal_fg_color != 0) - term_fg_color(cterm_normal_fg_color - 1); - if (cterm_normal_bg_color != 0) - term_bg_color(cterm_normal_bg_color - 1); - if (cterm_normal_fg_bold) - out_str(T_MD); +#ifdef FEAT_TERMTRUECOLOR + if (p_guicolors) + { + if (cterm_normal_fg_gui_color != INVALCOLOR) + term_fg_rgb_color(cterm_normal_fg_gui_color); + if (cterm_normal_bg_gui_color != INVALCOLOR) + term_bg_rgb_color(cterm_normal_bg_gui_color); + } + else +#endif + { + if (t_colors > 1) + { + /* set Normal cterm colors */ + if (cterm_normal_fg_color != 0) + term_fg_color(cterm_normal_fg_color - 1); + if (cterm_normal_bg_color != 0) + term_bg_color(cterm_normal_bg_color - 1); + if (cterm_normal_fg_bold) + out_str(T_MD); + } } } } @@ -7981,10 +8022,17 @@ screen_stop_highlight(void) void reset_cterm_colors(void) { - if (t_colors > 1) + if (IS_CTERM) { /* set Normal cterm colors */ +#ifdef FEAT_TERMTRUECOLOR + if (p_guicolors ? + (cterm_normal_fg_gui_color != INVALCOLOR + || cterm_normal_bg_gui_color != INVALCOLOR): + (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0)) +#else if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0) +#endif { out_str(T_OP); screen_attr = -1; @@ -8228,7 +8276,7 @@ screen_fill( #ifdef FEAT_GUI !gui.in_use && #endif - t_colors <= 1); + !IS_CTERM); for (row = start_row; row < end_row; ++row) { #ifdef FEAT_MBYTE @@ -8911,6 +8959,9 @@ can_clear(char_u *p) #ifdef FEAT_GUI || gui.in_use #endif +#ifdef FEAT_TERMTRUECOLOR + || (p_guicolors && cterm_normal_bg_gui_color != INVALCOLOR) +#endif || cterm_normal_bg_color == 0 || *T_UT != NUL)); } @@ -10242,6 +10293,9 @@ draw_tabline(void) #ifdef FEAT_GUI && !gui.in_use #endif +#ifdef FEAT_TERMTRUECOLOR + && !p_guicolors +#endif ); redraw_tabline = FALSE; diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -84,7 +84,9 @@ typedef struct file_buffer buf_T; /* fo # ifdef FEAT_XCLIPBOARD # include # endif -# define guicolor_T int /* avoid error in prototypes */ +# define guicolor_T long_u /* avoid error in prototypes and + * make FEAT_TERMTRUECOLOR work */ +# define INVALCOLOR ((guicolor_T)0x1ffffff) #endif /* @@ -911,6 +913,10 @@ typedef struct attr_entry /* These colors need to be > 8 bits to hold 256. */ short_u fg_color; /* foreground color number */ short_u bg_color; /* background color number */ +# ifdef FEAT_TERMTRUECOLOR + long_u fg_rgb; /* foreground color RGB */ + long_u bg_rgb; /* background color RGB */ +# endif } cterm; # ifdef FEAT_GUI struct diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -33,10 +33,12 @@ struct hl_group int sg_cterm_fg; /* terminal fg color number + 1 */ int sg_cterm_bg; /* terminal bg color number + 1 */ int sg_cterm_attr; /* Screen attr for color term mode */ -#ifdef FEAT_GUI /* for when using the GUI */ +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) guicolor_T sg_gui_fg; /* GUI foreground color handle */ guicolor_T sg_gui_bg; /* GUI background color handle */ +#endif +#ifdef FEAT_GUI guicolor_T sg_gui_sp; /* GUI special color handle */ GuiFont sg_font; /* GUI font handle */ #ifdef FEAT_XFONTSET @@ -97,10 +99,12 @@ static int syn_list_header(int did_heade static int hl_has_settings(int idx, int check_link); static void highlight_clear(int idx); -#ifdef FEAT_GUI +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) static void gui_do_one_color(int idx, int do_menu, int do_tooltip); +static guicolor_T color_name2handle(char_u *name); +#endif +#ifdef FEAT_GUI static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip); -static guicolor_T color_name2handle(char_u *name); static GuiFont font_name2handle(char_u *name); # ifdef FEAT_XFONTSET static GuiFontset fontset_name2handle(char_u *name, int fixed_width); @@ -7333,8 +7337,8 @@ do_highlight( for (idx = 0; idx < highlight_ga.ga_len; ++idx) highlight_clear(idx); init_highlight(TRUE, TRUE); -#ifdef FEAT_GUI - if (gui.in_use) +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) + if (USE_24BIT) highlight_gui_started(); #endif highlight_changed(); @@ -7788,10 +7792,16 @@ do_highlight( if (!init) HL_TABLE()[idx].sg_set |= SG_GUI; -# ifdef FEAT_GUI +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) /* In GUI guifg colors are only used when recognized */ i = color_name2handle(arg); - if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) + if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 +# ifdef FEAT_GUI + || !(USE_24BIT) +# else + || !p_guicolors +# endif + ) { HL_TABLE()[idx].sg_gui_fg = i; # endif @@ -7800,7 +7810,7 @@ do_highlight( HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg); else HL_TABLE()[idx].sg_gui_fg_name = NULL; -# ifdef FEAT_GUI +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) # ifdef FEAT_GUI_X11 if (is_menu_group) gui.menu_fg_pixel = i; @@ -7825,10 +7835,10 @@ do_highlight( if (!init) HL_TABLE()[idx].sg_set |= SG_GUI; -# ifdef FEAT_GUI +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) /* In GUI guifg colors are only used when recognized */ i = color_name2handle(arg); - if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) + if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) { HL_TABLE()[idx].sg_gui_bg = i; # endif @@ -7837,7 +7847,7 @@ do_highlight( HL_TABLE()[idx].sg_gui_bg_name = vim_strsave(arg); else HL_TABLE()[idx].sg_gui_bg_name = NULL; -# ifdef FEAT_GUI +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) # ifdef FEAT_GUI_X11 if (is_menu_group) gui.menu_bg_pixel = i; @@ -7997,7 +8007,9 @@ do_highlight( * Need to update all groups, because they might be using "bg" * and/or "fg", which have been changed now. */ - if (gui.in_use) +#endif +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) + if (USE_24BIT) highlight_gui_started(); #endif } @@ -8068,6 +8080,10 @@ restore_cterm_colors(void) cterm_normal_fg_color = 0; cterm_normal_fg_bold = 0; cterm_normal_bg_color = 0; +# ifdef FEAT_TERMTRUECOLOR + cterm_normal_fg_gui_color = INVALCOLOR; + cterm_normal_bg_gui_color = INVALCOLOR; +# endif #endif } @@ -8118,9 +8134,11 @@ highlight_clear(int idx) vim_free(HL_TABLE()[idx].sg_gui_sp_name); HL_TABLE()[idx].sg_gui_sp_name = NULL; #endif -#ifdef FEAT_GUI +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) HL_TABLE()[idx].sg_gui_fg = INVALCOLOR; HL_TABLE()[idx].sg_gui_bg = INVALCOLOR; +#endif +#ifdef FEAT_GUI HL_TABLE()[idx].sg_gui_sp = INVALCOLOR; gui_mch_free_font(HL_TABLE()[idx].sg_font); HL_TABLE()[idx].sg_font = NOFONT; @@ -8140,7 +8158,7 @@ highlight_clear(int idx) #endif } -#if defined(FEAT_GUI) || defined(PROTO) +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) || defined(PROTO) /* * Set the normal foreground and background colors according to the "Normal" * highlighting group. For X11 also set "Menu", "Scrollbar", and @@ -8149,44 +8167,78 @@ highlight_clear(int idx) void set_normal_colors(void) { - if (set_group_colors((char_u *)"Normal", - &gui.norm_pixel, &gui.back_pixel, - FALSE, TRUE, FALSE)) - { - gui_mch_new_colors(); - must_redraw = CLEAR; - } -#ifdef FEAT_GUI_X11 - if (set_group_colors((char_u *)"Menu", - &gui.menu_fg_pixel, &gui.menu_bg_pixel, - TRUE, FALSE, FALSE)) - { -# ifdef FEAT_MENU - gui_mch_new_menu_colors(); +#ifdef FEAT_GUI +# ifdef FEAT_TERMTRUECOLOR + if (gui.in_use) # endif - must_redraw = CLEAR; - } -# ifdef FEAT_BEVAL - if (set_group_colors((char_u *)"Tooltip", - &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, - FALSE, FALSE, TRUE)) - { -# ifdef FEAT_TOOLBAR - gui_mch_new_tooltip_colors(); + { + if (set_group_colors((char_u *)"Normal", + &gui.norm_pixel, &gui.back_pixel, + FALSE, TRUE, FALSE)) + { + gui_mch_new_colors(); + must_redraw = CLEAR; + } +# ifdef FEAT_GUI_X11 + if (set_group_colors((char_u *)"Menu", + &gui.menu_fg_pixel, &gui.menu_bg_pixel, + TRUE, FALSE, FALSE)) + { +# ifdef FEAT_MENU + gui_mch_new_menu_colors(); +# endif + must_redraw = CLEAR; + } +# ifdef FEAT_BEVAL + if (set_group_colors((char_u *)"Tooltip", + &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, + FALSE, FALSE, TRUE)) + { +# ifdef FEAT_TOOLBAR + gui_mch_new_tooltip_colors(); +# endif + must_redraw = CLEAR; + } +# endif + if (set_group_colors((char_u *)"Scrollbar", + &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, + FALSE, FALSE, FALSE)) + { + gui_new_scrollbar_colors(); + must_redraw = CLEAR; + } # endif - must_redraw = CLEAR; - } -#endif - if (set_group_colors((char_u *)"Scrollbar", - &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, - FALSE, FALSE, FALSE)) - { - gui_new_scrollbar_colors(); - must_redraw = CLEAR; - } -#endif -} - + } +#endif +#ifdef FEAT_TERMTRUECOLOR +# ifdef FEAT_GUI + else +# endif + { + int idx; + + idx = syn_name2id((char_u *)"Normal") - 1; + if (idx >= 0) + { + gui_do_one_color(idx, FALSE, FALSE); + + if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR) + { + cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; + must_redraw = CLEAR; + } + if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR) + { + cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; + must_redraw = CLEAR; + } + } + } +#endif +} +#endif + +#if defined(FEAT_GUI) || defined(PROTO) /* * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar". */ @@ -8299,24 +8351,6 @@ hl_set_fg_color_name( } /* - * Return the handle for a color name. - * Returns INVALCOLOR when failed. - */ - static guicolor_T -color_name2handle(char_u *name) -{ - if (STRCMP(name, "NONE") == 0) - return INVALCOLOR; - - if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) - return gui.norm_pixel; - if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) - return gui.back_pixel; - - return gui_get_color(name); -} - -/* * Return the handle for a font name. * Returns NOFONT when failed. */ @@ -8439,6 +8473,52 @@ hl_do_font( #endif /* FEAT_GUI */ +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) || defined(PROTO) +/* + * Return the handle for a color name. + * Returns INVALCOLOR when failed. + */ + static guicolor_T +color_name2handle(char_u *name) +{ + if (STRCMP(name, "NONE") == 0) + return INVALCOLOR; + + if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) + { +#if defined(FEAT_TERMTRUECOLOR) && defined(FEAT_GUI) + if (gui.in_use) +#endif +#ifdef FEAT_GUI + return gui.norm_pixel; +#endif +#if defined(FEAT_TERMTRUECOLOR) && defined(FEAT_GUI) + else +#endif +#ifdef FEAT_TERMTRUECOLOR + return cterm_normal_fg_gui_color; +#endif + } + if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) + { +#if defined(FEAT_TERMTRUECOLOR) && defined(FEAT_GUI) + if (gui.in_use) +#endif +#ifdef FEAT_GUI + return gui.back_pixel; +#endif +#if defined(FEAT_TERMTRUECOLOR) && defined(FEAT_GUI) + else +#endif +#ifdef FEAT_TERMTRUECOLOR + return cterm_normal_bg_gui_color; +#endif + } + + return GUI_GET_COLOR(name); +} +#endif + /* * Table with the specifications for an attribute number. * Note that this table is used by ALL buffers. This is required because the @@ -8514,8 +8594,15 @@ get_attr_entry(garray_T *table, attrentr && aep->ae_u.cterm.fg_color == taep->ae_u.cterm.fg_color && aep->ae_u.cterm.bg_color - == taep->ae_u.cterm.bg_color) - )) + == taep->ae_u.cterm.bg_color +#ifdef FEAT_TERMTRUECOLOR + && aep->ae_u.cterm.fg_rgb + == taep->ae_u.cterm.fg_rgb + && aep->ae_u.cterm.bg_rgb + == taep->ae_u.cterm.bg_rgb +#endif + + ))) return i + ATTR_OFF; } @@ -8580,6 +8667,10 @@ get_attr_entry(garray_T *table, attrentr { taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color; taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color; +#ifdef FEAT_TERMTRUECOLOR + taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb; + taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb; +#endif } ++table->ga_len; return (table->ga_len - 1 + ATTR_OFF); @@ -8671,7 +8762,7 @@ hl_combine_attr(int char_attr, int prim_ } #endif - if (t_colors > 1) + if (IS_CTERM) { if (char_attr > HL_ALL) char_aep = syn_cterm_attr2entry(char_attr); @@ -8696,6 +8787,12 @@ hl_combine_attr(int char_attr, int prim_ new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color; if (spell_aep->ae_u.cterm.bg_color > 0) new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color; +#ifdef FEAT_TERMTRUECOLOR + if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR) + new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb; + if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR) + new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb; +#endif } } return get_attr_entry(&cterm_attr_table, &new_en); @@ -8757,10 +8854,10 @@ syn_attr2attr(int attr) aep = syn_gui_attr2entry(attr); else #endif - if (t_colors > 1) - aep = syn_cterm_attr2entry(attr); - else - aep = syn_term_attr2entry(attr); + if (IS_CTERM) + aep = syn_cterm_attr2entry(attr); + else + aep = syn_term_attr2entry(attr); if (aep == NULL) /* highlighting not set */ return 0; @@ -8959,13 +9056,15 @@ highlight_color( return NULL; if (modec == 'g') { -# ifdef FEAT_GUI +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) +# ifdef FEAT_GUI /* return font name */ if (font) return HL_TABLE()[id - 1].sg_font_name; +# endif /* return #RRGGBB form (only possible when GUI is running) */ - if (gui.in_use && what[2] == '#') + if ((USE_24BIT) && what[2] == '#') { guicolor_T color; long_u rgb; @@ -8974,19 +9073,23 @@ highlight_color( if (fg) color = HL_TABLE()[id - 1].sg_gui_fg; else if (sp) +# ifdef FEAT_GUI color = HL_TABLE()[id - 1].sg_gui_sp; +# else + color = INVALCOLOR; +# endif else color = HL_TABLE()[id - 1].sg_gui_bg; if (color == INVALCOLOR) return NULL; - rgb = gui_mch_get_rgb(color); + rgb = GUI_MCH_GET_RGB(color); sprintf((char *)buf, "#%02x%02x%02x", (unsigned)(rgb >> 16), (unsigned)(rgb >> 8) & 255, (unsigned)rgb & 255); return buf; } -#endif +# endif if (fg) return (HL_TABLE()[id - 1].sg_gui_fg_name); if (sp) @@ -9011,8 +9114,9 @@ highlight_color( } #endif -#if (defined(FEAT_SYN_HL) && defined(FEAT_GUI) && defined(FEAT_PRINTER)) \ - || defined(PROTO) +#if (defined(FEAT_SYN_HL) \ + && (defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR)) \ + && defined(FEAT_PRINTER)) || defined(PROTO) /* * Return color name of highlight group "id" as RGB value. */ @@ -9034,7 +9138,7 @@ highlight_gui_color_rgb( if (color == INVALCOLOR) return 0L; - return gui_mch_get_rgb(color); + return GUI_MCH_GET_RGB(color); } #endif @@ -9150,13 +9254,22 @@ set_hl_attr( * For the color term mode: If there are other than "normal" * highlighting attributes, need to allocate an attr number. */ - if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0) + if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 +# ifdef FEAT_TERMTRUECOLOR + && sgp->sg_gui_fg == INVALCOLOR + && sgp->sg_gui_bg == INVALCOLOR +# endif + ) sgp->sg_cterm_attr = sgp->sg_cterm; else { at_en.ae_attr = sgp->sg_cterm; at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg; at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg; +# ifdef FEAT_TERMTRUECOLOR + at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB(sgp->sg_gui_fg); + at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB(sgp->sg_gui_bg); +# endif sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en); } } @@ -9307,10 +9420,12 @@ syn_add_group(char_u *name) vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(struct hl_group)); HL_TABLE()[highlight_ga.ga_len].sg_name = name; HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name); -#ifdef FEAT_GUI +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR; HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR; +# ifdef FEAT_GUI HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR; +# endif #endif ++highlight_ga.ga_len; @@ -9349,7 +9464,7 @@ syn_id2attr(int hl_id) attr = sgp->sg_gui_attr; else #endif - if (t_colors > 1) + if (IS_CTERM) attr = sgp->sg_cterm_attr; else attr = sgp->sg_term_attr; @@ -9403,7 +9518,7 @@ syn_get_final_id(int hl_id) return hl_id; } -#ifdef FEAT_GUI +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) /* * Call this function just after the GUI has started. * It finds the font and color handles for the highlighting groups. @@ -9414,7 +9529,12 @@ highlight_gui_started(void) int idx; /* First get the colors from the "Normal" and "Menu" group, if set */ - set_normal_colors(); +# if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) +# ifdef FEAT_TERMTRUECOLOR + if (USE_24BIT) +# endif + set_normal_colors(); +# endif for (idx = 0; idx < highlight_ga.ga_len; ++idx) gui_do_one_color(idx, FALSE, FALSE); @@ -9430,12 +9550,17 @@ gui_do_one_color( { int didit = FALSE; - if (HL_TABLE()[idx].sg_font_name != NULL) - { - hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, +# ifdef FEAT_GUI +# ifdef FEAT_TERMTRUECOLOR + if (gui.in_use) +# endif + if (HL_TABLE()[idx].sg_font_name != NULL) + { + hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, do_tooltip, TRUE); - didit = TRUE; - } + didit = TRUE; + } +# endif if (HL_TABLE()[idx].sg_gui_fg_name != NULL) { HL_TABLE()[idx].sg_gui_fg = @@ -9448,16 +9573,17 @@ gui_do_one_color( color_name2handle(HL_TABLE()[idx].sg_gui_bg_name); didit = TRUE; } +# ifdef FEAT_GUI if (HL_TABLE()[idx].sg_gui_sp_name != NULL) { HL_TABLE()[idx].sg_gui_sp = color_name2handle(HL_TABLE()[idx].sg_gui_sp_name); didit = TRUE; } +# endif if (didit) /* need to get a new attr number */ set_hl_attr(idx); } - #endif /* diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -77,6 +77,9 @@ struct builtin_term static struct builtin_term *find_builtin_term(char_u *name); static void parse_builtin_tcap(char_u *s); static void term_color(char_u *s, int n); +#ifdef FEAT_TERMTRUECOLOR +static void term_rgb_color(char_u *s, long_u rgb); +#endif static void gather_termleader(void); #ifdef FEAT_TERMRESPONSE static void req_codes_from_term(void); @@ -382,9 +385,9 @@ static struct builtin_term builtin_termc # else {(int)KS_CRI, "\033[%dC"}, # endif -#if defined(BEOS_DR8) +# if defined(BEOS_DR8) {(int)KS_DB, ""}, /* hack! see screen.c */ -#endif +# endif {K_UP, "\033[A"}, {K_DOWN, "\033[B"}, @@ -790,8 +793,10 @@ static struct builtin_term builtin_termc # endif # endif +# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__) || defined(FEAT_TERMTRUECOLOR) + {(int)KS_NAME, "xterm"}, +# endif # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__) - {(int)KS_NAME, "xterm"}, {(int)KS_CE, IF_EB("\033[K", ESC_STR "[K")}, {(int)KS_AL, IF_EB("\033[L", ESC_STR "[L")}, # ifdef TERMINFO @@ -939,6 +944,10 @@ static struct builtin_term builtin_termc {TERMCAP2KEY('F', 'Q'), IF_EB("\033[57;*~", ESC_STR "[57;*~")}, /* F36 */ {TERMCAP2KEY('F', 'R'), IF_EB("\033[58;*~", ESC_STR "[58;*~")}, /* F37 */ # endif +# ifdef FEAT_TERMTRUECOLOR + {(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")}, + {(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")}, +# endif # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) /* @@ -1257,6 +1266,171 @@ static struct builtin_term builtin_termc }; /* end of builtin_termcaps */ +#if defined(FEAT_TERMTRUECOLOR) || defined(PROTO) +# define RGB(r, g, b) ((r<<16) | (g<<8) | (b)) +struct rgbcolor_table_S { + char_u *color_name; + guicolor_T color; +}; +static struct rgbcolor_table_S rgb_table[] = { + {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, + {(char_u *)"blue", RGB(0x00, 0x00, 0xD4)}, + {(char_u *)"brown", RGB(0x80, 0x40, 0x40)}, + {(char_u *)"cyan", RGB(0x02, 0xAB, 0xEA)}, + {(char_u *)"darkblue", RGB(0x00, 0x00, 0x80)}, + {(char_u *)"darkcyan", RGB(0x00, 0x80, 0x80)}, + {(char_u *)"darkgray", RGB(0x80, 0x80, 0x80)}, + {(char_u *)"darkgreen", RGB(0x00, 0x80, 0x00)}, + {(char_u *)"darkgrey", RGB(0x80, 0x80, 0x80)}, + {(char_u *)"darkmagenta", RGB(0x80, 0x00, 0x80)}, + {(char_u *)"darkred", RGB(0x80, 0x00, 0x00)}, + {(char_u *)"darkyellow", RGB(0xBB, 0xBB, 0x00)}, + {(char_u *)"gray", RGB(0xC0, 0xC0, 0xC0)}, + {(char_u *)"gray10", RGB(0x1A, 0x1A, 0x1A)}, + {(char_u *)"gray20", RGB(0x33, 0x33, 0x33)}, + {(char_u *)"gray30", RGB(0x4D, 0x4D, 0x4D)}, + {(char_u *)"gray40", RGB(0x66, 0x66, 0x66)}, + {(char_u *)"gray50", RGB(0x7F, 0x7F, 0x7F)}, + {(char_u *)"gray60", RGB(0x99, 0x99, 0x99)}, + {(char_u *)"gray70", RGB(0xB3, 0xB3, 0xB3)}, + {(char_u *)"gray80", RGB(0xCC, 0xCC, 0xCC)}, + {(char_u *)"gray90", RGB(0xE5, 0xE5, 0xE5)}, + {(char_u *)"green", RGB(0x00, 0x64, 0x11)}, + {(char_u *)"grey", RGB(0xC0, 0xC0, 0xC0)}, + {(char_u *)"grey10", RGB(0x1A, 0x1A, 0x1A)}, + {(char_u *)"grey20", RGB(0x33, 0x33, 0x33)}, + {(char_u *)"grey30", RGB(0x4D, 0x4D, 0x4D)}, + {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)}, + {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)}, + {(char_u *)"grey60", RGB(0x99, 0x99, 0x99)}, + {(char_u *)"grey70", RGB(0xB3, 0xB3, 0xB3)}, + {(char_u *)"grey80", RGB(0xCC, 0xCC, 0xCC)}, + {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)}, + {(char_u *)"lightblue", RGB(0xA0, 0xA0, 0xFF)}, + {(char_u *)"lightcyan", RGB(0xA0, 0xFF, 0xFF)}, + {(char_u *)"lightgray", RGB(0xE0, 0xE0, 0xE0)}, + {(char_u *)"lightgreen", RGB(0xA0, 0xFF, 0xA0)}, + {(char_u *)"lightgrey", RGB(0xE0, 0xE0, 0xE0)}, + {(char_u *)"lightmagenta",RGB(0xF0, 0xA0, 0xF0)}, + {(char_u *)"lightred", RGB(0xFF, 0xA0, 0xA0)}, + {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xA0)}, + {(char_u *)"magenta", RGB(0xF2, 0x08, 0x84)}, + {(char_u *)"orange", RGB(0xFC, 0x80, 0x00)}, + {(char_u *)"purple", RGB(0xA0, 0x20, 0xF0)}, + {(char_u *)"red", RGB(0xDD, 0x08, 0x06)}, + {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)}, + {(char_u *)"slateblue", RGB(0x6A, 0x5A, 0xCD)}, + {(char_u *)"violet", RGB(0x8D, 0x38, 0xC9)}, + {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)}, + {(char_u *)"yellow", RGB(0xFC, 0xF3, 0x05)}, +}; + + static int +hex_digit(int c) +{ + if (isdigit(c)) + return c - '0'; + c = TOLOWER_ASC(c); + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0x1ffffff; +} + + guicolor_T +termtrue_mch_get_color(char_u *name) +{ + guicolor_T color; + int i; + + if (*name == '#' && strlen((char *) name) == 7) + { + color = RGB(((hex_digit(name[1])<<4) + hex_digit(name[2])), + ((hex_digit(name[3])<<4) + hex_digit(name[4])), + ((hex_digit(name[5])<<4) + hex_digit(name[6]))); + if (color > 0xffffff) + return INVALCOLOR; + return color; + } + else + { + /* Check if the name is one of the colors we know */ + for (i = 0; i < sizeof(rgb_table) / sizeof(rgb_table[0]); i++) + if (STRICMP(name, rgb_table[i].color_name) == 0) + return rgb_table[i].color; + } + + /* + * Last attempt. Look in the file "$VIM/rgb.txt". + */ + { +#define LINE_LEN 100 + FILE *fd; + char line[LINE_LEN]; + char_u *fname; + int r, g, b; + + fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); + if (fname == NULL) + return INVALCOLOR; + + fd = fopen((char *)fname, "rt"); + vim_free(fname); + if (fd == NULL) + return INVALCOLOR; + + while (!feof(fd)) + { + int len; + int pos; + char *color; + + fgets(line, LINE_LEN, fd); + len = strlen(line); + + if (len <= 1 || line[len-1] != '\n') + continue; + + line[len-1] = '\0'; + + i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); + if (i != 3) + continue; + + color = line + pos; + + if (STRICMP(color, name) == 0) + { + fclose(fd); + return (guicolor_T) RGB(r, g, b); + } + } + fclose(fd); + } + + return INVALCOLOR; +} + + guicolor_T +termtrue_get_color(char_u *name) +{ + guicolor_T t; + + if (*name == NUL) + return INVALCOLOR; + t = termtrue_mch_get_color(name); + + if (t == INVALCOLOR) + EMSG2(_("E254: Cannot allocate color %s"), name); + return t; +} + + long_u +termtrue_mch_get_rgb(guicolor_T color) +{ + return (long_u) color; +} +#endif + /* * DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM. */ @@ -1512,6 +1686,7 @@ set_termname(char_u *term) {KS_CWP, "WP"}, {KS_CWS, "WS"}, {KS_CSI, "SI"}, {KS_CEI, "EI"}, {KS_U7, "u7"}, {KS_RBG, "RB"}, + {KS_8F, "8f"}, {KS_8B, "8b"}, {(enum SpecialKey)0, NULL} }; @@ -2608,6 +2783,33 @@ term_color(char_u *s, int n) OUT_STR(tgoto((char *)s, 0, n)); } +#if defined(FEAT_TERMTRUECOLOR) || defined(PROTO) + void +term_fg_rgb_color(long_u rgb) +{ + term_rgb_color(T_8F, rgb); +} + + void +term_bg_rgb_color(long_u rgb) +{ + term_rgb_color(T_8B, rgb); +} + +#define RED(rgb) ((rgb>>16)&0xFF) +#define GREEN(rgb) ((rgb>> 8)&0xFF) +#define BLUE(rgb) ((rgb )&0xFF) + + static void +term_rgb_color(char_u *s, long_u rgb) +{ + char buf[7+3*3+2+1+1]; + + sprintf(buf, (char *)s, RED(rgb), GREEN(rgb), BLUE(rgb)); + OUT_STR(buf); +} +#endif + #if (defined(FEAT_TITLE) && (defined(UNIX) || defined(VMS) \ || defined(MACOS_X))) || defined(PROTO) /* diff --git a/src/term.h b/src/term.h --- a/src/term.h +++ b/src/term.h @@ -87,10 +87,12 @@ enum SpecialKey KS_CSV, /* scroll region vertical */ #endif KS_OP, /* original color pair */ - KS_U7 /* request cursor position */ + KS_U7, /* request cursor position */ + KS_8F, /* set foreground color (RGB) */ + KS_8B /* set background color (RGB) */ }; -#define KS_LAST KS_U7 +#define KS_LAST KS_8B /* * the terminal capabilities are stored in this array @@ -166,6 +168,8 @@ extern char_u *(term_strings[]); /* c #define T_RBG (term_str(KS_RBG)) /* request background RGB */ #define T_OP (term_str(KS_OP)) /* original color pair */ #define T_U7 (term_str(KS_U7)) /* request cursor position */ +#define T_8F (term_str(KS_8F)) /* set foreground color (RGB) */ +#define T_8B (term_str(KS_8B)) /* set background color (RGB) */ #define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */ #define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */ diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -621,6 +621,11 @@ static char *(features[]) = #else "-termresponse", #endif +#ifdef FEAT_TERMTRUECOLOR + "+termtruecolor", +#else + "-termtruecolor", +#endif #ifdef FEAT_TEXTOBJ "+textobjects", #else @@ -749,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1770, +/**/ 1769, /**/ 1768, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -1558,6 +1558,31 @@ typedef UINT32_TYPEDEF UINT32_T; #define MSG_PUTS_LONG(s) msg_puts_long_attr((char_u *)(s), 0) #define MSG_PUTS_LONG_ATTR(s, a) msg_puts_long_attr((char_u *)(s), (a)) +#ifdef FEAT_GUI +# ifdef FEAT_TERMTRUECOLOR +# define GUI_FUNCTION(f) (gui.in_use ? gui_##f : termtrue_##f) +# define USE_24BIT (gui.in_use || p_guicolors) +# else +# define GUI_FUNCTION(f) gui_##f +# define USE_24BIT gui.in_use +# endif +#else +# ifdef FEAT_TERMTRUECOLOR +# define GUI_FUNCTION(f) termtrue_##f +# define USE_24BIT p_guicolors +# endif +#endif +#ifdef FEAT_TERMTRUECOLOR +# define IS_CTERM (t_colors > 1 || p_guicolors) +#else +# define IS_CTERM (t_colors > 1) +#endif +#ifdef GUI_FUNCTION +# define GUI_MCH_GET_RGB GUI_FUNCTION(mch_get_rgb) +# define GUI_MCH_GET_COLOR GUI_FUNCTION(mch_get_color) +# define GUI_GET_COLOR GUI_FUNCTION(get_color) +#endif + /* Prefer using emsg3(), because perror() may send the output to the wrong * destination and mess up the screen. */ #ifdef HAVE_STRERROR