Replies: 32 comments
-
To work around this, you could have your configured theme be a symlink to another theme, and use your OS's task scheduling utility (e.g. systemd timers) to run a task every evening to replace the symlink with one pointing to the dark theme, and another to switch it to the light theme in the morning. But this is an excellent feature for a plugin to implement, once Helix has an interface for plugins. |
Beta Was this translation helpful? Give feedback.
-
+1 for this on macOS |
Beta Was this translation helpful? Give feedback.
-
This is better suited to either solving with symlinks or via scripting once we support it. Querying OS themes would introduce a bunch of platform specific code. |
Beta Was this translation helpful? Give feedback.
-
Is it possible to define a theme like base16 that inherits purely from the terminal's color scheme? I know for example wezterm supports switching theme based on light/dark switch in the OS (macos and Linux gnome). It would be cool if such a theme literally just output references to the terminal's foreground, background, so it would automatically change with the terminal. |
Beta Was this translation helpful? Give feedback.
-
It's possible, simply specify the colors as |
Beta Was this translation helpful? Give feedback.
-
But is "background" and "foreground" a thing? Otherwise you end up specifying "black" as the background which gains nothing in responding to terminal theme change. |
Beta Was this translation helpful? Give feedback.
-
Just came over to open an issue on this also. New terminal apps like Black Box do an excellent job of integrating with the operating system’s (ok, desktop environment’s) colour scheme. It’s a joy to see my terminal go from light mode to dark mode as my whole system does but sad to see Helix Editor stick out like a sore thumb when it launches in Dracula in the middle of a light scheme. Vampires don’t like the light and all that… :) (Beyond vanity and mere aesthetics, this has implications for legibility/readability and, thus, accessibility.) |
Beta Was this translation helpful? Give feedback.
-
I'll reiterate: there's no built-in terminal way to detect this. We'd need to do a bunch of platform-specific hacks and probably link directly against a bunch of GTK-specific libraries to be able to read this on Linux+GTK. See here for example: a nvim plugin that has to speak the dbus protocol (plus continually poll) to detect this: https://github.com/Sewdohe/Nvim-Adapt/blob/main/lua/nvim-adapt.lua You could script this by doing the dbus interaction externally to helix, then swap the config files. To deal with running instances we'd need to add support for reloading the config on |
Beta Was this translation helpful? Give feedback.
-
Ah, this was what I was just about to ask :) Scripting this for GNOME has been no effort at all. I’ll share my own script in a second once I’m happy it’s working properly. The ability to update running instances is the only thing it’s missing right now. |
Beta Was this translation helpful? Give feedback.
-
OK, sorry for the delay, life got in the way. So, here’s one way to synchronise Helix with the system colour scheme on GNOME: PrerequisitesMake sure your Helix configuration is at ~/.config/helix/config.toml (or change the paths in the scripts accordingly) and that you have a line in it that sets the theme. What it’s set to is not as important as the line being there so it can be changed by the update script. theme = "something" The scriptsFirst, create a folder to hold the scripts: mkdir -p ~/.config/helix/scripts/synchronise-with-system-colour-scheme Then create the following scripts and ensure they’re executable ( monitor.sh#!/usr/bin/env bash
gsettings monitor org.gnome.desktop.interface color-scheme \
| xargs -L1 bash -c "source ${HOME}/.config/helix/scripts/synchronise-with-system-colour-scheme/update.sh" update.sh#!/usr/bin/env bash
# Fail early, fail often.
set -eu -o pipefail
if [[ "$1" == "default" ]]; then
# Update Helix Editor config to use light theme.
sed -i 's/theme = ".*"/theme = "serika-light"/' ${HOME}/.config/helix/config.toml
else
# Update Helix Editor config to use dark theme.
sed -i 's/theme = ".*"/theme = "dracula"/' ${HOME}/.config/helix/config.toml
fi Edit the script to change the light and dark themes to the ones you want. You can see the ones available on your system using the You need to keep the monitor script running in the background for this to work. You can do this by simply running Before creating the systemd service, create two more helper scripts to enable and disable it: enable.sh#!/usr/bin/env bash
# Enables the service to start on boot and also starts it up immediately.
systemctl --user enable helix-system-colour-scheme-synchronisation.service
systemctl --user start helix-system-colour-scheme-synchronisation.service disable.sh#!/usr/bin/env bash
# Stop the service immediately and disables it from starting on boot.
systemctl --user stop helix-system-colour-scheme-synchronisation.service
systemctl --user disable helix-system-colour-scheme-synchronisation.service And, finally, create the systemd user service (in _~/.config/systemd/user and make sure it is executable.) helix-system-colour-scheme-synchronisation.service
That’s it. Run: Helix currently doesn’t automatically reload its configuration when it changes so you’ll have to restart existing instances manually. I look forward to the day when we can see a smooth fade from a light theme to a dark theme and back when the system theme changes ;) Hope you find this useful :) |
Beta Was this translation helpful? Give feedback.
-
@archeer, @the-mikedavis, et al., Just a quick heads up that I’ve now released a simple tool called Lipstick on a Pig (https://codeberg.org/small-tech/lipstick/#lipstick-on-a-pig) that handles the theme switches on GNOME-based systems. All you have to do is install it and it does its thing automatically. It currently also has support for the bat and delta tools (which are two I use daily) and you can easily add support for any other CLI app that supports colour themes by providing a simple plugin: https://codeberg.org/small-tech/lipstick/src/branch/main/src/lipstick-apps (For Helix, you currently need a restart but the moment we have some sort of functionality to reload the config when it detects a change, this should be automatic. How neat would it be if it actually fade/transitioned along with everything else?) :) Enjoy! 💕 |
Beta Was this translation helpful? Give feedback.
-
👋 I recently worked on something similar, how about adding linux support for this using the dbus freedesktop portal? It'll work on all distros that follow this standard and the only new dependency this would introduce is zbus & zvariant. I'm down to adding this to helix if the maintainers agree. |
Beta Was this translation helpful? Give feedback.
-
Now that we reload configuration when we receive the USR1 signal, I don't see any reason to build this directly into Helix, especially if it requires new dependencies. |
Beta Was this translation helpful? Give feedback.
-
@the-mikedavis ah that's a pity, it would really make the editor 'complete' for me. Let me know if anything changes your mind! |
Beta Was this translation helpful? Give feedback.
-
@the-mikedavis That’s great news. I just updated Lipstick on a Pig so it now sends the USR1 signal to Helix. This is what it looks like when you switch between light/dark themes on Fedora Silverblue with Helix Editor running under Black Box terminal and switching between the One Light and Dracula themes. lipstick-on-a-pig-helix-editor.mp4 |
Beta Was this translation helpful? Give feedback.
-
Another easy way to do this, is to use darkman. Then you can create scripts in sed -i 's/theme = ".*"/theme = "solarized_light"/' ${HOME}/.config/helix/config.toml
pkill -USR1 helix |
Beta Was this translation helpful? Give feedback.
-
I've also successfully used the I see that a VScode already has and the next version iTerm will also have this feature so I thought it would be nice if we can also have it :) I would be willing to dive in the code and work a PR :) |
Beta Was this translation helpful? Give feedback.
-
I definitely think there should be a canonical way to have auto light/dark theme in Helix. I don't really have an opinion on what that should be, but the quickest I can think of is using one of the system brightness crates and adding dark/light theme settings in config |
Beta Was this translation helpful? Give feedback.
-
I've started with this because I really miss this feature and in the hope that it'll be reconsidered, I'm willing to maintain it too once it's merged. In the meantime my branch could be useful for some people, also open to any feedback! |
Beta Was this translation helpful? Give feedback.
-
If it were possible to set the theme (and/or all settings) via command-line flag or environment variable, then that would allow us to control it at launch time without needing to modify the configuration files That wouldn't be the same as having it change on-the-fly, but it'd be enough for workflows where the light/dark decision is made once per terminal session |
Beta Was this translation helpful? Give feedback.
-
You can switch the helix editor theme on the fly by editing the configuration file (e.g. with |
Beta Was this translation helpful? Give feedback.
-
That's a possibility but it breaks the contract and become unavailable on declarative build system as Nix and Guix as those make config files read only and isn't suitable to change dynamically the declaration of the config. |
Beta Was this translation helpful? Give feedback.
-
As helix is a terminal editor, it could also try querying the background color with |
Beta Was this translation helpful? Give feedback.
-
Some terminals like iTerm212 send a If helix could specify commands in the config that are run in reaction to a signal, it would allow to automatically change the theme. There seems to be a plugin3 for neovim that does that. This would eliminate the need to run a separate watcher script in the background that modifies the helix config in place and reloads it in active helix processes by sending them a Footnotes |
Beta Was this translation helpful? Give feedback.
-
To solve or palliate this and many other issues, I do recommend to add:
|
Beta Was this translation helpful? Give feedback.
-
Since maintainers don’t seem interested in a better solution, here’s one way to set up automatic theme switching using iTerm2 (3.4) on macOS. The helix script modifies a custom theme instead of the
theme = "adaptive"
# ...
inherits = "github_dark"
#!/usr/bin/env bash
set -e -u -o pipefail
THEME_LIGHT="github_light"
THEME_DARK="github_dark"
THEME_FILEPATH="${HOME}/.config/helix/themes/adaptive.toml"
if [[ $# -eq 0 ]]; then
echo "Error: Missing theme argument." >&2
exit 1
fi
if [[ $1 == "light" ]]; then
sed -i '' -E "s/^inherits = \"$THEME_DARK\"$/inherits = \"$THEME_LIGHT\"/" "$THEME_FILEPATH"
elif [[ $1 == "dark" ]]; then
sed -i '' -E "s/^inherits = \"$THEME_LIGHT\"$/inherits = \"$THEME_DARK\"/" "$THEME_FILEPATH"
else
echo "Error: Invalid theme '$1'. Expected 'light' or 'dark'." >&2
exit 1
fi
pkill -USR1 hx || true
#!/usr/bin/env python3
# adapted from https://iterm2.com/python-api/examples/theme.html
import os
import subprocess
import iterm2
THEME_LIGHT = "Light Background"
THEME_DARK = "Dark Background"
HELIX_SWITCH_THEME_PATH = os.path.expanduser("~/.config/helix/switch_theme.sh")
async def update(connection, theme):
parts = theme.split(" ")
if "dark" in parts:
preset = await iterm2.ColorPreset.async_get(connection, THEME_DARK)
subprocess.run([HELIX_SWITCH_THEME_PATH, "dark"], check=True)
else:
preset = await iterm2.ColorPreset.async_get(connection, THEME_LIGHT)
subprocess.run([HELIX_SWITCH_THEME_PATH, "light"], check=True)
profiles=await iterm2.PartialProfile.async_query(connection)
for partial in profiles:
profile = await partial.async_get_full_profile()
await profile.async_set_color_preset(preset)
async def main(connection):
app = await iterm2.async_get_app(connection)
await update(connection, await app.async_get_variable("effectiveTheme"))
async with iterm2.VariableMonitor(connection, iterm2.VariableScopes.APP, "effectiveTheme", None) as mon:
while True:
theme = await mon.async_get()
await update(connection, theme)
iterm2.run_forever(main) |
Beta Was this translation helpful? Give feedback.
-
I wrote/use Lipstick on a Pig a little while ago to do this for Helix and a few other apps. In case it’s easier: https://codeberg.org/small-tech/lipstick |
Beta Was this translation helpful? Give feedback.
-
For macOS, I use this function in my # Switches themes in sync with macOS interface style. NOTE: non-universal & opionated
function switch_theme() {
local STYLE=$(defaults read NSGlobalDomain AppleInterfaceStyle 2>/dev/null)
if [[ "$STYLE" == "Dark" ]]; then
printf "Dark mode detected.\n"
kitty +kitten themes Modus Vivendi Tinted
sed -i '' \
's/theme = "[^"]*"/theme = \"modus_vivendi_tinted\"/g' \
$(readlink ~/.config/helix/config.toml)
else
printf "Light mode detected.\n"
kitty +kitten themes Modus Operandi Tinted
sed -i '' \
's/theme = "[^"]*"/theme = \"modus_operandi_tinted\"/g' \
$(readlink ~/.config/helix/config.toml)
fi
pkill -USR1 hx
} |
Beta Was this translation helpful? Give feedback.
-
Another +1 on including this as a feature. In the meantime, here's another macOS-specific solution using Hammerspoon that doesn't require polling or background processes (other than Hammerspoon itself, of course): # in helix config
theme = "adaptive" local write_file = function(path, content)
local file = io.open(path, "w")
assert(file, "Failed to open file for writing: " .. path)
file:write(content)
file:close()
end
local get_appearance = function()
local _, is_dark = hs.osascript.applescript(
'tell application "System Events" to tell appearance preferences to return dark mode')
return is_dark and "dark" or "light"
end
local light_theme = "tokyonight_day"
local dark_theme = "tokyonight_storm"
local last_appearance = get_appearance()
-- define as global variable to keep alive
watcher = hs.distributednotifications.new(function()
local appearance = get_appearance()
if appearance ~= last_appearance then
write_file(os.getenv("HOME") .. "/.config/helix/themes/adaptive.toml",
string.format("inherits = '%s'", appearance == "dark" and dark_theme or light_theme))
-- command will fail silently if hx isn't running, which is good enough for me
os.execute("kill -USR1 $(pgrep hx)")
end
last_appearance = appearance
end, 'AppleInterfaceThemeChangedNotification'):start() |
Beta Was this translation helpful? Give feedback.
-
Bat just merged in auto theme switching based on terminal color using a custom library called terminal colorsaurus, which is written in rust and is published as a crate. Delta also uses that library since version 0.17, March of this year With the next release it even seems to be supporting windows with the terminal app. So MacOS, Linux and Windows are supported with most to pretty much all terminal emulators working, see here. I think this issue should be revisited |
Beta Was this translation helpful? Give feedback.
-
Describe your feature request
My OS is in light mode during day time and dark mode at night.
I like to code in the sun but in order to see anything I have to use a light theme.
My request is to define a light theme and a dark theme and the theme chosen depends on the OS's theme.
Low priority though.
Beta Was this translation helpful? Give feedback.
All reactions