diff options
| -rwxr-xr-x | bin/theme-gen | 223 | ||||
| -rw-r--r-- | config/alacritty/colors/dracula_plus_high_contrast.toml | 24 | ||||
| -rw-r--r-- | config/alacritty/colors/kanagawabones.toml | 24 | ||||
| -rw-r--r-- | config/alacritty/colors/solarized_osaka_night.toml | 30 | ||||
| -rw-r--r-- | config/ghostty/colors/dracula_plus_high_contrast | 21 | ||||
| -rw-r--r-- | config/ghostty/colors/kanagawabones | 21 | ||||
| -rw-r--r-- | config/ghostty/colors/solarized_osaka_night | 21 | ||||
| -rw-r--r-- | config/ghostty/colors/sonokai | 21 | ||||
| -rw-r--r-- | config/nvim/colors/dracula_plus_high_contrast.lua | 6 | ||||
| -rw-r--r-- | config/nvim/colors/kanagawabones.lua | 5 | ||||
| -rw-r--r-- | config/nvim/colors/solarized_osaka_night.lua | 5 | ||||
| -rw-r--r-- | config/tmux/colors/dracula_plus_high_contrast.conf | 6 | ||||
| -rw-r--r-- | config/tmux/colors/kanagawabones.conf | 6 | ||||
| -rw-r--r-- | config/tmux/colors/solarized_osaka_night.conf | 6 | ||||
| -rw-r--r-- | config/tmux/colors/sonokai.conf | 6 |
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 |
