-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
TUI: detect background color #5027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Apparently vim already includes support for this, though neovim does not. Search for It looks like the terminal input handling drastically changed in neovim, making this hard to directly port over. I attached a WIP commit providing an implementation of this for neovim. It almost works: the background detection works perfectly, as does the setting of the default (so |
The TUI runs on a separate thread. Most likely that is the cause of the segfault.
This is because |
if (!option_was_set((char_u *)"bg")) { | ||
set_option_value((char_u *)"bg", 0, (char_u *)bgvalue, 0); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try putting this block in a function e.g. set_bg_color_deferred
, then schedule it on the main thread like this
loop_schedule(&main_loop, event_create(1, set_bg_color_deferred, ...));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure enough, that was the problem. New version momentarily.
c29dd00
to
50030e8
Compare
Just pushed a new version, which now works reliably thanks to @justinmk's advice about running on the main loop. |
LGTM. Is there a termcode to set the background? It could be used to |
Yes, the same code the terminal writes back to the application:
Looking at tui_spec.lua, it seems possible to add tests for this: just feed the terminal the escape sequences for various colors, followed by |
This comment has been minimized.
This comment has been minimized.
50030e8
to
0a30531
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I'm not sure why varying subsets of the tests fail on some platforms, while some of the tests pass. I don't know what would cause spurious test failures. Is it a race condition to send the control sequence that will change the background, followed by |
One interesting caveat about this change: setting the background causes a redraw, which dismisses the vim intro message. So if you run on a terminal that supports background color detection, and you don't already have |
} else if (isxdigit(c)) { | ||
if (component < 3 && rgb_max[component] != 0xffff) { | ||
uint16_t digit = (uint16_t)((c >= '0' && c <= '9') | ||
? c - '0' : 10 + tolower(c) - 'a'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hex2nr()
in charset.h
could be used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks; done.
xterm-compatible terminals support reporting their configured colors back to the application. Use this to obtain the current background color, compute its luminance to classify it as light or dark, and set 'bg' accordingly. Also set the default for 'bg', so that `:set bg&` will revert to that detected default.
0a30531
to
5372d9a
Compare
} else if (bad) { | ||
// ignore | ||
} else if (c == '/') { | ||
if (component < 3) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the sequence not already bad if we see three '/'
? Should bad
be set?
@joshtriplett Any comment on @oni-link's question? And could you rebase this? |
Merged in #9509 |
(Also reported as a vim issue, though I have more hope of a fix here.)
Vim's automatic background color detection works in GUI mode, but not in a terminal.
On any xterm-compatible terminal, vim could detect the background color via terminal escapes (documented in http://invisible-island.net/xterm/ctlseqs/ctlseqs.html) and use that to automatically detect whether to use
bg=dark
orbg=light
(by default or with:set bg&
).To detect the background color:
\e]11;COLOR\a
(or equivalent using OSC instead of\e]
for the escape, and ST or\e\\
instead of\a
for the terminator, which the existing terminal escape sequence handling probably already handles). If the COLOR portion matchesrgb:RRRR/GGGG/BBBB
where R, G, and B are hex digits, then compute the luminance 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.