kitty: capture theme choices however the kitten was launched
Saving a theme stopped sticking: the choice was captured only by the fish `kitten` wrapper, so `kitty +kitten themes`, a keybinding or any non-fish shell wrote <appearance>-theme.auto.conf directly and the next regeneration overwrote it from theme-modes. The dark slot had already lost a pick that way -- dark-theme.auto.conf held #0d0f31 while canonical dark said #2b2c2e. Move the capture into apply-theme-mode.sh, which every path runs. It records a cksum of each generated file after the repair step; on the next run a file whose checksum differs was written by something else, so it becomes canonical for that appearance. With no state recorded yet nothing is adopted, so a first run cannot mistake a pinned mode's duplicated files for real choices. The fish wrapper keeps only its useful part: re-apply the mode and reload so the change shows at once. theme-modes/dark.conf is the recovered #0d0f31 (1984). Covered by a new case in tests/test_theme_mode.sh that writes the theme file with no shell involved.
This commit is contained in:
parent
489b401f2f
commit
9e2667f8fe
@ -65,6 +65,7 @@ Library
|
|||||||
# every machine flag the others' mode. run_after_kitty-theme-mode.sh
|
# every machine flag the others' mode. run_after_kitty-theme-mode.sh
|
||||||
# regenerates them after apply.
|
# regenerates them after apply.
|
||||||
.config/kitty/theme-mode
|
.config/kitty/theme-mode
|
||||||
|
.config/kitty/.theme-generated
|
||||||
.config/kitty/dark-theme.auto.conf
|
.config/kitty/dark-theme.auto.conf
|
||||||
.config/kitty/light-theme.auto.conf
|
.config/kitty/light-theme.auto.conf
|
||||||
.config/kitty/no-preference-theme.auto.conf
|
.config/kitty/no-preference-theme.auto.conf
|
||||||
|
|||||||
@ -47,18 +47,46 @@ esac
|
|||||||
|
|
||||||
mkdir -p "$canonical_dir"
|
mkdir -p "$canonical_dir"
|
||||||
|
|
||||||
# Adopt the current automatic themes as canonical when they have not been
|
# Checksums of the files as this script last wrote them. Anything that differs
|
||||||
# captured yet. Only safe while following the OS: under a pinned mode the
|
# now was rewritten by something else -- in practice the themes kitten saving a
|
||||||
# generated files all hold the pinned theme and would overwrite the others.
|
# theme for that appearance -- so it is a new choice and becomes canonical.
|
||||||
if [ "$mode" = auto ]; then
|
# Recording it here rather than in the fish `kitten` wrapper means the choice
|
||||||
|
# survives however the kitten was launched: `kitty +kitten themes`, a keybinding
|
||||||
|
# or another shell all bypass that wrapper.
|
||||||
|
state_file="$config_dir/.theme-generated"
|
||||||
|
|
||||||
|
# cksum is POSIX, unlike shasum/sha256sum which differ across platforms.
|
||||||
|
sum_of() {
|
||||||
|
[ -f "$1" ] || return 1
|
||||||
|
cksum < "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
recorded_sum() {
|
||||||
|
[ -f "$state_file" ] || return 1
|
||||||
|
awk -v want="$1" '$1 == want { $1 = ""; sub(/^ /, ""); print; found = 1 }
|
||||||
|
END { exit !found }' "$state_file"
|
||||||
|
}
|
||||||
|
|
||||||
for appearance in dark light no-preference; do
|
for appearance in dark light no-preference; do
|
||||||
canonical="$canonical_dir/$appearance.conf"
|
canonical="$canonical_dir/$appearance.conf"
|
||||||
generated="$config_dir/$appearance-theme.auto.conf"
|
generated="$config_dir/$appearance-theme.auto.conf"
|
||||||
if [ ! -f "$canonical" ] && [ -f "$generated" ]; then
|
[ -f "$generated" ] || continue
|
||||||
cp "$generated" "$canonical"
|
|
||||||
|
# First adoption of an existing setup: take whatever is there, but only
|
||||||
|
# while following the OS. Under a pinned mode every generated file holds
|
||||||
|
# the pinned theme, so adopting them would overwrite the other appearances.
|
||||||
|
if [ ! -f "$canonical" ]; then
|
||||||
|
[ "$mode" = auto ] && cp "$generated" "$canonical"
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# With no state yet we cannot tell a fresh choice from a file we wrote, so
|
||||||
|
# leave canonical alone; the checksums recorded below make the next run
|
||||||
|
# able to tell.
|
||||||
|
now=$(sum_of "$generated") || continue
|
||||||
|
was=$(recorded_sum "$appearance") || continue
|
||||||
|
[ "$now" = "$was" ] || cp "$generated" "$canonical"
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
|
|
||||||
for appearance in dark light no-preference; do
|
for appearance in dark light no-preference; do
|
||||||
if [ "$mode" = auto ]; then
|
if [ "$mode" = auto ]; then
|
||||||
@ -85,3 +113,16 @@ for appearance in dark light no-preference; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
"$script_dir/repair-auto-themes.sh" "$config_dir"
|
"$script_dir/repair-auto-themes.sh" "$config_dir"
|
||||||
|
|
||||||
|
# Record what we ended up with, after the repair step, so the next run can tell
|
||||||
|
# an externally-saved theme from one of ours.
|
||||||
|
tmp_state=$(mktemp "$state_file.tmp.XXXXXX")
|
||||||
|
trap 'rm -f "$tmp_state"' EXIT HUP INT TERM
|
||||||
|
for appearance in dark light no-preference; do
|
||||||
|
generated="$config_dir/$appearance-theme.auto.conf"
|
||||||
|
[ -f "$generated" ] || continue
|
||||||
|
printf '%s %s\n' "$appearance" "$(sum_of "$generated")" >> "$tmp_state"
|
||||||
|
done
|
||||||
|
chmod 600 "$tmp_state"
|
||||||
|
mv -f "$tmp_state" "$state_file"
|
||||||
|
trap - EXIT HUP INT TERM
|
||||||
|
|||||||
@ -117,6 +117,37 @@ expect "new light theme is used once selected" \
|
|||||||
expect "dark theme survived the whole exchange" \
|
expect "dark theme survived the whole exchange" \
|
||||||
"$config_dir/theme-modes/dark.conf" "$DARK"
|
"$config_dir/theme-modes/dark.conf" "$DARK"
|
||||||
|
|
||||||
|
# --- a theme saved without going through the fish shim is still kept -----
|
||||||
|
# `kitty +kitten themes`, a keybinding, or any non-fish shell writes the
|
||||||
|
# automatic theme file directly and never runs the `kitten` function. The
|
||||||
|
# capture therefore lives in apply-theme-mode.sh, keyed on checksums, or the
|
||||||
|
# next regeneration silently reverts the choice.
|
||||||
|
echo dark >"$config_dir/theme-mode"
|
||||||
|
"$root/apply-theme-mode.sh" "$config_dir"
|
||||||
|
|
||||||
|
BYPASS_DARK='#0d0f31'
|
||||||
|
printf 'background %s\n' "$BYPASS_DARK" >"$config_dir/dark-theme.auto.conf"
|
||||||
|
"$root/apply-theme-mode.sh" "$config_dir"
|
||||||
|
expect "theme saved outside the shim becomes canonical" \
|
||||||
|
"$config_dir/theme-modes/dark.conf" "$BYPASS_DARK"
|
||||||
|
expect "and stays applied" "$config_dir/dark-theme.auto.conf" "$BYPASS_DARK"
|
||||||
|
|
||||||
|
# the same for a light theme while the pin is on dark
|
||||||
|
BYPASS_LIGHT='#fafafa'
|
||||||
|
printf 'background %s\n' "$BYPASS_LIGHT" >"$config_dir/light-theme.auto.conf"
|
||||||
|
"$root/apply-theme-mode.sh" "$config_dir"
|
||||||
|
expect "light theme saved outside the shim becomes canonical" \
|
||||||
|
"$config_dir/theme-modes/light.conf" "$BYPASS_LIGHT"
|
||||||
|
expect "but the dark pin still wins on screen" \
|
||||||
|
"$config_dir/light-theme.auto.conf" "$BYPASS_DARK"
|
||||||
|
|
||||||
|
# and a further run must not mistake our own output for a new choice
|
||||||
|
"$root/apply-theme-mode.sh" "$config_dir"
|
||||||
|
expect "adoption is idempotent (dark)" \
|
||||||
|
"$config_dir/theme-modes/dark.conf" "$BYPASS_DARK"
|
||||||
|
expect "adoption is idempotent (light)" \
|
||||||
|
"$config_dir/theme-modes/light.conf" "$BYPASS_LIGHT"
|
||||||
|
|
||||||
# --- a bare `theme` records auto when it lands on the macOS appearance ----
|
# --- a bare `theme` records auto when it lands on the macOS appearance ----
|
||||||
echo auto >"$config_dir/theme-mode"
|
echo auto >"$config_dir/theme-mode"
|
||||||
"$root/apply-theme-mode.sh" "$config_dir"
|
"$root/apply-theme-mode.sh" "$config_dir"
|
||||||
|
|||||||
@ -1,29 +1,37 @@
|
|||||||
background #1c2836
|
# 1984 theme by Bertie Blackman, https://github.com/covertbert/iterm2-1984/
|
||||||
|
|
||||||
foreground #ffffff
|
foreground #ffffff
|
||||||
cursor #bbbbbb
|
background #0d0f31
|
||||||
selection_background #b4d5ff
|
selection_foreground #000000
|
||||||
|
selection_background #00d5eb
|
||||||
color0 #000000
|
color0 #000000
|
||||||
color8 #545454
|
color1 #ff16b0
|
||||||
color1 #f9555f
|
color2 #b3f361
|
||||||
color9 #fa8b8e
|
color3 #ffea16
|
||||||
color2 #20af89
|
color4 #46bdff
|
||||||
color10 #34bb99
|
color5 #f806fa
|
||||||
color3 #fdf029
|
color6 #59e1e3
|
||||||
color11 #ffff55
|
color7 #feffff
|
||||||
color4 #589cf5
|
color8 #000000
|
||||||
color12 #589cf5
|
color9 #ff16b0
|
||||||
color5 #934d95
|
color10 #b3f361
|
||||||
color13 #e75598
|
color11 #ffea16
|
||||||
color6 #1e9ee6
|
color12 #46bdff
|
||||||
color14 #3978bb
|
color13 #f806fa
|
||||||
color7 #bbbbbb
|
color14 #6be4e6
|
||||||
color15 #ffffff
|
color15 #feffff
|
||||||
selection_foreground #1c2836
|
|
||||||
|
# URL styles
|
||||||
|
url_color #f806fa
|
||||||
|
url_style single
|
||||||
|
|
||||||
|
# Cursor styles
|
||||||
|
cursor #59e1e3
|
||||||
|
|
||||||
# START_AUTOGENERATED_TAB_STYLE
|
# START_AUTOGENERATED_TAB_STYLE
|
||||||
# Feel free to update these colors manually and remove these comments.
|
# Feel free to update these colors manually and remove these comments.
|
||||||
active_tab_foreground #444444
|
active_tab_foreground #eeeeee
|
||||||
active_tab_background #b4d5ff
|
active_tab_background #00d5eb
|
||||||
inactive_tab_foreground #ffffff
|
inactive_tab_foreground #ffffff
|
||||||
inactive_tab_background #16202b
|
inactive_tab_background #0a0c27
|
||||||
# END_AUTOGENERATED_TAB_STYLE
|
# END_AUTOGENERATED_TAB_STYLE
|
||||||
|
|||||||
@ -4,49 +4,17 @@ function kitten --description 'Run kitten and restore Kitty theme overrides'
|
|||||||
set config_dir "$KITTY_CONFIG_DIRECTORY"
|
set config_dir "$KITTY_CONFIG_DIRECTORY"
|
||||||
end
|
end
|
||||||
|
|
||||||
set -l is_themes false
|
|
||||||
if test (count $argv) -gt 0; and test "$argv[1]" = themes
|
|
||||||
set is_themes true
|
|
||||||
end
|
|
||||||
|
|
||||||
# The automatic theme files are generated from $config_dir/theme-modes, so record
|
|
||||||
# their state first: whichever one the kitten rewrites is the theme just
|
|
||||||
# chosen for that appearance, and has to be captured before the mode is
|
|
||||||
# re-applied over the top of it.
|
|
||||||
set -l appearances dark light no-preference
|
|
||||||
set -l before
|
|
||||||
if test $is_themes = true
|
|
||||||
for appearance in $appearances
|
|
||||||
set -l file "$config_dir/$appearance-theme.auto.conf"
|
|
||||||
if test -r "$file"
|
|
||||||
set -a before (command shasum <"$file" | string split -f1 ' ')
|
|
||||||
else
|
|
||||||
set -a before missing
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
command kitten $argv
|
command kitten $argv
|
||||||
set -l kitten_status $status
|
set -l kitten_status $status
|
||||||
|
|
||||||
|
# Re-apply the pinned mode over whatever the themes kitten just wrote, and
|
||||||
|
# reload so the change shows immediately. apply-theme-mode.sh does the
|
||||||
|
# capturing itself, by checksum, so a theme saved through some other route
|
||||||
|
# -- `kitty +kitten themes`, a keybinding, another shell -- is picked up on
|
||||||
|
# its next run rather than being lost.
|
||||||
if test $kitten_status -eq 0
|
if test $kitten_status -eq 0
|
||||||
and test $is_themes = true
|
and test (count $argv) -gt 0
|
||||||
for index in (seq (count $appearances))
|
and test "$argv[1]" = themes
|
||||||
set -l appearance $appearances[$index]
|
|
||||||
set -l file "$config_dir/$appearance-theme.auto.conf"
|
|
||||||
test -r "$file"
|
|
||||||
or continue
|
|
||||||
|
|
||||||
set -l now (command shasum <"$file" | string split -f1 ' ')
|
|
||||||
test "$now" = "$before[$index]"
|
|
||||||
and continue
|
|
||||||
|
|
||||||
command mkdir -p "$config_dir/theme-modes"
|
|
||||||
or return $status
|
|
||||||
command cp "$file" "$config_dir/theme-modes/$appearance.conf"
|
|
||||||
or return $status
|
|
||||||
end
|
|
||||||
|
|
||||||
"$HOME/.config/kitty/apply-theme-mode.sh" "$config_dir"
|
"$HOME/.config/kitty/apply-theme-mode.sh" "$config_dir"
|
||||||
or return $status
|
or return $status
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user