summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/theme-gen223
-rw-r--r--config/alacritty/colors/dracula_plus_high_contrast.toml24
-rw-r--r--config/alacritty/colors/kanagawabones.toml24
-rw-r--r--config/alacritty/colors/solarized_osaka_night.toml30
-rw-r--r--config/ghostty/colors/dracula_plus_high_contrast21
-rw-r--r--config/ghostty/colors/kanagawabones21
-rw-r--r--config/ghostty/colors/solarized_osaka_night21
-rw-r--r--config/ghostty/colors/sonokai21
-rw-r--r--config/nvim/colors/dracula_plus_high_contrast.lua6
-rw-r--r--config/nvim/colors/kanagawabones.lua5
-rw-r--r--config/nvim/colors/solarized_osaka_night.lua5
-rw-r--r--config/tmux/colors/dracula_plus_high_contrast.conf6
-rw-r--r--config/tmux/colors/kanagawabones.conf6
-rw-r--r--config/tmux/colors/solarized_osaka_night.conf6
-rw-r--r--config/tmux/colors/sonokai.conf6
15 files changed, 425 insertions, 0 deletions
diff --git a/bin/theme-gen b/bin/theme-gen
new file mode 100755
index 0000000..6000e5e
--- /dev/null
+++ b/bin/theme-gen
@@ -0,0 +1,223 @@
+#!/bin/bash
+# Generate tmux, ghostty and (from ghostty-format sources) alacritty color
+# files, so bin/theme can use any theme with `theme --set <mode> <name>`.
+#
+# Sources: the alacritty-theme checkout (~/src/alacritty/alacritty-theme/
+# themes) by name, or any theme file by path -- alacritty-format .toml, or the
+# `palette = N=#hex` format Ghostty.app bundles its built-in themes in.
+#
+# Writes:
+# $XDG_CONFIG_HOME/tmux/colors/<name>.conf
+# $XDG_CONFIG_HOME/ghostty/colors/<name>
+# $XDG_CONFIG_HOME/alacritty/colors/<name>.toml (ghostty-format sources
+# only: an alacritty-format
+# source is used in place)
+#
+# Usage:
+# theme-gen <name> # theme from the alacritty-theme checkout
+# theme-gen /path/to/theme.toml # or a ghostty theme file
+# theme-gen -n <slug> <path> # generate as <slug>, not the basename
+# theme-gen -f <name> # overwrite existing generated files
+#
+# Nothing is activated: run `theme --set <mode> <name>` afterwards.
+
+set -euo pipefail
+
+: ${HOME:="$(cd ~ && pwd)"}
+: ${XDG_CONFIG_HOME:=$HOME/.config}
+themes_dir="$HOME/src/alacritty/alacritty-theme/themes"
+ghostty_themes_dir="/Applications/Ghostty.app/Contents/Resources/ghostty/themes"
+
+usage() {
+ sed -n '2,19p' "$0" | sed 's/^# \{0,1\}//'
+ exit "${1:-0}"
+}
+
+force=0
+while getopts :fn:h opt; do
+ case "$opt" in
+ f) force=1 ;;
+ n) override_name="$OPTARG" ;;
+ h) usage 0 ;;
+ *) usage 1 ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+if [[ $# -ne 1 ]]; then
+ usage 1
+fi
+
+src="$1"
+if [[ -f "$src" ]]; then
+ name="$(basename "$src")"
+ name="${name%.toml}"
+else
+ name="$src"
+ src="${themes_dir}/${name}.toml"
+fi
+if [[ -n "${override_name:-}" ]]; then
+ name="$override_name"
+fi
+
+if [[ ! -f "$src" ]]; then
+ echo "ERROR: no theme file at $src" >&2
+ echo "Themes available in $themes_dir:" >&2
+ ls "$themes_dir" >&2 2>/dev/null || true
+ echo "Ghostty built-ins live in $ghostty_themes_dir" >&2
+ exit 1
+fi
+
+# Ghostty bundles themes as `palette = N=#hex` plus background/foreground;
+# alacritty themes are .toml sections. Parse either into the same
+# <section>.<key>=<hex> lines (no leading '#', lowercased) the writers below
+# consume.
+parse_colors() {
+ if grep -qE '^[ \t]*palette[ \t]*=' "$src"; then
+ awk '
+ function hexof(val) {
+ if (match(val, /#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]/))
+ return tolower(substr(val, RSTART + 1, RLENGTH - 1))
+ return ""
+ }
+ BEGIN { split("black red green yellow blue magenta cyan white", K, " ") }
+ /^[ \t]*palette[ \t]*=/ {
+ line = $0
+ sub(/^[ \t]*palette[ \t]*=[ \t]*/, "", line)
+ split(line, kv, "=")
+ idx = kv[1] + 0
+ hex = tolower(kv[2]); gsub(/[ \t]/, "", hex); sub(/^#/, "", hex)
+ if (hex !~ /^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/) next
+ if (idx < 0 || idx > 15) next
+ print ((idx < 8) ? "normal" : "bright") "." K[(idx % 8) + 1] "=" hex
+ next
+ }
+ /^[ \t]*background[ \t]*=/ { hex = hexof($0); if (hex != "") print "primary.background=" hex; next }
+ /^[ \t]*foreground[ \t]*=/ { hex = hexof($0); if (hex != "") print "primary.foreground=" hex; next }
+ ' "$src"
+ else
+ awk '
+ /^[ \t]*\[/ {
+ section = $0
+ sub(/^[ \t]*\[/, "", section); sub(/\].*$/, "", section)
+ next
+ }
+ /[ \t]*=/ {
+ sect = section
+ sub(/^colors\./, "", sect)
+ if (sect != "primary" && sect != "normal" && sect != "bright") next
+ eq = index($0, "=")
+ key = substr($0, 1, eq - 1); gsub(/[ \t]/, "", key)
+ val = substr($0, eq + 1)
+ if (match(val, /"[^"]*"|'"'"'[^'"'"']*'"'"'/)) {
+ v = substr(val, RSTART + 1, RLENGTH - 2)
+ } else if (match(val, /#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]/)) {
+ v = substr(val, RSTART, RLENGTH)
+ } else next
+ gsub(/[ \t]/, "", v)
+ if (v !~ /^#?[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]$/) next
+ sub(/^#/, "", v)
+ print sect "." key "=" tolower(v)
+ }
+ ' "$src"
+ fi
+}
+
+# Ghostty-format sources have no alacritty file of their own, so theme-gen
+# writes one; alacritty-format sources are used in place, so none is written.
+ghostty_source=0
+if grep -qE '^[ \t]*palette[ \t]*=' "$src"; then
+ ghostty_source=1
+fi
+
+# no associative arrays: /bin/bash on macOS is 3.2. Keys are sanitized into
+# variable names like c_primary_background.
+c_key() {
+ printf '%s' "$1" | tr '.' '_'
+}
+while IFS='=' read -r k v; do
+ # keys come from the theme file and go through eval: accept only plain
+ # section.key names and hex values, or a theme file could run commands
+ [[ "$k" =~ ^[a-z]+\.[a-z_]+$ && "$v" =~ ^[0-9a-f]{6}$ ]] || continue
+ eval "c_$(c_key "$k")='$v'"
+done < <(parse_colors)
+
+get() {
+ local var="c_$(c_key "$1")" fallback="${2-}"
+ if [[ -n "${!var:-}" ]]; then
+ printf '%s' "${!var}"
+ elif [[ -n "$fallback" ]]; then
+ printf '%s' "$fallback"
+ else
+ echo "ERROR: theme is missing $1" >&2
+ exit 1
+ fi
+}
+
+bg="$(get primary.background)"
+fg="$(get primary.foreground)"
+
+tmux_out="$XDG_CONFIG_HOME/tmux/colors/${name}.conf"
+ghostty_out="$XDG_CONFIG_HOME/ghostty/colors/${name}"
+alacritty_out="$XDG_CONFIG_HOME/alacritty/colors/${name}.toml"
+for out in "$tmux_out" "$ghostty_out" $([[ "$ghostty_source" -eq 1 ]] && echo "$alacritty_out"); do
+ if [[ -e "$out" && "$force" -ne 1 ]]; then
+ echo "ERROR: $out already exists; use -f to overwrite" >&2
+ exit 1
+ fi
+done
+
+if [[ "$ghostty_source" -eq 1 ]]; then
+ {
+ echo "# ${name} (generated by theme-gen from ${src})"
+ echo "[colors.primary]"
+ echo "background = \"#${bg}\""
+ echo "foreground = \"#${fg}\""
+ echo
+ echo "[colors.normal]"
+ for key in black red green yellow blue magenta cyan white; do
+ echo "${key} = \"#$(get "normal.${key}")\""
+ done
+ echo
+ echo "[colors.bright]"
+ for key in black red green yellow blue magenta cyan white; do
+ echo "${key} = \"#$(get "bright.${key}")\""
+ done
+ } > "$alacritty_out"
+fi
+
+# Ghostty: primary + full 16-color palette.
+{
+ echo "# ${name} color scheme (generated by theme-gen from ${src})"
+ echo
+ echo "background = #${bg}"
+ echo "foreground = #${fg}"
+ echo
+ local_i=0
+ for section in normal bright; do
+ for key in black red green yellow blue magenta cyan white; do
+ echo "palette = ${local_i}=#$(get "${section}.${key}" "$(get "normal.${key}" "${fg}")")"
+ local_i=$((local_i + 1))
+ done
+ done
+} > "$ghostty_out"
+
+# tmux: status bar, messages, pane borders. tmux >= 3.2 takes hex directly.
+pane_border="$(get bright.black "$(get normal.black "${fg}")")"
+pane_active="$(get normal.blue "${fg}")"
+mkdir -p "$(dirname "$tmux_out")"
+{
+ echo "# ${name} (generated by theme-gen from ${src})"
+ echo "set -g status-style fg=#${fg},bg=default"
+ echo "set -g message-style fg=#${bg},bg=#${fg},fill=#${fg}"
+ echo "set -g pane-border-style fg=#${pane_border}"
+ echo "set -g pane-active-border-style fg=#${pane_active}"
+ echo "set -g window-status-current-style fg=#${fg}"
+} > "$tmux_out"
+
+echo "wrote $tmux_out"
+echo "wrote $ghostty_out"
+if [[ "$ghostty_source" -eq 1 ]]; then
+ echo "wrote $alacritty_out"
+fi
+echo "activate with: theme --set <mode> ${name}"
diff --git a/config/alacritty/colors/dracula_plus_high_contrast.toml b/config/alacritty/colors/dracula_plus_high_contrast.toml
new file mode 100644
index 0000000..6eaa8ec
--- /dev/null
+++ b/config/alacritty/colors/dracula_plus_high_contrast.toml
@@ -0,0 +1,24 @@
+# dracula_plus_high_contrast (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Dracula+ High Contrast)
+[colors.primary]
+background = "#14141a"
+foreground = "#f8f8f2"
+
+[colors.normal]
+black = "#9ba0b4"
+red = "#ff7676"
+green = "#50fa7b"
+yellow = "#ffcb6b"
+blue = "#82aaff"
+magenta = "#c792ea"
+cyan = "#8be9fd"
+white = "#f8f8f2"
+
+[colors.bright]
+black = "#9ba1b5"
+red = "#ff8a8a"
+green = "#69ff94"
+yellow = "#ffd98a"
+blue = "#d6acff"
+magenta = "#ff92df"
+cyan = "#a4ffff"
+white = "#ffffff"
diff --git a/config/alacritty/colors/kanagawabones.toml b/config/alacritty/colors/kanagawabones.toml
new file mode 100644
index 0000000..93e6eaa
--- /dev/null
+++ b/config/alacritty/colors/kanagawabones.toml
@@ -0,0 +1,24 @@
+# kanagawabones (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Kanagawabones)
+[colors.primary]
+background = "#1f1f28"
+foreground = "#ddd8bb"
+
+[colors.normal]
+black = "#1f1f28"
+red = "#e46a78"
+green = "#98bc6d"
+yellow = "#e5c283"
+blue = "#7eb3c9"
+magenta = "#957fb8"
+cyan = "#7eb3c9"
+white = "#ddd8bb"
+
+[colors.bright]
+black = "#49495e"
+red = "#ec818c"
+green = "#9ec967"
+yellow = "#f1c982"
+blue = "#7bc2df"
+magenta = "#a98fd2"
+cyan = "#7bc2df"
+white = "#a8a48d"
diff --git a/config/alacritty/colors/solarized_osaka_night.toml b/config/alacritty/colors/solarized_osaka_night.toml
new file mode 100644
index 0000000..11a1fbc
--- /dev/null
+++ b/config/alacritty/colors/solarized_osaka_night.toml
@@ -0,0 +1,30 @@
+# Solarized Osaka Night (dark variant) -- copied from ~/src/alacritty/alacritty-theme/themes/solarized_osaka.toml
+# Colors (Solarized Osaka)
+# Source https://github.com/craftzdog/solarized-osaka.nvim
+
+# Default colors
+[colors.primary]
+background = '#001a1d'
+foreground = '#839496'
+
+# Normal colors
+[colors.normal]
+black = '#073642'
+red = '#dc322f'
+green = '#859900'
+yellow = '#b58900'
+blue = '#268bd2'
+magenta = '#d33682'
+cyan = '#2aa198'
+white = '#eee8d5'
+
+# Bright colors
+[colors.bright]
+black = '#4c4c4c'
+red = '#cb4b16'
+green = '#586e75'
+yellow = '#657b83'
+blue = '#839496'
+magenta = '#6c71c4'
+cyan = '#93a1a1'
+white = '#fdf6e3'
diff --git a/config/ghostty/colors/dracula_plus_high_contrast b/config/ghostty/colors/dracula_plus_high_contrast
new file mode 100644
index 0000000..4f74f86
--- /dev/null
+++ b/config/ghostty/colors/dracula_plus_high_contrast
@@ -0,0 +1,21 @@
+# dracula_plus_high_contrast color scheme (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Dracula+ High Contrast)
+
+background = #14141a
+foreground = #f8f8f2
+
+palette = 0=#9ba0b4
+palette = 1=#ff7676
+palette = 2=#50fa7b
+palette = 3=#ffcb6b
+palette = 4=#82aaff
+palette = 5=#c792ea
+palette = 6=#8be9fd
+palette = 7=#f8f8f2
+palette = 8=#9ba1b5
+palette = 9=#ff8a8a
+palette = 10=#69ff94
+palette = 11=#ffd98a
+palette = 12=#d6acff
+palette = 13=#ff92df
+palette = 14=#a4ffff
+palette = 15=#ffffff
diff --git a/config/ghostty/colors/kanagawabones b/config/ghostty/colors/kanagawabones
new file mode 100644
index 0000000..bd1a43b
--- /dev/null
+++ b/config/ghostty/colors/kanagawabones
@@ -0,0 +1,21 @@
+# kanagawabones color scheme (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Kanagawabones)
+
+background = #1f1f28
+foreground = #ddd8bb
+
+palette = 0=#1f1f28
+palette = 1=#e46a78
+palette = 2=#98bc6d
+palette = 3=#e5c283
+palette = 4=#7eb3c9
+palette = 5=#957fb8
+palette = 6=#7eb3c9
+palette = 7=#ddd8bb
+palette = 8=#49495e
+palette = 9=#ec818c
+palette = 10=#9ec967
+palette = 11=#f1c982
+palette = 12=#7bc2df
+palette = 13=#a98fd2
+palette = 14=#7bc2df
+palette = 15=#a8a48d
diff --git a/config/ghostty/colors/solarized_osaka_night b/config/ghostty/colors/solarized_osaka_night
new file mode 100644
index 0000000..851f8eb
--- /dev/null
+++ b/config/ghostty/colors/solarized_osaka_night
@@ -0,0 +1,21 @@
+# solarized_osaka_night color scheme (generated by theme-gen from config/alacritty/colors/solarized_osaka_night.toml)
+
+background = #001a1d
+foreground = #839496
+
+palette = 0=#073642
+palette = 1=#dc322f
+palette = 2=#859900
+palette = 3=#b58900
+palette = 4=#268bd2
+palette = 5=#d33682
+palette = 6=#2aa198
+palette = 7=#eee8d5
+palette = 8=#4c4c4c
+palette = 9=#cb4b16
+palette = 10=#586e75
+palette = 11=#657b83
+palette = 12=#839496
+palette = 13=#6c71c4
+palette = 14=#93a1a1
+palette = 15=#fdf6e3
diff --git a/config/ghostty/colors/sonokai b/config/ghostty/colors/sonokai
new file mode 100644
index 0000000..9cb18c6
--- /dev/null
+++ b/config/ghostty/colors/sonokai
@@ -0,0 +1,21 @@
+# sonokai color scheme (generated by theme-gen from /Users/sz/src/alacritty/alacritty-theme/themes/sonokai.toml)
+
+background = #2c2e34
+foreground = #e2e2e3
+
+palette = 0=#181819
+palette = 1=#fc5d7c
+palette = 2=#9ed072
+palette = 3=#e7c664
+palette = 4=#76cce0
+palette = 5=#b39df3
+palette = 6=#f39660
+palette = 7=#e2e2e3
+palette = 8=#7f8490
+palette = 9=#fc5d7c
+palette = 10=#9ed072
+palette = 11=#e7c664
+palette = 12=#76cce0
+palette = 13=#b39df3
+palette = 14=#f39660
+palette = 15=#e2e2e3
diff --git a/config/nvim/colors/dracula_plus_high_contrast.lua b/config/nvim/colors/dracula_plus_high_contrast.lua
new file mode 100644
index 0000000..1248e2d
--- /dev/null
+++ b/config/nvim/colors/dracula_plus_high_contrast.lua
@@ -0,0 +1,6 @@
+-- Stand-in for "Dracula+ High Contrast" (selected via bin/theme): no dracula
+-- nvim port is installed yet, so use the closest installed dark theme rather
+-- than have `colorscheme dracula+ high contrast` error at startup. Swap when
+-- a port is added.
+vim.opt.background = "dark"
+vim.cmd("colorscheme onedark")
diff --git a/config/nvim/colors/kanagawabones.lua b/config/nvim/colors/kanagawabones.lua
new file mode 100644
index 0000000..58da269
--- /dev/null
+++ b/config/nvim/colors/kanagawabones.lua
@@ -0,0 +1,5 @@
+-- Stand-in for "Kanagawabones" (selected via bin/theme): no bones nvim port
+-- is installed yet, so use the closest installed dark theme rather than have
+-- `colorscheme kanagawabones` error at startup. Swap when a port is added.
+vim.opt.background = "dark"
+vim.cmd("colorscheme onedark")
diff --git a/config/nvim/colors/solarized_osaka_night.lua b/config/nvim/colors/solarized_osaka_night.lua
new file mode 100644
index 0000000..9eb6b01
--- /dev/null
+++ b/config/nvim/colors/solarized_osaka_night.lua
@@ -0,0 +1,5 @@
+-- Stand-in for "Solarized Osaka Night" (selected via bin/theme): no osaka
+-- nvim port is installed, so use Solarized dark -- same family, wrong accent
+-- colors. Swap when a port is added.
+vim.opt.background = "dark"
+vim.cmd("colorscheme solarized")
diff --git a/config/tmux/colors/dracula_plus_high_contrast.conf b/config/tmux/colors/dracula_plus_high_contrast.conf
new file mode 100644
index 0000000..e4360a8
--- /dev/null
+++ b/config/tmux/colors/dracula_plus_high_contrast.conf
@@ -0,0 +1,6 @@
+# dracula_plus_high_contrast (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Dracula+ High Contrast)
+set -g status-style fg=#f8f8f2,bg=default
+set -g message-style fg=#14141a,bg=#f8f8f2,fill=#f8f8f2
+set -g pane-border-style fg=#9ba1b5
+set -g pane-active-border-style fg=#82aaff
+set -g window-status-current-style fg=#f8f8f2
diff --git a/config/tmux/colors/kanagawabones.conf b/config/tmux/colors/kanagawabones.conf
new file mode 100644
index 0000000..08bd912
--- /dev/null
+++ b/config/tmux/colors/kanagawabones.conf
@@ -0,0 +1,6 @@
+# kanagawabones (generated by theme-gen from /Applications/Ghostty.app/Contents/Resources/ghostty/themes/Kanagawabones)
+set -g status-style fg=#ddd8bb,bg=default
+set -g message-style fg=#1f1f28,bg=#ddd8bb,fill=#ddd8bb
+set -g pane-border-style fg=#49495e
+set -g pane-active-border-style fg=#7eb3c9
+set -g window-status-current-style fg=#ddd8bb
diff --git a/config/tmux/colors/solarized_osaka_night.conf b/config/tmux/colors/solarized_osaka_night.conf
new file mode 100644
index 0000000..456537a
--- /dev/null
+++ b/config/tmux/colors/solarized_osaka_night.conf
@@ -0,0 +1,6 @@
+# solarized_osaka_night (generated by theme-gen from config/alacritty/colors/solarized_osaka_night.toml)
+set -g status-style fg=#839496,bg=default
+set -g message-style fg=#001a1d,bg=#839496,fill=#839496
+set -g pane-border-style fg=#4c4c4c
+set -g pane-active-border-style fg=#268bd2
+set -g window-status-current-style fg=#839496
diff --git a/config/tmux/colors/sonokai.conf b/config/tmux/colors/sonokai.conf
new file mode 100644
index 0000000..2d71aba
--- /dev/null
+++ b/config/tmux/colors/sonokai.conf
@@ -0,0 +1,6 @@
+# sonokai (generated by theme-gen from /Users/sz/src/alacritty/alacritty-theme/themes/sonokai.toml)
+set -g status-style fg=#e2e2e3,bg=default
+set -g message-style fg=#2c2e34,bg=#e2e2e3,fill=#e2e2e3
+set -g pane-border-style fg=#7f8490
+set -g pane-active-border-style fg=#76cce0
+set -g window-status-current-style fg=#e2e2e3