forked from aniani/vim
patch 8.0.1194: actual fg and bg colors of terminal are unknown
Problem: Actual fg and bg colors of terminal are unknown. Solution: Add t_RF. Store response to t_RB and t_RF, use for terminal.
This commit is contained in:
134
src/term.c
134
src/term.c
@@ -125,6 +125,17 @@ static int crv_status = STATUS_GET;
|
||||
/* Request Cursor position report: */
|
||||
static int u7_status = STATUS_GET;
|
||||
|
||||
#ifdef FEAT_TERMINAL
|
||||
/* Request foreground color report: */
|
||||
static int rfg_status = STATUS_GET;
|
||||
static int fg_r = 0;
|
||||
static int fg_g = 0;
|
||||
static int fg_b = 0;
|
||||
static int bg_r = 255;
|
||||
static int bg_g = 255;
|
||||
static int bg_b = 255;
|
||||
#endif
|
||||
|
||||
/* Request background color report: */
|
||||
static int rbg_status = STATUS_GET;
|
||||
|
||||
@@ -882,6 +893,7 @@ static struct builtin_term builtin_termcaps[] =
|
||||
{(int)KS_CGP, IF_EB("\033[13t", ESC_STR "[13t")},
|
||||
# endif
|
||||
{(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")},
|
||||
{(int)KS_RFG, IF_EB("\033]10;?\007", ESC_STR "]10;?\007")},
|
||||
{(int)KS_RBG, IF_EB("\033]11;?\007", ESC_STR "]11;?\007")},
|
||||
{(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")},
|
||||
# ifdef FEAT_TERMGUICOLORS
|
||||
@@ -1185,6 +1197,7 @@ static struct builtin_term builtin_termcaps[] =
|
||||
# endif
|
||||
{(int)KS_CRV, "[CRV]"},
|
||||
{(int)KS_U7, "[U7]"},
|
||||
{(int)KS_RFG, "[RFG]"},
|
||||
{(int)KS_RBG, "[RBG]"},
|
||||
{K_UP, "[KU]"},
|
||||
{K_DOWN, "[KD]"},
|
||||
@@ -1608,7 +1621,7 @@ set_termname(char_u *term)
|
||||
{KS_TS, "ts"}, {KS_FS, "fs"},
|
||||
{KS_CWP, "WP"}, {KS_CWS, "WS"},
|
||||
{KS_CSI, "SI"}, {KS_CEI, "EI"},
|
||||
{KS_U7, "u7"}, {KS_RBG, "RB"},
|
||||
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
|
||||
{KS_8F, "8f"}, {KS_8B, "8b"},
|
||||
{KS_CBE, "BE"}, {KS_CBD, "BD"},
|
||||
{KS_CPS, "PS"}, {KS_CPE, "PE"},
|
||||
@@ -3320,6 +3333,9 @@ settmode(int tmode)
|
||||
* them. */
|
||||
if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
|
||||
|| u7_status == STATUS_SENT
|
||||
#ifdef FEAT_TERMINAL
|
||||
|| rfg_status == STATUS_SENT
|
||||
#endif
|
||||
|| rbg_status == STATUS_SENT
|
||||
|| rbm_status == STATUS_SENT
|
||||
|| rcs_status == STATUS_SENT))
|
||||
@@ -3391,6 +3407,9 @@ stoptermcap(void)
|
||||
/* May need to discard T_CRV, T_U7 or T_RBG response. */
|
||||
if (crv_status == STATUS_SENT
|
||||
|| u7_status == STATUS_SENT
|
||||
# ifdef FEAT_TERMINAL
|
||||
|| rfg_status == STATUS_SENT
|
||||
# endif
|
||||
|| rbg_status == STATUS_SENT
|
||||
|| rbm_status == STATUS_SENT
|
||||
|| rcs_status == STATUS_SENT)
|
||||
@@ -3508,16 +3527,30 @@ may_req_bg_color(void)
|
||||
{
|
||||
if (can_get_termresponse() && starting == 0)
|
||||
{
|
||||
/* Only request background if t_RB is set and 'background' wasn't
|
||||
* changed. */
|
||||
if (rbg_status == STATUS_GET
|
||||
&& *T_RBG != NUL
|
||||
&& !option_was_set((char_u *)"bg"))
|
||||
int didit = FALSE;
|
||||
|
||||
#ifdef FEAT_TERMINAL
|
||||
/* Only request foreground if t_RF is set. */
|
||||
if (rfg_status == STATUS_GET && *T_RFG != NUL)
|
||||
{
|
||||
LOG_TR("Sending FG request");
|
||||
out_str(T_RFG);
|
||||
rfg_status = STATUS_SENT;
|
||||
didit = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only request background if t_RB is set. */
|
||||
if (rbg_status == STATUS_GET && *T_RBG != NUL)
|
||||
{
|
||||
LOG_TR("Sending BG request");
|
||||
out_str(T_RBG);
|
||||
rbg_status = STATUS_SENT;
|
||||
didit = TRUE;
|
||||
}
|
||||
|
||||
if (didit)
|
||||
{
|
||||
/* check for the characters now, otherwise they might be eaten by
|
||||
* get_keystroke() */
|
||||
out_flush();
|
||||
@@ -4688,46 +4721,72 @@ check_termcode(
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for background color response from the terminal:
|
||||
/* Check for fore/background color response from the terminal:
|
||||
*
|
||||
* {lead}11;rgb:{rrrr}/{gggg}/{bbbb}{tail}
|
||||
* {lead}{code};rgb:{rrrr}/{gggg}/{bbbb}{tail}
|
||||
*
|
||||
* {code} is 10 for foreground, 11 for background
|
||||
* {lead} can be <Esc>] or OSC
|
||||
* {tail} can be '\007', <Esc>\ or STERM.
|
||||
*
|
||||
* Consume any code that starts with "{lead}11;", it's also
|
||||
* possible that "rgba" is following.
|
||||
*/
|
||||
else if (*T_RBG != NUL
|
||||
else if ((*T_RBG != NUL || *T_RFG != NUL)
|
||||
&& ((tp[0] == ESC && len >= 2 && tp[1] == ']')
|
||||
|| tp[0] == OSC))
|
||||
{
|
||||
j = 1 + (tp[0] == ESC);
|
||||
if (len >= j + 3 && (argp[0] != '1'
|
||||
|| argp[1] != '1' || argp[2] != ';'))
|
||||
|| (argp[1] != '1' && argp[1] != '0')
|
||||
|| argp[2] != ';'))
|
||||
i = 0; /* no match */
|
||||
else
|
||||
for (i = j; i < len; ++i)
|
||||
if (tp[i] == '\007' || (tp[0] == OSC ? tp[i] == STERM
|
||||
: (tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')))
|
||||
{
|
||||
int is_bg = argp[1] == '1';
|
||||
|
||||
if (i - j >= 21 && STRNCMP(tp + j + 3, "rgb:", 4) == 0
|
||||
&& tp[j + 11] == '/' && tp[j + 16] == '/'
|
||||
&& !option_was_set((char_u *)"bg"))
|
||||
&& tp[j + 11] == '/' && tp[j + 16] == '/')
|
||||
{
|
||||
char *newval = (3 * '6' < tp[j+7] + tp[j+12]
|
||||
int rval = hexhex2nr(tp + j + 7);
|
||||
int gval = hexhex2nr(tp + j + 12);
|
||||
int bval = hexhex2nr(tp + j + 17);
|
||||
|
||||
if (is_bg)
|
||||
{
|
||||
char *newval = (3 * '6' < tp[j+7] + tp[j+12]
|
||||
+ tp[j+17]) ? "light" : "dark";
|
||||
|
||||
LOG_TR("Received RBG response");
|
||||
rbg_status = STATUS_GOT;
|
||||
if (STRCMP(p_bg, newval) != 0)
|
||||
{
|
||||
/* value differs, apply it */
|
||||
set_option_value((char_u *)"bg", 0L,
|
||||
LOG_TR("Received RBG response");
|
||||
rbg_status = STATUS_GOT;
|
||||
#ifdef FEAT_TERMINAL
|
||||
bg_r = rval;
|
||||
bg_g = gval;
|
||||
bg_b = bval;
|
||||
#endif
|
||||
if (!option_was_set((char_u *)"bg")
|
||||
&& STRCMP(p_bg, newval) != 0)
|
||||
{
|
||||
/* value differs, apply it */
|
||||
set_option_value((char_u *)"bg", 0L,
|
||||
(char_u *)newval, 0);
|
||||
reset_option_was_set((char_u *)"bg");
|
||||
redraw_asap(CLEAR);
|
||||
reset_option_was_set((char_u *)"bg");
|
||||
redraw_asap(CLEAR);
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_TERMINAL
|
||||
else
|
||||
{
|
||||
LOG_TR("Received RFG response");
|
||||
rfg_status = STATUS_GOT;
|
||||
fg_r = rval;
|
||||
fg_g = gval;
|
||||
fg_b = bval;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* got finished code: consume it */
|
||||
@@ -4735,7 +4794,8 @@ check_termcode(
|
||||
key_name[1] = (int)KE_IGNORE;
|
||||
slen = i + 1 + (tp[i] == ESC);
|
||||
# ifdef FEAT_EVAL
|
||||
set_vim_var_string(VV_TERMRGBRESP, tp, slen);
|
||||
set_vim_var_string(is_bg ? VV_TERMRBGRESP
|
||||
: VV_TERMRFGRESP, tp, slen);
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
@@ -5768,6 +5828,36 @@ check_termcode(
|
||||
return 0; /* no match found */
|
||||
}
|
||||
|
||||
#if defined(FEAT_TERMINAL) || defined(PROTO)
|
||||
/*
|
||||
* Get the text foreground color, if known.
|
||||
*/
|
||||
void
|
||||
term_get_fg_color(uint8_t *r, uint8_t *g, uint8_t *b)
|
||||
{
|
||||
if (rfg_status == STATUS_GOT)
|
||||
{
|
||||
*r = fg_r;
|
||||
*g = fg_g;
|
||||
*b = fg_b;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the text background color, if known.
|
||||
*/
|
||||
void
|
||||
term_get_bg_color(uint8_t *r, uint8_t *g, uint8_t *b)
|
||||
{
|
||||
if (rbg_status == STATUS_GOT)
|
||||
{
|
||||
*r = bg_r;
|
||||
*g = bg_g;
|
||||
*b = bg_b;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Replace any terminal code strings in from[] with the equivalent internal
|
||||
* vim representation. This is used for the "from" and "to" part of a
|
||||
|
||||
Reference in New Issue
Block a user