Skip to content
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

Choose Theme Based on The Terminal's Color Scheme #2896

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

bash
Copy link

@bash bash commented Mar 15, 2024

Resolves #1746

This PR is an alternative to #2797. The most notable difference is that this PR uses my own library terminal-colorsaurus instead of termbg.
Among other things, this solves (or at least softens) concerns around timeout / latency.

For additional background, see also my PR to delta: dandavison/delta#1615

Usage

As suggested in #1746, there are two new options with accompanying environment variables:

  • --theme-dark / BAT_THEME_DARK
  • --theme-light / BAT_THEME_LIGHT

By default, bat detects if the terminal is dark or light and uses --theme-<mode> or falls back to the default dark or light theme respectively.

If the detection fails, the terminal is treated as having a dark background.

The --theme option and BAT_THEME env var always overrides these new options for backwards compatibility and to have an easy way to disable color detection. As a consequence --theme=default always uses the default dark theme.

I also decided to add an option for controlling the color detection --detect-color-scheme. I don't think this is strictly necessary and I'm leaning on removing this. The only value that is not achievable through a combination of other options is --detect-color-scheme=always.

Latency and Terminal Support

terminal-colorsaurus includes Measurements for a couple of terminals, both terminals that support OSC 10/OSC 11 and some that don't.

For terminals that don't support OSC 10/OSC 11 querying for the color scheme usually takes well below 100 µs.

How does this work?

Colorsaurus sends two escape sequences: OSC 11 (the actual color querying sequence) followed by DA1 (which is supported by almost all terminals out there). Since terminals answer in the same order as the sequences were received we know that if we receive the answer to DA1 then the terminal does not support OSC 11 and can bail out early and avoid a long timeout.

For terminals that support OSC 10/OSC 11 there's a wide range of latency: Some terminals take less than 100 µs while others usually take around 30 ms.

Windows

Windows is not supported. Calling terminal-colorsaurus on windows is a no-op, so there's no added latency there.

macOS

I have completely removed the current detection via macOS system preferences as terminal-colorsaurus is correctly able to detect whether the terminal is dark or light. I saw dalance/termbg#8 referenced somewhere in the discussion, but I am unable to reproduce the issue. I am running macOS Ventura 13.6.4.

Open Questions

  • Should I keep --detect-color-scheme or remove it?
  • Is the additional startup cost acceptable?

@patbl
Copy link

patbl commented Mar 18, 2024

As suggested in #1746, there are two new options with accompanying environment variables:

  • --theme-dark / BAT_THEME_DARK
  • --theme-light / DELTA_THEME_LIGHT

I think there was a typo (the second one should probably be BAT_THEME_LIGHT).

@bash
Copy link
Author

bash commented Mar 18, 2024

@patbl Yep that's a typo, thanks :)

Lucky me, it's only in the PR description and not in the actual PR changes.

@sersorrel
Copy link

This seems to work well! I do need to specify --detect-color-scheme=always, though – I use bat via lesspipe, and without that flag (actually implemented locally as a patch to change the default, since lesspipe doesn't provide any way to send custom arguments to bat...) the detection doesn't run.

What is the downside of not always doing colour scheme detection? The code briefly mentions a race condition with pagers; am I just lucky to have not hit that myself? What would be the symptoms of this happening?

@bash
Copy link
Author

bash commented Apr 9, 2024

@sersorrel That's great to hear! I'm not familiar with lesspipe, how exactly do you combine bat with lesspipe? Do you pipe bat's output to less?

What is the downside of not always doing colour scheme detection? The code briefly mentions a race condition with pagers.

Yes, exactly :) You can observe the race condition when piping bat's output to less. In that case both processes are started (mostly) simultaneously and try to access the terminal at the same time (both color detection and less read from the terminal and enable / disable "raw mode").

Here's how I witness the race condition:
Run bat --detect-color-scheme always .editorconfig | less.
For me less sometimes won't recognize q for exiting.

@sersorrel
Copy link

sersorrel commented Apr 11, 2024

Honestly, I can't figure out exactly how lesspipe.sh invokes bat... The general mechanism is that less examines $LESSOPEN and pipes the file to it before displaying whatever it prints (whether for syntax highlighting or for e.g. displaying a list of files inside a .zip). lesspipe.sh is a generic script that, when invoked as $LESSOPEN, will look at the filename and apply syntax highlighting or whatever other filtering as appropriate.

I can't reproduce the race condition with that command, interestingly.

@bash
Copy link
Author

bash commented Apr 16, 2024

From a quick (and not thorough) peek at less' source code I think there's indeed no race condition in that case. Less waits for $LESSOPEN to complete before it starts to do its own input processing.

@bash bash force-pushed the dark-light branch 2 times, most recently from 01981dc to 4409c56 Compare April 16, 2024 12:46
Excerpt from the [changelog](https://github.com/bash/terminal-colorsaurus/blob/0.4.0/changelog.md):

> * ⚡ Renamed «color scheme» to «color palette».
> * ⚡ Removed `is_dark_on_light` and `is_light_on_dark` functions. Use `color_scheme` instead.
> * Add new convenience function `color_scheme` which returns a nice `Dark / Light` enum.
> * Add support for urxvt's `rgba:` color format.
> * Further refined the documentation (more organized terminal list, new terminals tested).
> * Improved handling of ambigous color palettes (e.g. when background color is the same as foreground).
> * Queries are now terminated with `ST` (the standard string terminator) instead of `BEL` (which is an xterm extension).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for different themes based on Terminal color scheme
3 participants