theme dark:light

This commit is contained in:
Harivansh Rathi 2026-03-20 15:37:34 -04:00
parent 7ae7c1ceec
commit 67128fe09b
7 changed files with 190 additions and 40 deletions

View file

@ -7,11 +7,16 @@ local active_schemes = {
}
local function ensure_server_socket()
if vim.v.servername ~= nil and vim.v.servername ~= "" then
return
local socket_path = ("/tmp/nvim-%d.sock"):format(vim.fn.getpid())
local active_servers = vim.fn.serverlist()
for _, server in ipairs(active_servers) do
if server == socket_path then return end
end
local socket_path = ("/tmp/nvim-%d.sock"):format(vim.fn.getpid())
local stat = vim.uv.fs_stat(socket_path)
if stat and stat.type == "socket" then vim.fn.delete(socket_path) end
vim.fn.serverstart(socket_path)
end
@ -55,6 +60,7 @@ function M.apply(mode)
vim.g.cozybox_theme_mode = next_mode
apply_cozybox_overrides()
vim.schedule(function() pcall(vim.cmd, "redraw!") end)
end
function M.setup()

View file

@ -5,7 +5,7 @@
}: let
theme = import ../lib/theme.nix {inherit config;};
ghosttyConfig = ''
theme = "dark:cozybox-dark,light:cozybox-light"
theme = "cozybox-current"
font-family = Berkeley Mono
font-codepoint-map = U+f101-U+f25c=nonicons
background-opacity = 1

View file

@ -9,7 +9,7 @@ in {
home.packages = builtins.attrValues customScripts.packages;
home.activation.initializeThemeState = lib.hm.dag.entryAfter ["writeBoundary"] ''
mkdir -p "${customScripts.theme.paths.stateDir}" "${customScripts.theme.paths.tmuxDir}"
mkdir -p "${customScripts.theme.paths.stateDir}" "${customScripts.theme.paths.ghosttyDir}" "${customScripts.theme.paths.tmuxDir}"
if [[ -f "${customScripts.theme.paths.stateFile}" ]]; then
mode=$(tr -d '[:space:]' < "${customScripts.theme.paths.stateFile}")
@ -20,14 +20,17 @@ in {
case "$mode" in
light)
ghostty_target="${customScripts.theme.paths.ghosttyDir}/cozybox-light"
tmux_target="${customScripts.tmuxConfigs.light}"
;;
*)
printf '%s\n' "${customScripts.theme.defaultMode}" > "${customScripts.theme.paths.stateFile}"
ghostty_target="${customScripts.theme.paths.ghosttyDir}/cozybox-dark"
tmux_target="${customScripts.tmuxConfigs.dark}"
;;
esac
ln -sfn "$ghostty_target" "${customScripts.theme.paths.ghosttyCurrentFile}"
ln -sfn "$tmux_target" "${customScripts.theme.paths.tmuxCurrentFile}"
'';
}

View file

@ -108,6 +108,91 @@
$path
)
_codex_read_theme_mode() {
local mode_file="$HOME/.local/state/theme/current"
if [[ -f "$mode_file" ]]; then
local mode
mode=$(tr -d '[:space:]' < "$mode_file")
if [[ "$mode" == light || "$mode" == dark ]]; then
printf '%s' "$mode"
return
fi
fi
printf 'dark'
}
_codex_apply_highlight_styles() {
local mode="$(_codex_read_theme_mode)"
if [[ "$mode" == "''${_CODEX_LAST_HIGHLIGHT_THEME:-}" ]]; then
return
fi
typeset -gA ZSH_HIGHLIGHT_STYLES
if [[ "$mode" == light ]]; then
ZSH_HIGHLIGHT_STYLES[arg0]='fg=#427b58'
ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=#427b58,underline'
ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=#8f3f71'
ZSH_HIGHLIGHT_STYLES[bracket-error]='fg=#ea6962,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=#076678,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=#427b58,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=#8f3f71,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-4]='fg=#b57614,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-5]='fg=#076678,bold'
ZSH_HIGHLIGHT_STYLES[comment]='fg=#928374'
ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=#8f3f71'
ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#b57614'
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#b57614'
ZSH_HIGHLIGHT_STYLES[global-alias]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[path]='fg=#3c3836,underline'
ZSH_HIGHLIGHT_STYLES[precommand]='fg=#427b58,underline'
ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=#8f3f71'
ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=#076678'
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#b57614'
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#b57614'
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#b57614'
ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=#427b58,underline'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#ea6962,bold'
else
ZSH_HIGHLIGHT_STYLES[arg0]='fg=#8ec97c'
ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=#8ec97c,underline'
ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=#8ec07c'
ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=#8ec07c'
ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=#d3869b'
ZSH_HIGHLIGHT_STYLES[bracket-error]='fg=#ea6962,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=#5b84de,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=#8ec97c,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=#d3869b,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-4]='fg=#d8a657,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-5]='fg=#8ec07c,bold'
ZSH_HIGHLIGHT_STYLES[comment]='fg=#7c6f64'
ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=#d3869b'
ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=#8ec07c'
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#d8a657'
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#d8a657'
ZSH_HIGHLIGHT_STYLES[global-alias]='fg=#8ec07c'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#5b84de'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#5b84de'
ZSH_HIGHLIGHT_STYLES[path]='fg=#d4be98,underline'
ZSH_HIGHLIGHT_STYLES[precommand]='fg=#8ec97c,underline'
ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=#d3869b'
ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=#8ec07c'
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#d8a657'
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#d8a657'
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#d8a657'
ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=#8ec97c,underline'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#ea6962,bold'
fi
typeset -g _CODEX_LAST_HIGHLIGHT_THEME="$mode"
}
unalias ga 2>/dev/null
git() {
@ -153,6 +238,7 @@
zle -N zle-line-finish
precmd() {
_codex_apply_highlight_styles
_codex_set_cursor beam
}
@ -160,6 +246,8 @@
_codex_set_cursor beam
}
_codex_apply_highlight_styles
if command -v wt >/dev/null 2>&1; then
eval "$(command wt config shell init zsh)"
fi

View file

@ -4,71 +4,92 @@
stateDir = "${config.xdg.stateHome}/theme";
stateFile = "${config.xdg.stateHome}/theme/current";
ghosttyDir = "${config.xdg.configHome}/ghostty/themes";
ghosttyCurrentFile = "${config.xdg.configHome}/ghostty/themes/current.conf";
ghosttyCurrentFile = "${config.xdg.configHome}/ghostty/themes/cozybox-current";
tmuxDir = "${config.xdg.configHome}/tmux/theme";
tmuxCurrentFile = "${config.xdg.configHome}/tmux/theme/current.conf";
};
themes = {
dark = {
ghosttyTheme = "Gruvbox Material Dark";
background = "#181818";
surface = "#1e1e1e";
selectionBackground = "#504945";
selectionForeground = "#ebdbb2";
cursorColor = "#ddc7a1";
cursorText = "#181818";
foreground = "#ebdbb2";
text = "#d4be98";
mutedText = "#7c6f64";
red = "#ea6962";
green = "#8ec97c";
yellow = "#d8a657";
blue = "#5b84de";
aqua = "#8ec07c";
purple = "#d3869b";
orange = "#e78a4e";
border = "#181818";
palette = [
"#1d2021"
"#ea6962"
"#8ec97c"
"#d79921"
"#5b84de"
"#b16286"
"#689d6a"
"#a89984"
"#928374"
"#ea6962"
"#8ec97c"
"#fabd2f"
"#5b84de"
"#d3869b"
"#8ec07c"
"#ebdbb2"
];
};
light = {
ghosttyTheme = "Gruvbox Material Light";
background = "#e7e7e7";
surface = "#e1e1e1";
selectionBackground = "#c3c7c9";
selectionForeground = "#1d2021";
selectionForeground = "#3c3836";
cursorColor = "#282828";
text = "#282828";
cursorText = "#e7e7e7";
foreground = "#3c3836";
text = "#3c3836";
mutedText = "#665c54";
red = "#ea6962";
green = "#8ec97c";
yellow = "#d8a657";
blue = "#5b84de";
aqua = "#8ec07c";
purple = "#d3869b";
orange = "#e78a4e";
border = "#c3c7c9";
palette = [
"#f9f5d7"
"#ea6962"
"#8ec97c"
"#d8a657"
"#5b84de"
"#d3869b"
"#8ec07c"
"#7c6f64"
"#928374"
"#ea6962"
"#8ec97c"
"#d8a657"
"#5b84de"
"#d3869b"
"#8ec07c"
"#3c3836"
];
};
};
renderGhostty = mode: let
theme = themes.${mode};
paletteLines =
builtins.concatStringsSep "\n"
(builtins.genList
(index: "palette = ${toString index}=${builtins.elemAt theme.palette index}")
(builtins.length theme.palette));
in ''
theme = "${theme.ghosttyTheme}"
background = ${theme.background}
foreground = ${theme.foreground}
cursor-color = ${theme.cursorColor}
cursor-text = ${theme.cursorText}
selection-background = ${theme.selectionBackground}
selection-foreground = ${theme.selectionForeground}
palette = 1=${theme.red}
palette = 2=${theme.green}
palette = 3=${theme.yellow}
palette = 4=${theme.blue}
palette = 5=${theme.purple}
palette = 6=${theme.aqua}
palette = 9=${theme.red}
palette = 10=${theme.green}
palette = 11=${theme.yellow}
palette = 12=${theme.blue}
palette = 13=${theme.purple}
palette = 14=${theme.aqua}
${paletteLines}
'';
renderTmux = mode: let

View file

@ -64,11 +64,15 @@
theme = mkScript {
name = "theme";
file = ./theme.sh;
runtimeInputs = with pkgs; [coreutils neovim tmux];
runtimeInputs = with pkgs; [coreutils findutils neovim tmux];
replacements = {
"@DEFAULT_MODE@" = theme.defaultMode;
"@STATE_DIR@" = theme.paths.stateDir;
"@STATE_FILE@" = theme.paths.stateFile;
"@GHOSTTY_DIR@" = theme.paths.ghosttyDir;
"@GHOSTTY_CURRENT_FILE@" = theme.paths.ghosttyCurrentFile;
"@GHOSTTY_DARK_FILE@" = "${theme.paths.ghosttyDir}/cozybox-dark";
"@GHOSTTY_LIGHT_FILE@" = "${theme.paths.ghosttyDir}/cozybox-light";
"@TMUX_DIR@" = theme.paths.tmuxDir;
"@TMUX_CURRENT_FILE@" = theme.paths.tmuxCurrentFile;
"@TMUX_DARK_FILE@" = "${tmuxConfigs.dark}";

View file

@ -16,14 +16,20 @@ read_mode() {
link_mode_assets() {
local mode="$1"
local ghostty_target
local tmux_target
local apple_dark_mode
case "$mode" in
dark)
ghostty_target="@GHOSTTY_DARK_FILE@"
tmux_target="@TMUX_DARK_FILE@"
apple_dark_mode=true
;;
light)
ghostty_target="@GHOSTTY_LIGHT_FILE@"
tmux_target="@TMUX_LIGHT_FILE@"
apple_dark_mode=false
;;
*)
echo "invalid mode: $mode" >&2
@ -31,18 +37,40 @@ link_mode_assets() {
;;
esac
mkdir -p "@STATE_DIR@" "@TMUX_DIR@"
mkdir -p "@STATE_DIR@" "@GHOSTTY_DIR@" "@TMUX_DIR@"
printf '%s\n' "$mode" > "@STATE_FILE@"
ln -sfn "$ghostty_target" "@GHOSTTY_CURRENT_FILE@"
ln -sfn "$tmux_target" "@TMUX_CURRENT_FILE@"
if command -v tmux >/dev/null 2>&1 && tmux start-server >/dev/null 2>&1; then
tmux source-file "@TMUX_CONFIG@" >/dev/null 2>&1 || true
fi
for socket in /tmp/nvim-*.sock; do
if [[ "$(uname -s)" == "Darwin" ]] && command -v osascript >/dev/null 2>&1; then
osascript -e "tell application \"System Events\" to tell appearance preferences to set dark mode to ${apple_dark_mode}" >/dev/null 2>&1 || true
osascript <<'EOF' >/dev/null 2>&1 || true
tell application "System Events"
if not (exists process "Ghostty") then
return
end if
tell process "Ghostty"
click menu item "Reload Configuration" of menu 1 of menu bar item "Ghostty" of menu bar 1
end tell
end tell
EOF
fi
while IFS= read -r socket; do
[[ -S "$socket" ]] || continue
nvim --server "$socket" --remote-send "<Cmd>ThemeSync $mode<CR>" >/dev/null 2>&1 || true
done
nvim --server "$socket" --remote-expr "execute('ThemeSync $mode')" >/dev/null 2>&1 || true
done < <(
{
find /tmp -maxdepth 1 -type s -name 'nvim-*.sock' 2>/dev/null
find "${TMPDIR:-/tmp}" -type s -path "*/nvim.${USER}/*/nvim.*" 2>/dev/null
} | sort -u
)
}
mode="${1:-current}"