215 lines
7.7 KiB
Bash
Executable File
215 lines
7.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# mwxcol — Farbschema auf diesem Rechner installieren.
|
|
# Siehe README.md für die Palette und die einzelnen Zuordnungen.
|
|
|
|
set -eu
|
|
|
|
REPO=$(cd "$(dirname "$0")" && pwd)
|
|
MODE=install
|
|
USE_LINK=0
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
mwxcol — Farbschema installieren
|
|
|
|
./install.sh Themes kopieren (vorhandene Dateien nach .bak sichern)
|
|
./install.sh --link statt kopieren ins Repo symlinken — dann kann
|
|
nichts mehr auseinanderlaufen, das Repo muss aber
|
|
an seinem Platz bleiben ($REPO)
|
|
./install.sh --check nur vergleichen, nichts verändern
|
|
./install.sh --help
|
|
|
|
Ziele:
|
|
eza ~/.config/eza/theme.yml
|
|
joe ~/.joe/colors/default.jcf
|
|
fzf ~/.config/mwxcol/fzf-colors.zsh (+ eine source-Zeile in ~/.zshrc)
|
|
iTerm ~/.config/mwxcol/mwxcol.itermcolors (danach einmal importieren)
|
|
Nova ~/Library/Application Support/Nova/Extensions/org.mwx (nur macOS)
|
|
Xcode ~/Library/Developer/Xcode/UserData/FontAndColorThemes/mwxcol.xccolortheme
|
|
cc ~/.claude/themes/mwxcol.json (Claude Code, danach /theme)
|
|
EOF
|
|
}
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--link) USE_LINK=1 ;;
|
|
--check) MODE=check ;;
|
|
--help|-h) usage; exit 0 ;;
|
|
*) echo "unbekannte Option: $1" >&2; usage >&2; exit 2 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
say() { printf ' %-6s %-46s %s\n' "$1" "$2" "$3"; }
|
|
|
|
# Kürzt $HOME zu ~ für die Ausgabe.
|
|
tilde() { printf '%s' "$1" | sed "s|^$HOME|~|"; }
|
|
|
|
# install_path <name> <quelle-im-repo> <ziel>
|
|
# Funktioniert für Dateien und Verzeichnisse.
|
|
install_path() {
|
|
name=$1; src=$2; dst=$3
|
|
short=$(tilde "$dst")
|
|
|
|
if [ ! -e "$src" ]; then
|
|
say "$name" "$short" "QUELLE FEHLT: $src"
|
|
return 0
|
|
fi
|
|
|
|
if [ -L "$dst" ] && [ "$(readlink "$dst")" = "$src" ]; then
|
|
say "$name" "$short" "ok (Symlink ins Repo)"
|
|
[ "$MODE" = check ] && return 0
|
|
[ "$USE_LINK" = 1 ] && return 0
|
|
fi
|
|
|
|
if [ -e "$dst" ] && diff -r -q "$src" "$dst" >/dev/null 2>&1; then
|
|
say "$name" "$short" "ok (identisch)"
|
|
[ "$MODE" = check ] && return 0
|
|
[ "$USE_LINK" = 0 ] && return 0
|
|
fi
|
|
|
|
if [ "$MODE" = check ]; then
|
|
if [ -e "$dst" ]; then
|
|
say "$name" "$short" "WEICHT AB"
|
|
else
|
|
say "$name" "$short" "fehlt"
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$dst")"
|
|
|
|
if [ -e "$dst" ] && [ ! -L "$dst" ]; then
|
|
rm -rf "$dst.bak"
|
|
cp -R "$dst" "$dst.bak"
|
|
note="Backup: $(basename "$dst").bak"
|
|
else
|
|
note=""
|
|
fi
|
|
|
|
rm -rf "$dst"
|
|
if [ "$USE_LINK" = 1 ]; then
|
|
ln -sfn "$src" "$dst"
|
|
say "$name" "$short" "verlinkt $note"
|
|
else
|
|
cp -R "$src" "$dst"
|
|
say "$name" "$short" "kopiert $note"
|
|
fi
|
|
}
|
|
|
|
echo "mwxcol aus $REPO"
|
|
[ "$MODE" = check ] && echo "(nur Prüfung — es wird nichts verändert)"
|
|
echo
|
|
|
|
install_path eza "$REPO/themes/eza/theme.yml" "$HOME/.config/eza/theme.yml"
|
|
install_path joe "$REPO/themes/joe/default.jcf" "$HOME/.joe/colors/default.jcf"
|
|
install_path fzf "$REPO/themes/fzf/colors.zsh" "$HOME/.config/mwxcol/fzf-colors.zsh"
|
|
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
install_path iterm "$REPO/themes/iterm/mwxcol.itermcolors" \
|
|
"$HOME/.config/mwxcol/mwxcol.itermcolors"
|
|
else
|
|
say iterm "-" "übersprungen (nur macOS)"
|
|
fi
|
|
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
install_path nova "$REPO/themes/nova/mwx.novaextension" \
|
|
"$HOME/Library/Application Support/Nova/Extensions/org.mwx"
|
|
else
|
|
say nova "-" "übersprungen (nur macOS)"
|
|
fi
|
|
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
install_path xcode "$REPO/themes/xcode/mwxcol.xccolortheme" \
|
|
"$HOME/Library/Developer/Xcode/UserData/FontAndColorThemes/mwxcol.xccolortheme"
|
|
else
|
|
say xcode "-" "übersprungen (nur macOS)"
|
|
fi
|
|
|
|
# Claude Code liest ~/.claude/themes/*.json und benennt das Theme nach dem
|
|
# Dateinamen; CLAUDE_CONFIG_DIR verschiebt das Verzeichnis.
|
|
install_path cc "$REPO/themes/claude-code/mwxcol.json" \
|
|
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/themes/mwxcol.json"
|
|
|
|
# fzf wird nicht über eine Theme-Datei geladen, sondern über eine Umgebungs-
|
|
# variable — die Datei oben muss also von der Shell gesourct werden.
|
|
echo
|
|
SRC_LINE='[ -f ~/.config/mwxcol/fzf-colors.zsh ] && source ~/.config/mwxcol/fzf-colors.zsh'
|
|
if [ -f "$HOME/.zshrc" ] && grep -q 'mwxcol/fzf-colors.zsh' "$HOME/.zshrc"; then
|
|
echo "fzf: ~/.zshrc sourct die Farbdatei bereits."
|
|
elif [ -f "$HOME/.zshrc" ] && grep -q '# fzf — Palette aus mwxcol.go' "$HOME/.zshrc"; then
|
|
echo "fzf: ~/.zshrc enthält den Farbblock bereits direkt — nichts zu tun."
|
|
echo " (Wer stattdessen die Repo-Datei sourcen will: Block löschen und"
|
|
echo " diese Zeile eintragen)"
|
|
echo " $SRC_LINE"
|
|
else
|
|
echo "fzf: noch nicht in ~/.zshrc verdrahtet. Diese Zeile eintragen:"
|
|
echo " $SRC_LINE"
|
|
fi
|
|
|
|
# iTerm2 hält seine Einstellungen im Speicher und schreibt sie beim Beenden
|
|
# zurück — eine direkt bearbeitete Plist wäre also wieder weg. Deshalb wird
|
|
# das Preset nur bereitgelegt und einmalig von Hand importiert.
|
|
if [ "$(uname)" = "Darwin" ] && [ -e "$HOME/Library/Preferences/com.googlecode.iterm2.plist" ]; then
|
|
echo
|
|
themed=$(python3 - <<'PY' 2>/dev/null || true
|
|
import plistlib, subprocess, os
|
|
p = os.path.expanduser("~/Library/Preferences/com.googlecode.iterm2.plist")
|
|
xml = subprocess.run(["plutil","-convert","xml1","-o","-",p],
|
|
capture_output=True).stdout
|
|
d = plistlib.loads(xml)
|
|
for prof in d.get("New Bookmarks", []):
|
|
if prof.get("Name") != "Default":
|
|
continue
|
|
c = prof.get("Ansi 1 Color") or {}
|
|
hx = "%02X%02X%02X" % tuple(round(c.get(k, 0) * 255)
|
|
for k in ("Red Component", "Green Component", "Blue Component"))
|
|
print("ja" if hx == "F38BA8" else "nein")
|
|
PY
|
|
)
|
|
if [ "$themed" = "ja" ]; then
|
|
echo "iTerm2: Profil \"Default\" trägt die Palette bereits."
|
|
else
|
|
echo "iTerm2: Profil \"Default\" trägt noch nicht die Palette. Einmalig:"
|
|
echo " Einstellungen > Profiles > Colors > Color Presets… > Import…"
|
|
echo " $(tilde "$HOME/.config/mwxcol/mwxcol.itermcolors")"
|
|
echo " danach im selben Menü \"mwxcol\" auswählen."
|
|
echo " Vorher ansehen: $(tilde "$REPO")/themes/iterm/preview.sh"
|
|
fi
|
|
fi
|
|
|
|
# Claude Code merkt sich das Theme in den Settings, nicht am Dateinamen.
|
|
CC_SETTINGS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json"
|
|
if [ -f "$CC_SETTINGS" ]; then
|
|
echo
|
|
if grep -q '"theme"[[:space:]]*:[[:space:]]*"custom:mwxcol"' "$CC_SETTINGS"; then
|
|
echo "Claude Code: Theme mwxcol ist gewählt."
|
|
else
|
|
echo "Claude Code: Theme noch nicht gewählt — /theme > mwxcol, oder in"
|
|
echo " $(tilde "$CC_SETTINGS") eintragen: \"theme\": \"custom:mwxcol\""
|
|
fi
|
|
fi
|
|
|
|
# Xcode führt hell und dunkel getrennt (XCFontAndColorCurrentTheme und
|
|
# …CurrentDarkTheme). Die Datei bereitzulegen reicht also nicht, sie muss in
|
|
# den Einstellungen ausgewählt werden — und ein laufendes Xcode sieht eine neu
|
|
# hinzugekommene Theme-Datei erst nach dem Neustart.
|
|
if [ "$(uname)" = "Darwin" ] && [ -d "$HOME/Library/Developer/Xcode" ]; then
|
|
echo
|
|
light=$(defaults read com.apple.dt.Xcode XCFontAndColorCurrentTheme 2>/dev/null || echo "—")
|
|
dark=$(defaults read com.apple.dt.Xcode XCFontAndColorCurrentDarkTheme 2>/dev/null || echo "—")
|
|
if [ "$light" = "mwxcol.xccolortheme" ] && [ "$dark" = "mwxcol.xccolortheme" ]; then
|
|
echo "Xcode: mwxcol ist gewählt (hell und dunkel)."
|
|
else
|
|
echo "Xcode: mwxcol noch nicht überall gewählt."
|
|
echo " aktuell hell: $light"
|
|
echo " aktuell dunkel: $dark"
|
|
echo " Einstellungen > Themes > mwxcol (Xcode ggf. vorher neu starten)."
|
|
fi
|
|
fi
|
|
|
|
if [ "$MODE" != check ]; then
|
|
echo
|
|
echo "Danach: exec zsh — Nova-Theme unter Einstellungen > Themes > mwx wählen."
|
|
fi
|