Compare commits
2 Commits
a4eb8ae75d
...
9c339fb730
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c339fb730 | ||
|
|
a68b138d38 |
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
config_dir=${1:-"$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"}
|
||||||
|
|
||||||
|
for appearance in dark light no-preference; do
|
||||||
|
config_file="$config_dir/$appearance-theme.auto.conf"
|
||||||
|
[ -f "$config_file" ] || continue
|
||||||
|
|
||||||
|
if awk '
|
||||||
|
$1 == "macos_titlebar_color" {
|
||||||
|
count++
|
||||||
|
if ($2 == "background") correct++
|
||||||
|
}
|
||||||
|
END { exit !(count == 1 && correct == 1) }
|
||||||
|
' "$config_file"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp=$(mktemp "$config_file.tmp.XXXXXX")
|
||||||
|
trap 'rm -f "$tmp"' EXIT HUP INT TERM
|
||||||
|
awk '$1 != "macos_titlebar_color"' "$config_file" > "$tmp"
|
||||||
|
printf '\nmacos_titlebar_color background\n' >> "$tmp"
|
||||||
|
chmod "$(stat -f '%Lp' "$config_file")" "$tmp"
|
||||||
|
mv -f "$tmp" "$config_file"
|
||||||
|
trap - EXIT HUP INT TERM
|
||||||
|
done
|
||||||
@ -1,28 +1,23 @@
|
|||||||
background #ffffff
|
background #f8f8f8
|
||||||
foreground #4c4c4c
|
foreground #2a2b33
|
||||||
cursor #4c4c4c
|
cursor #bbbbbb
|
||||||
selection_background #d6d6d6
|
selection_background #e5e5e6
|
||||||
color0 #000000
|
color0 #000000
|
||||||
color8 #000000
|
color8 #000000
|
||||||
color1 #c82828
|
color1 #de3d35
|
||||||
color9 #c82828
|
color9 #de3d35
|
||||||
color2 #708b00
|
color2 #3e953a
|
||||||
color10 #708b00
|
color10 #3e953a
|
||||||
color3 #e9b600
|
color3 #d2b67b
|
||||||
color11 #e9b600
|
color11 #d2b67b
|
||||||
color4 #4170ae
|
color4 #2f5af3
|
||||||
color12 #4170ae
|
color12 #2f5af3
|
||||||
color5 #8958a7
|
color5 #950095
|
||||||
color13 #8958a7
|
color13 #a00095
|
||||||
color6 #3d999f
|
color6 #3e953a
|
||||||
color14 #3d999f
|
color14 #3e953a
|
||||||
color7 #fffefe
|
color7 #bbbbbb
|
||||||
color15 #fffefe
|
color15 #ffffff
|
||||||
selection_foreground #ffffff
|
selection_foreground #2a2b33
|
||||||
|
|
||||||
active_tab_foreground #ffffff
|
|
||||||
active_tab_background #2e84e6
|
|
||||||
inactive_tab_foreground #2e84e6
|
|
||||||
inactive_tab_background #ffffff
|
|
||||||
|
|
||||||
macos_titlebar_color background
|
macos_titlebar_color background
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||||
|
tmpdir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$tmpdir"' EXIT HUP INT TERM
|
||||||
|
config_dir="$tmpdir/config"
|
||||||
|
fake_bin="$tmpdir/bin"
|
||||||
|
log="$tmpdir/commands.log"
|
||||||
|
mkdir -p "$config_dir" "$fake_bin"
|
||||||
|
|
||||||
|
printf 'background #111111\n' > "$config_dir/dark-theme.auto.conf"
|
||||||
|
printf 'background #eeeeee\nmacos_titlebar_color system\n' \
|
||||||
|
> "$config_dir/light-theme.auto.conf"
|
||||||
|
printf 'background #222222\nmacos_titlebar_color background\n' \
|
||||||
|
> "$config_dir/no-preference-theme.auto.conf"
|
||||||
|
|
||||||
|
"$root/repair-auto-themes.sh" "$config_dir"
|
||||||
|
"$root/tests/verify_auto_themes.sh" "$config_dir"
|
||||||
|
|
||||||
|
for appearance in dark light no-preference; do
|
||||||
|
count=$(grep -c '^macos_titlebar_color background$' \
|
||||||
|
"$config_dir/$appearance-theme.auto.conf")
|
||||||
|
[ "$count" -eq 1 ]
|
||||||
|
done
|
||||||
|
|
||||||
|
before=$(shasum "$config_dir"/*-theme.auto.conf)
|
||||||
|
"$root/repair-auto-themes.sh" "$config_dir"
|
||||||
|
after=$(shasum "$config_dir"/*-theme.auto.conf)
|
||||||
|
[ "$before" = "$after" ]
|
||||||
|
|
||||||
|
cat > "$fake_bin/kitten" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
printf 'kitten %s\n' "$*" >> "$TEST_LOG"
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
cat > "$fake_bin/kitty" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
printf 'kitty %s\n' "$*" >> "$TEST_LOG"
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
chmod +x "$fake_bin/kitten" "$fake_bin/kitty"
|
||||||
|
|
||||||
|
printf 'background #fafafa\n' > "$config_dir/light-theme.auto.conf"
|
||||||
|
TEST_LOG="$log" PATH="$fake_bin:$PATH" \
|
||||||
|
KITTY_CONFIG_DIRECTORY="$config_dir" KITTY_WINDOW_ID=1 \
|
||||||
|
fish --no-config -c \
|
||||||
|
'source "$HOME/.config/fish/functions/kitten.fish"; kitten themes Tomorrow'
|
||||||
|
grep -q '^kitten themes Tomorrow$' "$log"
|
||||||
|
grep -q '^kitty @ load-config$' "$log"
|
||||||
|
"$root/tests/verify_auto_themes.sh" "$config_dir"
|
||||||
|
|
||||||
|
: > "$log"
|
||||||
|
TEST_LOG="$log" PATH="$fake_bin:$PATH" \
|
||||||
|
KITTY_CONFIG_DIRECTORY="$config_dir" KITTY_WINDOW_ID=1 \
|
||||||
|
fish --no-config -c \
|
||||||
|
'source "$HOME/.config/fish/functions/kitten.fish"; kitten icat image.png'
|
||||||
|
grep -q '^kitten icat image.png$' "$log"
|
||||||
|
if grep -q '^kitty ' "$log"; then
|
||||||
|
echo "non-theme kitten command triggered a Kitty reload" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "PASS: theme repair is idempotent and the Fish shim only intercepts themes"
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
from importlib.util import module_from_spec, spec_from_file_location
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from kitty.fast_data_types import Color
|
||||||
|
from kitty.tab_bar import DrawData, ExtraData, TabBarData, as_rgb
|
||||||
|
|
||||||
|
|
||||||
|
class Cursor:
|
||||||
|
x = 0
|
||||||
|
fg = as_rgb(0xFEDCBA)
|
||||||
|
bg = as_rgb(0xABCDEF)
|
||||||
|
|
||||||
|
|
||||||
|
class RecordingScreen:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.cursor = Cursor()
|
||||||
|
self.draws: list[tuple[str, int, int]] = []
|
||||||
|
|
||||||
|
def draw(self, text: str) -> None:
|
||||||
|
self.draws.append((text, self.cursor.fg, self.cursor.bg))
|
||||||
|
self.cursor.x += len(text)
|
||||||
|
|
||||||
|
|
||||||
|
def load_renderer():
|
||||||
|
path = Path.cwd() / "tab_bar.py"
|
||||||
|
spec = spec_from_file_location("kitty_user_tab_bar", path)
|
||||||
|
if spec is None or spec.loader is None:
|
||||||
|
raise RuntimeError(f"cannot load {path}")
|
||||||
|
module = module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
def draw_data(theme_bg: int) -> DrawData:
|
||||||
|
return DrawData(
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
(),
|
||||||
|
Color(0x11, 0x11, 0x11),
|
||||||
|
Color(0xAB, 0xCD, 0xEF),
|
||||||
|
Color(0xFE, 0xDC, 0xBA),
|
||||||
|
Color(0x22, 0x22, 0x22),
|
||||||
|
Color((theme_bg >> 16) & 0xFF, (theme_bg >> 8) & 0xFF, theme_bg & 0xFF),
|
||||||
|
"",
|
||||||
|
None,
|
||||||
|
"",
|
||||||
|
"default",
|
||||||
|
"top",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
renderer = load_renderer()
|
||||||
|
for theme_bg in (0xF8F8F8, 0x1C2836):
|
||||||
|
roles = renderer.tab_colors(draw_data(theme_bg).default_bg)
|
||||||
|
actual_roles = tuple(int(value) for value in roles)
|
||||||
|
expected_roles = (theme_bg, 0x2E84E6, 0x2E84E6, theme_bg)
|
||||||
|
if actual_roles != expected_roles:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"theme #{theme_bg:06x}: expected roles {expected_roles!r}, "
|
||||||
|
f"got {actual_roles!r}"
|
||||||
|
)
|
||||||
|
|
||||||
|
for is_active, expected in (
|
||||||
|
(True, (as_rgb(theme_bg), as_rgb(0x2E84E6))),
|
||||||
|
(False, (as_rgb(0x2E84E6), as_rgb(theme_bg))),
|
||||||
|
):
|
||||||
|
screen = RecordingScreen()
|
||||||
|
renderer.draw_tab(
|
||||||
|
draw_data(theme_bg),
|
||||||
|
screen,
|
||||||
|
TabBarData("tab", is_active=is_active),
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
True,
|
||||||
|
ExtraData(),
|
||||||
|
)
|
||||||
|
_, actual_fg, actual_bg = screen.draws[0]
|
||||||
|
if (actual_fg, actual_bg) != expected:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"theme #{theme_bg:06x}, active={is_active}: "
|
||||||
|
f"expected cursor colors {expected!r}, "
|
||||||
|
f"got {(actual_fg, actual_bg)!r}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(
|
||||||
|
"PASS: tab colors ignore theme-provided tab roles "
|
||||||
|
"for light and dark backgrounds"
|
||||||
|
)
|
||||||
@ -1,16 +1,35 @@
|
|||||||
from kitty.fast_data_types import Screen
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
from kitty.fast_data_types import Color, Screen
|
||||||
from kitty.tab_bar import DrawData, ExtraData, TabBarData, as_rgb, draw_title
|
from kitty.tab_bar import DrawData, ExtraData, TabBarData, as_rgb, draw_title
|
||||||
|
|
||||||
|
|
||||||
|
class TabColors(NamedTuple):
|
||||||
|
active_fg: Color
|
||||||
|
active_bg: Color
|
||||||
|
inactive_fg: Color
|
||||||
|
inactive_bg: Color
|
||||||
|
|
||||||
|
|
||||||
|
TAB_ACCENT = Color(0x2e, 0x84, 0xe6)
|
||||||
|
|
||||||
|
|
||||||
|
def tab_colors(theme_bg: Color) -> TabColors:
|
||||||
|
return TabColors(theme_bg, TAB_ACCENT, TAB_ACCENT, theme_bg)
|
||||||
|
|
||||||
|
|
||||||
def draw_tab(
|
def draw_tab(
|
||||||
draw_data: DrawData, screen: Screen, tab: TabBarData,
|
draw_data: DrawData, screen: Screen, tab: TabBarData,
|
||||||
before: int, max_title_length: int, index: int, is_last: bool,
|
before: int, max_title_length: int, index: int, is_last: bool,
|
||||||
extra_data: ExtraData
|
extra_data: ExtraData
|
||||||
) -> int:
|
) -> int:
|
||||||
active_fg = draw_data.default_bg
|
colors = tab_colors(draw_data.default_bg)
|
||||||
|
fg = colors.active_fg if tab.is_active else colors.inactive_fg
|
||||||
|
bg = colors.active_bg if tab.is_active else colors.inactive_bg
|
||||||
default_bg = as_rgb(int(draw_data.default_bg))
|
default_bg = as_rgb(int(draw_data.default_bg))
|
||||||
orig_fg = as_rgb(int(active_fg)) if tab.is_active else screen.cursor.fg
|
orig_fg = as_rgb(int(fg))
|
||||||
orig_bg = screen.cursor.bg if tab.is_active else default_bg
|
orig_bg = as_rgb(int(bg))
|
||||||
title_draw_data = draw_data._replace(active_fg=active_fg) if tab.is_active else draw_data
|
title_draw_data = draw_data._replace(**colors._asdict())
|
||||||
screen.cursor.fg = orig_fg
|
screen.cursor.fg = orig_fg
|
||||||
screen.cursor.bg = orig_bg
|
screen.cursor.bg = orig_bg
|
||||||
left_sep, right_sep = ('', '')
|
left_sep, right_sep = ('', '')
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
function kitten --description 'Run kitten and restore Kitty theme overrides'
|
||||||
|
command kitten $argv
|
||||||
|
set -l kitten_status $status
|
||||||
|
|
||||||
|
if test $kitten_status -eq 0
|
||||||
|
and test (count $argv) -gt 0
|
||||||
|
and test "$argv[1]" = themes
|
||||||
|
set -l config_dir "$HOME/.config/kitty"
|
||||||
|
if set -q KITTY_CONFIG_DIRECTORY
|
||||||
|
set config_dir "$KITTY_CONFIG_DIRECTORY"
|
||||||
|
end
|
||||||
|
|
||||||
|
"$HOME/.config/kitty/repair-auto-themes.sh" "$config_dir"
|
||||||
|
or return $status
|
||||||
|
|
||||||
|
if set -q KITTY_WINDOW_ID
|
||||||
|
command kitty @ load-config
|
||||||
|
or return $status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return $kitten_status
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user