colour -> color, behaviour -> behavior, centre -> center, favourite -> favorite, and about twenty other pairs, applied consistently across comments, docs, error/UI copy, and a handful of QML identifiers that used the British spelling as their actual name: SystemSettings' serialiseValue/serialiseTable/normaliseGradient, Displays' normaliseModes, Wallpaper's normalisePolicy, SettingsBackup's serialiseHomeState, DateTime's ntpSynchronised property, Clipboard's _normalise helper, and ShortcutCapture's cancelled signal (with its onCancelled handler in ShortcutsPage.qml). Every call site and the two tests that assert on the literal source text (settings-ownership and settings-backup-live contracts) were updated in lockstep. Left untouched: config/dot/espanso/match/packages/misspell-en/ is a vendored third-party autocorrect dictionary -- its entries are typo corrections, not our prose, and rewriting them would fight the package's own purpose (and any future re-sync from upstream). The already-American `favorites` property (Home page pinned accessories) was never actually misspelled -- only nearby comments and error strings said "favourites" -- so no data migration was needed there. Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
262 lines
11 KiB
Bash
Executable File
262 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# --- Helper functions ---
|
|
log() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
|
|
|
|
# Define paths as they have not been defined by new bashrc yet!
|
|
PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
|
|
PANAMA_BASH="${PANAMA_BASH:-$PANAMA_PATH/config/bash}"
|
|
PANAMA_DOT="$PANAMA_PATH/config/dot"
|
|
PANAMA_OLD="$PANAMA_PATH/config/old"
|
|
CONFIG="$HOME/.config"
|
|
|
|
# Make backup folder if it doesn't exist
|
|
mkdir -p "$PANAMA_OLD"
|
|
|
|
# --- Bashrc ---
|
|
echo -e "\n--- Replacing .bashrc ---"
|
|
# Backup existing .bashrc if it's a regular file
|
|
if [ -f "$HOME/.bashrc" ] && [ ! -L "$HOME/.bashrc" ]; then
|
|
log "Backing up existing .bashrc"
|
|
mv "$HOME/.bashrc" "$PANAMA_OLD/.bashrc"
|
|
fi
|
|
# Remove old symlink if it exists and points somewhere else
|
|
if [ -L "$HOME/.bashrc" ]; then
|
|
log "Removing old .bashrc symlink"
|
|
rm "$HOME/.bashrc"
|
|
fi
|
|
# Symlink Panama .bashrc file to ~/.bashrc
|
|
log "Symlinking Panama .bashrc file to ~/.bashrc"
|
|
ln -s "$PANAMA_BASH/.bashrc" "$HOME/.bashrc"
|
|
|
|
# Each entry is symlinked as ~/.config/<name> -> $PANAMA_DOT/<name>.
|
|
# "forge" is the GNOME tiling extension; "hypr"/"quickshell"/"wofi" are the
|
|
# Hyprland desktop. They coexist deliberately — the GNOME session keeps working
|
|
# while Hyprland is being used, so you can log back into either.
|
|
dirs=("espanso" "forge" "ghostty" "gtk-3.0" "gtk-4.0" "hypr" "kitty" "nvim" \
|
|
"quickshell" "tmux" "uwsm" "vicinae" "wofi" "xdg-desktop-portal")
|
|
|
|
# --- Vim vimrc ---
|
|
echo -e "\n--- Setting up vim ---"
|
|
mkdir -p "$HOME/.vim"
|
|
if [ -L "$HOME/.vim/vimrc" ]; then
|
|
rm "$HOME/.vim/vimrc"
|
|
log "Removed old symlink at ~/.vim/vimrc"
|
|
fi
|
|
if [ -f "$HOME/.vim/vimrc" ]; then
|
|
mv "$HOME/.vim/vimrc" "$PANAMA_OLD/vimrc"
|
|
log "Moved existing ~/.vim/vimrc to $PANAMA_OLD/vimrc"
|
|
fi
|
|
ln -s "$PANAMA_DOT/vim/vimrc" "$HOME/.vim/vimrc"
|
|
log "Linked $PANAMA_DOT/vim/vimrc → ~/.vim/vimrc"
|
|
|
|
for dir in "${dirs[@]}"; do
|
|
echo -e "\n--- Setting up $dir ---"
|
|
|
|
# Remove old symlink if it exists
|
|
if [ -L "$CONFIG/$dir" ]; then
|
|
rm "$CONFIG/$dir"
|
|
log "Removed old symlink at $CONFIG/$dir"
|
|
fi
|
|
|
|
# Backup existing directory if it exists
|
|
if [ -d "$CONFIG/$dir" ]; then
|
|
mv "$CONFIG/$dir" "$PANAMA_OLD/$dir"
|
|
log "Moved existing $dir config to $PANAMA_OLD/$dir"
|
|
# A regular file at this path (not a directory, not a symlink) is missed by
|
|
# the guards above, so `ln -s` below would fail with "File exists" -- back
|
|
# it up the same way.
|
|
elif [ -f "$CONFIG/$dir" ]; then
|
|
mv "$CONFIG/$dir" "$PANAMA_OLD/$dir"
|
|
log "Moved existing $dir file to $PANAMA_OLD/$dir"
|
|
fi
|
|
|
|
# Create symlink
|
|
ln -s "$PANAMA_DOT/$dir" "$CONFIG/$dir"
|
|
log "Linked $PANAMA_DOT/$dir → $CONFIG/$dir"
|
|
done
|
|
|
|
# tmux.conf ends with a source-file of current-theme.conf, generated from the
|
|
# color scheme rather than committed. Seed it so a fresh checkout starts themed
|
|
# -- the source-file is -q, so a missing file is silent, which would leave tmux
|
|
# unstyled with nothing to explain it.
|
|
TMUX_THEME="$PANAMA_DOT/tmux/current-theme.conf"
|
|
if [ -e "$TMUX_THEME" ]; then
|
|
log "Keeping existing tmux theme at $TMUX_THEME"
|
|
elif [ -d "$PANAMA_DOT/tmux/themes" ]; then
|
|
tmux_scheme="dark"
|
|
tmux_prefs="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
|
|
if [ -r "$tmux_prefs" ]; then
|
|
tmux_stored="$(jq -r '.colorScheme // "dark"' "$tmux_prefs" 2>/dev/null || echo dark)"
|
|
[ "$tmux_stored" = "light" ] && tmux_scheme="light"
|
|
fi
|
|
[ "$tmux_scheme" = "light" ] && tmux_name="tokyonight-day" || tmux_name="tokyonight-moon"
|
|
cp "$PANAMA_DOT/tmux/themes/$tmux_name.conf" "$TMUX_THEME"
|
|
log "Seeded tmux $tmux_scheme theme ($tmux_name) → $TMUX_THEME"
|
|
fi
|
|
|
|
# hyprlock.conf is generated from a template on every color scheme change and
|
|
# is not committed. Seed it so the FIRST lock of a fresh install is themed --
|
|
# without it hyprlock falls back to its own defaults, which is a bare gray
|
|
# screen with none of this desktop's identity, and the first time anyone would
|
|
# find out is when they walked away from the machine.
|
|
HYPRLOCK_TEMPLATE="$PANAMA_DOT/hypr/hyprlock.conf.template"
|
|
HYPRLOCK_CONF="$PANAMA_DOT/hypr/hyprlock.conf"
|
|
if [ -e "$HYPRLOCK_CONF" ]; then
|
|
log "Keeping existing hyprlock config at $HYPRLOCK_CONF"
|
|
elif [ -r "$HYPRLOCK_TEMPLATE" ]; then
|
|
lock_scheme="dark"
|
|
lock_prefs="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
|
|
if [ -r "$lock_prefs" ]; then
|
|
lock_stored="$(jq -r '.colorScheme // "dark"' "$lock_prefs" 2>/dev/null || echo dark)"
|
|
[ "$lock_stored" = "light" ] && lock_scheme="light"
|
|
fi
|
|
if [ "$lock_scheme" = "light" ]; then
|
|
sed -e "s/@FG@/55, 96, 191/g" -e "s/@MUTED@/97, 114, 176/g" \
|
|
-e "s/@ACCENT@/46, 125, 233/g" -e "s/@ERROR@/245, 42, 101/g" \
|
|
-e "s/@BG@/225, 226, 231/g" -e "s/@FIELD@/208, 213, 227/g" \
|
|
-e "s/@MUTED_HEX@/6172b0/g" -e "s/@ERROR_HEX@/f52a65/g" \
|
|
"$HYPRLOCK_TEMPLATE" > "$HYPRLOCK_CONF"
|
|
else
|
|
sed -e "s/@FG@/200, 211, 245/g" -e "s/@MUTED@/130, 139, 184/g" \
|
|
-e "s/@ACCENT@/130, 170, 255/g" -e "s/@ERROR@/255, 117, 127/g" \
|
|
-e "s/@BG@/34, 36, 54/g" -e "s/@FIELD@/46, 47, 61/g" \
|
|
-e "s/@MUTED_HEX@/828bb8/g" -e "s/@ERROR_HEX@/ff757f/g" \
|
|
"$HYPRLOCK_TEMPLATE" > "$HYPRLOCK_CONF"
|
|
fi
|
|
log "Seeded hyprlock $lock_scheme theme → $HYPRLOCK_CONF"
|
|
fi
|
|
|
|
# btop reads themes from its own config directory, but OWNS btop.conf -- it
|
|
# rewrites that file on exit -- so only the theme files are exposed, per file,
|
|
# and the config itself is left to btop. panama-theme-apps edits the single
|
|
# color_theme line in place.
|
|
BTOP_THEME_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/btop/themes"
|
|
mkdir -p "$BTOP_THEME_DIR"
|
|
for btop_theme_src in "$PANAMA_DOT"/btop/themes/*.theme; do
|
|
[ -e "$btop_theme_src" ] || continue
|
|
btop_theme_dst="$BTOP_THEME_DIR/$(basename "$btop_theme_src")"
|
|
if [ -L "$btop_theme_dst" ]; then
|
|
rm "$btop_theme_dst"
|
|
fi
|
|
if [ -e "$btop_theme_dst" ]; then
|
|
log "Keeping existing btop theme at $btop_theme_dst"
|
|
else
|
|
ln -s "$btop_theme_src" "$btop_theme_dst"
|
|
log "Linked btop theme → $btop_theme_dst"
|
|
fi
|
|
done
|
|
|
|
# GTK3 has no include mechanism, so its settings.ini is generated whole from a
|
|
# template rather than layered. Without this, a fresh checkout has a template
|
|
# and no settings.ini, and GTK3 applications fall back to their built-in theme.
|
|
# panama-theme-apps rewrites both files on every scheme change after this.
|
|
for gtk_version in 3.0 4.0; do
|
|
gtk_template="$PANAMA_DOT/gtk-$gtk_version/settings.ini.template"
|
|
gtk_settings="$PANAMA_DOT/gtk-$gtk_version/settings.ini"
|
|
[ -r "$gtk_template" ] || continue
|
|
if [ -e "$gtk_settings" ]; then
|
|
log "Keeping existing GTK settings at $gtk_settings"
|
|
else
|
|
gtk_scheme="dark"
|
|
gtk_prefs="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
|
|
if [ -r "$gtk_prefs" ]; then
|
|
gtk_stored="$(jq -r '.colorScheme // "dark"' "$gtk_prefs" 2>/dev/null || echo dark)"
|
|
[ "$gtk_stored" = "light" ] && gtk_scheme="light"
|
|
fi
|
|
if [ "$gtk_scheme" = "light" ]; then
|
|
gtk_name="adw-gtk3"; gtk_dark=0
|
|
else
|
|
gtk_name="adw-gtk3-dark"; gtk_dark=1
|
|
fi
|
|
sed -e "s/@GTK_THEME@/$gtk_name/" -e "s/@PREFER_DARK@/$gtk_dark/" \
|
|
"$gtk_template" > "$gtk_settings"
|
|
log "Generated GTK $gtk_version settings ($gtk_name) → $gtk_settings"
|
|
fi
|
|
done
|
|
|
|
# kitty.conf ends with `include current-theme.conf`, and that file is generated
|
|
# from the desktop color scheme rather than committed -- it is machine state.
|
|
# A fresh checkout therefore has no such file, and kitty starts by complaining
|
|
# about a missing include and falling back to its stock colors. Seed it from
|
|
# the scheme in settings.json (dark unless the user has chosen otherwise) so a
|
|
# first launch is themed; ColorScheme.qml overwrites it on every change after.
|
|
KITTY_THEME="$PANAMA_DOT/kitty/current-theme.conf"
|
|
if [ -e "$KITTY_THEME" ]; then
|
|
log "Keeping existing kitty theme at $KITTY_THEME"
|
|
else
|
|
scheme="dark"
|
|
settings="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
|
|
if [ -r "$settings" ]; then
|
|
stored="$(jq -r '.colorScheme // "dark"' "$settings" 2>/dev/null || echo dark)"
|
|
[ "$stored" = "light" ] && scheme="light"
|
|
fi
|
|
[ "$scheme" = "light" ] && theme="tokyonight-day" || theme="tokyonight-moon"
|
|
cp "$PANAMA_DOT/kitty/themes/$theme.conf" "$KITTY_THEME"
|
|
log "Seeded kitty $scheme theme ($theme) → $KITTY_THEME"
|
|
fi
|
|
|
|
# Vicinae 0.26 discovers user themes from its XDG data directory rather than
|
|
# from ~/.config/vicinae. Keep the authored theme in Panama with the rest of
|
|
# the launcher config and expose only that file at Vicinae's runtime path.
|
|
VICINAE_THEME_DIR="$HOME/.local/share/vicinae/themes"
|
|
mkdir -p "$VICINAE_THEME_DIR"
|
|
|
|
# Every authored theme, not just the dark one: vicinae.json selects a theme per
|
|
# system appearance, so linking only Moon left the launcher falling back to its
|
|
# stock palette whenever Panama was in light mode.
|
|
for theme_src in "$PANAMA_DOT"/vicinae/themes/*.toml; do
|
|
[ -e "$theme_src" ] || continue
|
|
theme_dst="$VICINAE_THEME_DIR/$(basename "$theme_src")"
|
|
|
|
if [ -L "$theme_dst" ]; then
|
|
rm "$theme_dst"
|
|
fi
|
|
|
|
if [ -e "$theme_dst" ]; then
|
|
log "Keeping existing Vicinae theme at $theme_dst"
|
|
else
|
|
ln -s "$theme_src" "$theme_dst"
|
|
log "Linked Vicinae theme → $theme_dst"
|
|
fi
|
|
done
|
|
|
|
# Panama-native applications live in the user data directory so launchers can
|
|
# discover them alongside system desktop entries. Keep each authored file in
|
|
# the repository and expose it with a narrow per-file symlink.
|
|
# Panama ships its own application icons. Without these the desktop entries fall
|
|
# back to a generic symbolic glyph, which is drawn for 16px toolbar use and
|
|
# looks wrong beside full-color application icons in the dock.
|
|
PANAMA_ICON_DIR="$PANAMA_PATH/config/local/share/icons/hicolor/scalable/apps"
|
|
USER_ICON_DIR="$HOME/.local/share/icons/hicolor/scalable/apps"
|
|
mkdir -p "$USER_ICON_DIR"
|
|
for icon_file in "$PANAMA_ICON_DIR"/*.svg; do
|
|
[[ -e "$icon_file" ]] || continue
|
|
icon_name="$(basename "$icon_file")"
|
|
icon_target="$USER_ICON_DIR/$icon_name"
|
|
if [[ -L "$icon_target" ]]; then
|
|
rm "$icon_target"
|
|
elif [[ -e "$icon_target" ]]; then
|
|
mv "$icon_target" "$icon_target.bak"
|
|
fi
|
|
ln -s "$icon_file" "$icon_target"
|
|
done
|
|
gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" 2>/dev/null || true
|
|
|
|
PANAMA_APPLICATION_DIR="$PANAMA_PATH/config/local/share/applications"
|
|
USER_APPLICATION_DIR="$HOME/.local/share/applications"
|
|
mkdir -p "$USER_APPLICATION_DIR"
|
|
for desktop_file in "$PANAMA_APPLICATION_DIR"/*.desktop; do
|
|
[[ -e "$desktop_file" ]] || continue
|
|
desktop_name="$(basename "$desktop_file")"
|
|
desktop_target="$USER_APPLICATION_DIR/$desktop_name"
|
|
if [[ -L "$desktop_target" ]]; then
|
|
rm "$desktop_target"
|
|
elif [[ -e "$desktop_target" ]]; then
|
|
log "Keeping existing desktop entry at $desktop_target"
|
|
continue
|
|
fi
|
|
ln -s "$desktop_file" "$desktop_target"
|
|
log "Linked $desktop_name → $desktop_target"
|
|
done
|