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

Default theme compatible with light/dark terminals #1104

Closed
hoffa opened this issue Jul 8, 2020 · 29 comments · Fixed by #1412
Closed

Default theme compatible with light/dark terminals #1104

hoffa opened this issue Jul 8, 2020 · 29 comments · Fixed by #1412
Labels
feature-request New feature or request

Comments

@hoffa
Copy link

hoffa commented Jul 8, 2020

Hi! 👋
First of all, thanks for making such a great tool!

One reason preventing me from using bat much is because there's no theme that's readable on both light and dark terminals. For instance, the default theme shows text as white, which is invisible on a white background.

I think this might be fairly common use case, as macOS' default terminal theme automatically switches between light/dark as the system theme changes.

I wonder if there's any plans of making the default theme compatible with both types of terminals? I think one major improvement would be to show text in the default text color, instead of white.

I'd be happy to help if this would seem reasonable.

@hoffa hoffa added the feature-request New feature or request label Jul 8, 2020
@sharkdp
Copy link
Owner

sharkdp commented Jul 9, 2020

@hoffa
Copy link
Author

hoffa commented Jul 9, 2020

That’s good to know, thanks! It’ll only work on macOS however, and I’m sure people like to use bat in a variety of environments.

@skyfaller
Copy link

skyfaller commented Jul 23, 2020

I recently moved to Linux (Pop OS, i.e. Gnome with Pop Shell) from macOS and I am switching between dark mode and light mode. Bat stands out as a program I use constantly that doesn't play well with my light mode daytime theme.

@sharkdp
Copy link
Owner

sharkdp commented Jul 25, 2020

How do other programs detect dark mode? Does your terminal style change? Do other terminal programs react to the change?

@skyfaller
Copy link

In Gnome Terminal, in my profile -> Colors -> Text and Background Color, I checked "Use colors from system theme", which makes it respect Dark Mode. The terminal background and text colors change as the system theme changes between light and dark themes.

Web pages in web browsers use the prefers-color-scheme media query but I'm not sure if that's relevant here.

@sharkdp
Copy link
Owner

sharkdp commented Jul 25, 2020

In Gnome Terminal, in my profile -> Colors -> Text and Background Color, I checked "Use colors from system theme", which makes it respect Dark Mode. The terminal background and text colors change as the system theme changes between light and dark themes.

If the terminal theme changes, you could use bats base16 theme (which changes with the terminal theme). It's not ideal though, as the color choice is severely limited.

A better choice would be to automatically select a pre-configured dark/light theme (like Monokai vs. GitHub). But this would require us to somehow get a hold of that Gnome property.

@skyfaller
Copy link

Here's an interesting thread on detecting the terminal background color: https://unix.stackexchange.com/questions/245378/common-environment-variable-to-set-dark-or-light-terminal-background

I'm not knowledgeable enough to know if this is useful info.

@hoffa
Copy link
Author

hoffa commented Jul 26, 2020

The easiest way support both light and dark themes is to use the standard ANSI colors, default text color for text (i.e. not explicitly specify white or black), and no background color.

@sharkdp
Copy link
Owner

sharkdp commented Jul 26, 2020

The easiest way support both light and dark themes is to use the standard ANSI colors, default text color for text (i.e. not explicitly specify white or black), and no background color.

Maybe. But it's also a way that restricts the color output to 256 colors. Something that I simply refuse to fall back to (as a standard / by default) in 2020.

I didn't do any extensive research, but I guess there could be a way to query the current theme with something like

gsettings get org.gnome.desktop.interface gtk-theme

@hoffa
Copy link
Author

hoffa commented Jul 26, 2020

Meanwhile, here's an alternative that displays nicely on any old light/dark ANSI terminal:

wat() { 
    if [ -t 1 ]; then
        highlight --force --stdout -O ansi "$@" | less -RFX
    else
        cat "$@"
    fi
}

Requires brew install highlight or whatever your package manager is.

@skyfaller
Copy link

I didn't do any extensive research, but I guess there could be a way to query the current theme with something like

gsettings get org.gnome.desktop.interface gtk-theme

That appears to work for me, the light theme is 'Pop' and the dark theme is 'Pop-dark'. Now what do we do with that info? :)

@eth-p
Copy link
Collaborator

eth-p commented Jul 29, 2020

gsettings get org.gnome.desktop.interface gtk-theme

That appears to work for me, the light theme is 'Pop' and the dark theme is 'Pop-dark'. Now what do we do with that info? :)

A wrapper command could work:

bat() {
    local sys_theme="$(gsettings get org.gnome.desktop.interface gtk-theme)"
    local bat_theme
    case "${sys_theme}" in
    "Pop") bat_theme="GitHub" ;;
    "Pop-dark") bat_theme="default" ;;
    *) bat_theme="default" ;;
    esac
    command bat --theme="${bat_theme}"
}

If you add that to your bash profile, it should work just by using the bat command as usual.

@Nemo157
Copy link

Nemo157 commented Aug 10, 2020

But it's also a way that restricts the color output to 256 colors.

This is a good thing. It means that you have consistent colors throughout your terminal usage, instead of each CLI utility using its own themes with clashing colors; and when you want to change theme you can do so in one location instead of having to recustomise every single utility.

I've given up on having utilities that work correctly across light and dark backgrounds and have reconfigured my light themes so that white -> black and black -> white, but defaulting to ansi-dark would at least get you most of the way there to supporting users custom terminal themes without configuration.

@sharkdp
Copy link
Owner

sharkdp commented Aug 15, 2020

This is a good thing. It means that you have consistent colors throughout your terminal usage, instead of each CLI utility using its own themes with clashing colors

You can still have widely different themes with 256 colors. Maybe what you meant are the base 16 colors that are usually customized to a certain theme? (the 256 colors can also be customized, but usually are not).

but defaulting to ansi-dark would at least get you most of the way there to supporting users custom terminal themes without configuration

The problem with the base16 (and even the 256 color) themes is that I find that really limiting. I'm old enough to remember the times when I was able to switch Windows from 256 to "true color". And I do not want to go back there. Using 24bit colors should be a standard.

In any case, bat leaves the choice to the user. It's also really easy to change a theme.

@sharkdp
Copy link
Owner

sharkdp commented Sep 20, 2020

Closing this for now, as I don't see what we could do inside bat.

@sharkdp sharkdp closed this as completed Sep 20, 2020
@skyfaller
Copy link

skyfaller commented Sep 30, 2020

If anyone's curious, here's what I did with fish shell in Gnome Terminal. I wrote a function I called theme_bat:

function theme_bat
    switch (gsettings get org.gnome.desktop.interface gtk-theme)
    case "'Pop'"
        set -gx BAT_THEME GitHub
    case "'Pop-dark'"
        set -gx BAT_THEME default
    case '*'
        echo "I don't recognize the GTK theme"
    end
end

Then in Gnome Terminal, I went to Preferences -> Profiles -> MyThemeName -> Command, checked "Run a custom command instead of my shell" and for my custom command I entered /usr/bin/fish -c 'theme_bat';/usr/bin/fish.

This means when I open Gnome Terminal in my default theme, it first runs a script that checks whether the GTK theme is light or dark, then sets the $BAT_THEME shell variable to the appropriate theme. Then it runs my regular shell.

Note that this doesn't affect other terminal emulators such as Alacritty (which doesn't currently integrate with the GTK light/dark mode), they can continue with the default bat theme or whatever configuration is best for them.

@leiflm
Copy link

leiflm commented Nov 20, 2020

Alternative 1: Gnome Night Mode + Shell alias

  1. Create a shell script (i.e. ~/.local/bin/is_night):
#!/usr/bin/env bash

# This relies on the user defined time window within Gnome Night Mode settings.
NOW=$(date +'%H.0')
NIGHT_TIME_START=$(gsettings get org.gnome.settings-daemon.plugins.color night-light-schedule-from)
NIGHT_TIME_END=$(gsettings get org.gnome.settings-daemon.plugins.color night-light-schedule-to)

# d=day n=night
function isNight()
{
  if [ $(echo "${NIGHT_TIME_START} < ${NIGHT_TIME_END}" | bc -q) == 1 ]
  then
    # pattern: dnd
    OP='-a'
  else 
    # pattern: ndn
    OP='-o'
  fi

  [ $(echo "${NOW} > ${NIGHT_TIME_START}" | bc -q) == 1  "$OP"  $(echo "${NOW} < ${NIGHT_TIME_END}" | bc -q) == 1 ]
}

isNight

Make sure ~/.local/bin is part of your $PATH and the script is executable. Then adjust the suggested shell alias as follows:

alias cat="bat --theme=\$(is_night && echo myNightTheme || echo myDayTheme)"

Alternative 2: Use Gnome Extension and modify bat's config file

Here is another, maybe more consistent way, to handle the switch, that is based on the Night Theme Switcher extension for the Gnome Shell.

Create the script night_mode, mark it executable and a link to it called day_mode:

#!/usr/bin/env bash

update_bat()
{
  CONFIG_FILE_PATH="$(bat --config-file)"
  THEME="${1/day/GitHub}"
  THEME="${THEME/night/1337}"
  
  if [ ! -f "$CONFIG_FILE_PATH" ]
  then
    bat --generate-config-file
    if [ ! -f "$CONFIG_FILE_PATH" ]
    then
      echo "Could neither find nor create config file \"$CONFIG_FILE_PATH\""
      exit 1
    fi
  fi
  
  # switch bat
  sed --in-place "s/^--theme=.*$/--theme=$THEME/"  "$CONFIG_FILE_PATH"
}

SCRIPT_NAME=$(basename $0)
MODE=${SCRIPT_NAME/%_mode/} 

echo "Switching to $MODE mode"
update_bat $MODE

Then configure the scripts to be executed by the Night Switch Shell Extension on night/day switch respectively.

@hoffa
Copy link
Author

hoffa commented Nov 20, 2020

Thanks for all the workarounds!

I still think bat should be able to provide a theme that only uses ANSI colors, so that (1) it automatically works with light and dark terminals without hacks, and (2) works consistently on any ANSI terminal (even in a vanilla tmux) without the dependency on special terminal capabilities (e.g. 256 colors), which often aren't the default. This is how most UNIX tools with colors work.

@sharkdp
Copy link
Owner

sharkdp commented Nov 23, 2020

@hoffa Isn't that covered by one of the base16 themes? See https://github.com/sharkdp/bat#8-bit-themes

@hoffa
Copy link
Author

hoffa commented Nov 23, 2020

@sharkdp It's very close! The only problem I see is that they use a hardcoded color for normal text (i.e. explicitly specifying text as black or white), instead of using the terminal default (\033[0m). This means ansi-dark and base16 aren't really legible on a light terminal, and ansi-light isn't really legible on a dark terminal.

@wimstefan
Copy link

For that purpose you can use any of the examples above to switch the theme from ansi-dark to ansi-light and the other way around. I do the same with a script using sed ... you could also create two config files for both dark and light versions and a symbolic link to one of those files depending on the daytime. Good enough for me.

@sharkdp
Copy link
Owner

sharkdp commented Nov 29, 2020

@hoffa I see, thank you for the information. @mk12 FYI - If you are interested. Do you think we could somehow achieve that for the base16 themes? I guess it would require special handling in bat itself, not just the theme.

@mk12
Copy link
Contributor

mk12 commented Nov 29, 2020

This is a good thing. It means that you have consistent colors throughout your terminal usage, instead of each CLI utility using its own themes with clashing colors; and when you want to change theme you can do so in one location instead of having to recustomise every single utility.

I'm sympathetic to this view. I want my terminal to be a controlled environment, not like a web browser. I configure the terminal's font in one place, not in every CLI app's config, and I expect it to be the same with color palettes. It's a tradeoff, but I think 16 colors is more than enough for syntax highlighting. (There are cases where it really does feel limiting, e.g. for delta to overlay syntax & diff highlighting your palette would also need "muted red bg", "muted green bg", etc.)

@mk12 FYI - If you are interested. Do you think we could somehow achieve that for the base16 themes? I guess it would require special handling in bat itself, not just the theme.

I propose deprecating ansi-light and ansi-dark, replacing them with a single ansi theme that works for both. All it needs to do is use default fg/bg instead of white/black. I'll give it a shot now.

@sharkdp
Copy link
Owner

sharkdp commented Feb 28, 2021

This is now available in bat v0.18.

@fregante
Copy link

This is now available in bat v0.18.

What is available exactly?

What I see is that bat does not work out of the box on the default macOS terminal theme. Asking users to customize a tool out of the box to make it work suggests that it does not have good defaults. This is what I see.

Screen Shot 4

I suggest having a better default theme that works regardless of the terminal theme, just like every other CLI tool does (HTTPie comes to mind)

@Enselic
Copy link
Collaborator

Enselic commented Apr 17, 2021

What is available exactly?

New in bat 0.18.0 is a theme that works with both Light and Dark
mode in e.g. macOS, namely the ansi theme. In fact, this theme in practice behaves like the default "theme" of HTTPie. So if you want HTTPie-like behavior, that is the theme you should use.

Use it like this: bat --theme ansi license. You might want to make
it default on your system, and one easy way to do that is to run bat --generate-config-file and then add the line --theme="ansi" to the
generated file (the path of the file is printed).

As sharkdp explained, this theme is simply too ugly to be used by default though.

In fact, I wonder if it is possible to create a beautiful theme that works with both white and black backgrounds. It is easy to make it work for "normal" text, using the "reset to default foreground and background color" approach used by both HTTPie and the ansi bat theme. The tricky thing is to pick colors that work with both white and black background. Maybe someone could take a shot at creating such a theme?

@hoffa
Copy link
Author

hoffa commented Aug 4, 2022

2 years later, I really want bat to be part of my standard toolset, but it's difficult. I jump around systems and don't want to spend time remembering yet another parameter/config/alias for my tools to work resiliently regardless of environment. The default theme hurts versatility.

As sharkdp explained, this theme is simply too ugly to be used by default though.

It's perhaps ugly in a silo. But I'd argue consistency of colors in foundational tools is more important, and makes the tool more accessible without configuration. Plus my colors look nice and are configurable.

@Enselic
Copy link
Collaborator

Enselic commented Aug 5, 2022

If you are on Mac the situation will be much improved next release, see #2197

Maybe that fix can inspire someone to also improve the situation on other platforms

See #1746 for some more discussion

@sharkdp
Copy link
Owner

sharkdp commented Sep 6, 2022

If you are on Mac the situation will be much improved next release, see #2197

That release is out now: https://github.com/sharkdp/bat/releases/tag/v0.22.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants