mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 17:36:29 +00:00
TUI: rework background-color detection
- Like Vim, use set_option_value() followed by reset_option_was_set(). - Do not use set_string_default(), so the default is predictable. This affects `:set bg&`. - Wait until end-of-startup (VimEnter) to handle the response. The response is racey anyways, so timing is irrelevant. This allows OptionSet to be triggered, unlike during startup.
This commit is contained in:
@@ -83,10 +83,10 @@ EXTERN struct nvim_stats_s {
|
||||
int64_t redraw;
|
||||
} g_stats INIT(= { 0, 0 });
|
||||
|
||||
/* Values for "starting" */
|
||||
#define NO_SCREEN 2 /* no screen updating yet */
|
||||
#define NO_BUFFERS 1 /* not all buffers loaded yet */
|
||||
/* 0 not starting anymore */
|
||||
// Values for "starting".
|
||||
#define NO_SCREEN 2 // no screen updating yet
|
||||
#define NO_BUFFERS 1 // not all buffers loaded yet
|
||||
// 0 not starting anymore
|
||||
|
||||
/*
|
||||
* Number of Rows and Columns in the screen.
|
||||
|
@@ -883,7 +883,7 @@ set_options_default (
|
||||
/// @param name The name of the option
|
||||
/// @param val The value of the option
|
||||
/// @param allocated If true, do not copy default as it was already allocated.
|
||||
void set_string_default(const char *name, char *val, bool allocated)
|
||||
static void set_string_default(const char *name, char *val, bool allocated)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
int opt_idx = findoption(name);
|
||||
|
@@ -357,12 +357,28 @@ static bool handle_forced_escape(TermInput *input)
|
||||
static void set_bg_deferred(void **argv)
|
||||
{
|
||||
char *bgvalue = argv[0];
|
||||
set_string_default("bg", bgvalue, false);
|
||||
if (!option_was_set("bg")) {
|
||||
set_option_value("bg", 0, bgvalue, 0);
|
||||
if (starting) {
|
||||
// Wait until after startup, so OptionSet is triggered.
|
||||
loop_schedule(&main_loop, event_create(set_bg_deferred, 1, bgvalue));
|
||||
return;
|
||||
}
|
||||
if (!option_was_set("bg") && !strequal((char *)p_bg, bgvalue)) {
|
||||
// Value differs, apply it.
|
||||
set_option_value("bg", 0L, bgvalue, 0);
|
||||
reset_option_was_set("bg");
|
||||
}
|
||||
}
|
||||
|
||||
// During startup, tui.c requests the background color (see `ext.get_bg`).
|
||||
//
|
||||
// Here in input.c, we watch for the terminal response `\e]11;COLOR\a`. If
|
||||
// COLOR matches `rgb:RRRR/GGGG/BBBB` where R, G, and B are hex digits, then
|
||||
// compute the luminance[1] of the RGB color and classify it as light/dark
|
||||
// accordingly. Note that the color components may have anywhere from one to
|
||||
// four hex digits, and require scaling accordingly as values out of 4, 8, 12,
|
||||
// or 16 bits.
|
||||
//
|
||||
// [1] https://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
static bool handle_background_color(TermInput *input)
|
||||
{
|
||||
size_t count = 0;
|
||||
@@ -407,7 +423,10 @@ static bool handle_background_color(TermInput *input)
|
||||
double b = (double)rgb[2] / (double)rgb_max[2];
|
||||
double luminance = (0.299 * r) + (0.587 * g) + (0.114 * b); // CCIR 601
|
||||
char *bgvalue = luminance < 0.5 ? "dark" : "light";
|
||||
DLOG("bg response: %s", bgvalue);
|
||||
loop_schedule(&main_loop, event_create(set_bg_deferred, 1, bgvalue));
|
||||
} else {
|
||||
DLOG("failed to parse bg response");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -836,6 +836,28 @@ describe('TUI background color', function()
|
||||
..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]')
|
||||
end)
|
||||
|
||||
it("triggers OptionSet event on terminal-response", function()
|
||||
feed_data('\027:autocmd OptionSet background echo "did OptionSet, yay!"\n')
|
||||
|
||||
-- The child Nvim is running asynchronously; wait for it to register the
|
||||
-- OptionSet handler.
|
||||
feed_data('\027:autocmd OptionSet\n')
|
||||
screen:expect({any='--- Autocommands ---'})
|
||||
|
||||
feed_data('\012') -- CTRL-L: clear the screen
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
{4:~ }|
|
||||
{4:~ }|
|
||||
{4:~ }|
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed_data('\027]11;rgb:ffff/ffff/ffff\007')
|
||||
screen:expect{any='did OptionSet, yay!'}
|
||||
end)
|
||||
|
||||
local function assert_bg(color, bg)
|
||||
it('handles '..color..' as '..bg, function()
|
||||
feed_data('\027]11;rgb:'..color..'\007:echo &background\n')
|
||||
|
Reference in New Issue
Block a user