@@ -125,6 +125,17 @@ static int crv_status = STATUS_GET;
125125/* Request Cursor position report: */
126126static int u7_status = STATUS_GET ;
127127
128+ #ifdef FEAT_TERMINAL
129+ /* Request foreground color report: */
130+ static int rfg_status = STATUS_GET ;
131+ static int fg_r = 0 ;
132+ static int fg_g = 0 ;
133+ static int fg_b = 0 ;
134+ static int bg_r = 255 ;
135+ static int bg_g = 255 ;
136+ static int bg_b = 255 ;
137+ #endif
138+
128139/* Request background color report: */
129140static int rbg_status = STATUS_GET ;
130141
@@ -882,6 +893,7 @@ static struct builtin_term builtin_termcaps[] =
882893 {(int )KS_CGP , IF_EB ("\033[13t" , ESC_STR "[13t" )},
883894# endif
884895 {(int )KS_CRV , IF_EB ("\033[>c" , ESC_STR "[>c" )},
896+ {(int )KS_RFG , IF_EB ("\033]10;?\007" , ESC_STR "]10;?\007" )},
885897 {(int )KS_RBG , IF_EB ("\033]11;?\007" , ESC_STR "]11;?\007" )},
886898 {(int )KS_U7 , IF_EB ("\033[6n" , ESC_STR "[6n" )},
887899# ifdef FEAT_TERMGUICOLORS
@@ -1185,6 +1197,7 @@ static struct builtin_term builtin_termcaps[] =
11851197# endif
11861198 {(int )KS_CRV , "[CRV]" },
11871199 {(int )KS_U7 , "[U7]" },
1200+ {(int )KS_RFG , "[RFG]" },
11881201 {(int )KS_RBG , "[RBG]" },
11891202 {K_UP , "[KU]" },
11901203 {K_DOWN , "[KD]" },
@@ -1608,7 +1621,7 @@ set_termname(char_u *term)
16081621 {KS_TS , "ts" }, {KS_FS , "fs" },
16091622 {KS_CWP , "WP" }, {KS_CWS , "WS" },
16101623 {KS_CSI , "SI" }, {KS_CEI , "EI" },
1611- {KS_U7 , "u7" }, {KS_RBG , "RB" },
1624+ {KS_U7 , "u7" }, {KS_RFG , "RF" }, { KS_RBG , "RB" },
16121625 {KS_8F , "8f" }, {KS_8B , "8b" },
16131626 {KS_CBE , "BE" }, {KS_CBD , "BD" },
16141627 {KS_CPS , "PS" }, {KS_CPE , "PE" },
@@ -3320,6 +3333,9 @@ settmode(int tmode)
33203333 * them. */
33213334 if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
33223335 || u7_status == STATUS_SENT
3336+ #ifdef FEAT_TERMINAL
3337+ || rfg_status == STATUS_SENT
3338+ #endif
33233339 || rbg_status == STATUS_SENT
33243340 || rbm_status == STATUS_SENT
33253341 || rcs_status == STATUS_SENT ))
@@ -3391,6 +3407,9 @@ stoptermcap(void)
33913407 /* May need to discard T_CRV, T_U7 or T_RBG response. */
33923408 if (crv_status == STATUS_SENT
33933409 || u7_status == STATUS_SENT
3410+ # ifdef FEAT_TERMINAL
3411+ || rfg_status == STATUS_SENT
3412+ # endif
33943413 || rbg_status == STATUS_SENT
33953414 || rbm_status == STATUS_SENT
33963415 || rcs_status == STATUS_SENT )
@@ -3508,16 +3527,30 @@ may_req_bg_color(void)
35083527{
35093528 if (can_get_termresponse () && starting == 0 )
35103529 {
3511- /* Only request background if t_RB is set and 'background' wasn't
3512- * changed. */
3513- if (rbg_status == STATUS_GET
3514- && * T_RBG != NUL
3515- && !option_was_set ((char_u * )"bg" ))
3530+ int didit = FALSE;
3531+
3532+ #ifdef FEAT_TERMINAL
3533+ /* Only request foreground if t_RF is set. */
3534+ if (rfg_status == STATUS_GET && * T_RFG != NUL )
3535+ {
3536+ LOG_TR ("Sending FG request" );
3537+ out_str (T_RFG );
3538+ rfg_status = STATUS_SENT ;
3539+ didit = TRUE;
3540+ }
3541+ #endif
3542+
3543+ /* Only request background if t_RB is set. */
3544+ if (rbg_status == STATUS_GET && * T_RBG != NUL )
35163545 {
35173546 LOG_TR ("Sending BG request" );
35183547 out_str (T_RBG );
35193548 rbg_status = STATUS_SENT ;
3549+ didit = TRUE;
3550+ }
35203551
3552+ if (didit )
3553+ {
35213554 /* check for the characters now, otherwise they might be eaten by
35223555 * get_keystroke() */
35233556 out_flush ();
@@ -4688,54 +4721,81 @@ check_termcode(
46884721 }
46894722 }
46904723
4691- /* Check for background color response from the terminal:
4724+ /* Check for fore/ background color response from the terminal:
46924725 *
4693- * {lead}11 ;rgb:{rrrr}/{gggg}/{bbbb}{tail}
4726+ * {lead}{code} ;rgb:{rrrr}/{gggg}/{bbbb}{tail}
46944727 *
4728+ * {code} is 10 for foreground, 11 for background
46954729 * {lead} can be <Esc>] or OSC
46964730 * {tail} can be '\007', <Esc>\ or STERM.
46974731 *
46984732 * Consume any code that starts with "{lead}11;", it's also
46994733 * possible that "rgba" is following.
47004734 */
4701- else if (* T_RBG != NUL
4735+ else if (( * T_RBG != NUL || * T_RFG != NUL )
47024736 && ((tp [0 ] == ESC && len >= 2 && tp [1 ] == ']' )
47034737 || tp [0 ] == OSC ))
47044738 {
47054739 j = 1 + (tp [0 ] == ESC );
47064740 if (len >= j + 3 && (argp [0 ] != '1'
4707- || argp [1 ] != '1' || argp [2 ] != ';' ))
4741+ || (argp [1 ] != '1' && argp [1 ] != '0' )
4742+ || argp [2 ] != ';' ))
47084743 i = 0 ; /* no match */
47094744 else
47104745 for (i = j ; i < len ; ++ i )
47114746 if (tp [i ] == '\007' || (tp [0 ] == OSC ? tp [i ] == STERM
47124747 : (tp [i ] == ESC && i + 1 < len && tp [i + 1 ] == '\\' )))
47134748 {
4749+ int is_bg = argp [1 ] == '1' ;
4750+
47144751 if (i - j >= 21 && STRNCMP (tp + j + 3 , "rgb:" , 4 ) == 0
4715- && tp [j + 11 ] == '/' && tp [j + 16 ] == '/'
4716- && !option_was_set ((char_u * )"bg" ))
4752+ && tp [j + 11 ] == '/' && tp [j + 16 ] == '/' )
47174753 {
4718- char * newval = (3 * '6' < tp [j + 7 ] + tp [j + 12 ]
4719- + tp [j + 17 ]) ? "light" : "dark" ;
4754+ int rval = hexhex2nr (tp + j + 7 );
4755+ int gval = hexhex2nr (tp + j + 12 );
4756+ int bval = hexhex2nr (tp + j + 17 );
47204757
4721- LOG_TR ("Received RBG response" );
4722- rbg_status = STATUS_GOT ;
4723- if (STRCMP (p_bg , newval ) != 0 )
4758+ if (is_bg )
47244759 {
4725- /* value differs, apply it */
4726- set_option_value ((char_u * )"bg" , 0L ,
4760+ char * newval = (3 * '6' < tp [j + 7 ] + tp [j + 12 ]
4761+ + tp [j + 17 ]) ? "light" : "dark" ;
4762+
4763+ LOG_TR ("Received RBG response" );
4764+ rbg_status = STATUS_GOT ;
4765+ #ifdef FEAT_TERMINAL
4766+ bg_r = rval ;
4767+ bg_g = gval ;
4768+ bg_b = bval ;
4769+ #endif
4770+ if (!option_was_set ((char_u * )"bg" )
4771+ && STRCMP (p_bg , newval ) != 0 )
4772+ {
4773+ /* value differs, apply it */
4774+ set_option_value ((char_u * )"bg" , 0L ,
47274775 (char_u * )newval , 0 );
4728- reset_option_was_set ((char_u * )"bg" );
4729- redraw_asap (CLEAR );
4776+ reset_option_was_set ((char_u * )"bg" );
4777+ redraw_asap (CLEAR );
4778+ }
4779+ }
4780+ #ifdef FEAT_TERMINAL
4781+ else
4782+ {
4783+ LOG_TR ("Received RFG response" );
4784+ rfg_status = STATUS_GOT ;
4785+ fg_r = rval ;
4786+ fg_g = gval ;
4787+ fg_b = bval ;
47304788 }
4789+ #endif
47314790 }
47324791
47334792 /* got finished code: consume it */
47344793 key_name [0 ] = (int )KS_EXTRA ;
47354794 key_name [1 ] = (int )KE_IGNORE ;
47364795 slen = i + 1 + (tp [i ] == ESC );
47374796# ifdef FEAT_EVAL
4738- set_vim_var_string (VV_TERMRGBRESP , tp , slen );
4797+ set_vim_var_string (is_bg ? VV_TERMRBGRESP
4798+ : VV_TERMRFGRESP , tp , slen );
47394799# endif
47404800 break ;
47414801 }
@@ -5768,6 +5828,36 @@ check_termcode(
57685828 return 0 ; /* no match found */
57695829}
57705830
5831+ #if defined(FEAT_TERMINAL ) || defined(PROTO )
5832+ /*
5833+ * Get the text foreground color, if known.
5834+ */
5835+ void
5836+ term_get_fg_color (uint8_t * r , uint8_t * g , uint8_t * b )
5837+ {
5838+ if (rfg_status == STATUS_GOT )
5839+ {
5840+ * r = fg_r ;
5841+ * g = fg_g ;
5842+ * b = fg_b ;
5843+ }
5844+ }
5845+
5846+ /*
5847+ * Get the text background color, if known.
5848+ */
5849+ void
5850+ term_get_bg_color (uint8_t * r , uint8_t * g , uint8_t * b )
5851+ {
5852+ if (rbg_status == STATUS_GOT )
5853+ {
5854+ * r = bg_r ;
5855+ * g = bg_g ;
5856+ * b = bg_b ;
5857+ }
5858+ }
5859+ #endif
5860+
57715861/*
57725862 * Replace any terminal code strings in from[] with the equivalent internal
57735863 * vim representation. This is used for the "from" and "to" part of a
0 commit comments