From 7fd0e37061ab0b533306853d34f05e0aeba0ad7a Mon Sep 17 00:00:00 2001 From: The_miro Date: Thu, 11 Jun 2026 15:46:01 +0200 Subject: [PATCH] refactor(hyprlua): move hypr-usr/ into hypr/usr/ and wire sysupdate sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device-specific Lua configs (monitors, binds, input, etc.) previously lived in a top-level hypr-usr/ sibling to hypr/. They now live inside hypr/usr/ so all hypr-related configs sit under one directory tree. - git mv hypr-usr/ → hypr/usr/ - hyprland.lua: require() calls updated to require("usr.*") - input.lua: require("input-device-exceptions") → require("usr.input-device-exceptions") - hyprpaper.conf + monitorhandler.sh + wallpaper-picker: wallpaper.conf path updated from ~/.config/wallpaper.conf → ~/.config/hypr/usr/wallpaper.conf - monitorhandler.sh: fix stale desktopenvs/hyprland/ → desktopenvs/hyprlua/ - binds.lua: edit-binds keybind path corrected to ~/.config/hypr/usr/binds.lua - helpmenu.sh: update binds.lua source path - updater.conf: SOURCE_BASE fixed (hyprland→hyprlua), config hypr except usr, remove flat hypr-usr entry - update-configs.sh: add "except " support for the config type - hyprlua.sh installer: remove now-redundant hypr-usr copy lines - migrate-hyprland-to-hyprlua.sh: deploy from hypr/usr/ instead of hypr-usr/ - sysupdate.sh: add CONFIG SYNC section with _migrate_hypr_usr() which moves old flat-layout files into usr/ (case 1) or copies fresh from dotfiles when no local config exists (case 2); fallback copy preserves hypr/usr/ Co-Authored-By: Claude Sonnet 4.6 --- .../hyprlua/config-updater/update-configs.sh | 52 +++++- .../hyprlua/config-updater/updater.conf | 11 +- desktopenvs/hyprlua/hypr/hyprland.lua | 14 +- desktopenvs/hyprlua/hypr/hyprpaper.conf | 2 +- .../{hypr-usr => hypr/usr}/autostart.lua | 0 .../hyprlua/{hypr-usr => hypr/usr}/binds.lua | 2 +- .../{hypr-usr => hypr/usr}/envvars.lua | 0 .../usr}/input-device-exceptions.lua | 0 .../hyprlua/{hypr-usr => hypr/usr}/input.lua | 2 +- .../{hypr-usr => hypr/usr}/mk-device-block.sh | 0 .../usr}/mk-device-exception.sh | 0 .../{hypr-usr => hypr/usr}/monitors.lua | 0 .../{hypr-usr => hypr/usr}/wallpaper.conf | 0 .../usr}/windowrules.conf.old | 0 .../{hypr-usr => hypr/usr}/windowrules.lua | 0 desktopenvs/hyprlua/scripts/helpmenu.sh | 2 +- desktopenvs/hyprlua/scripts/monitorhandler.sh | 4 +- desktopenvs/hyprlua/scripts/wallpaper-picker | 2 +- desktopenvs/migrate-hyprland-to-hyprlua.sh | 25 ++- setup/modules/Desktop-Environments/hyprlua.sh | 7 +- sysupdate.sh | 173 ++++++++++++++++++ 21 files changed, 253 insertions(+), 43 deletions(-) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/autostart.lua (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/binds.lua (99%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/envvars.lua (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/input-device-exceptions.lua (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/input.lua (90%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/mk-device-block.sh (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/mk-device-exception.sh (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/monitors.lua (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/wallpaper.conf (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/windowrules.conf.old (100%) rename desktopenvs/hyprlua/{hypr-usr => hypr/usr}/windowrules.lua (100%) diff --git a/desktopenvs/hyprlua/config-updater/update-configs.sh b/desktopenvs/hyprlua/config-updater/update-configs.sh index 5321428..b2b27fd 100755 --- a/desktopenvs/hyprlua/config-updater/update-configs.sh +++ b/desktopenvs/hyprlua/config-updater/update-configs.sh @@ -3,6 +3,14 @@ # # Config: ~/.config/config-updater/updater.conf # Manifest: ~/.config/config-updater/manifest +# +# Syntax in updater.conf: +# config [except ...] +# copy SOURCE_BASE/ to ~/.config/, optionally skipping subdirs +# flat +# copy contents of SOURCE_BASE/ directly into ~/.config/ +# ignore +# present in source but intentionally not managed here set -euo pipefail @@ -23,6 +31,7 @@ die() { err "$*"; exit 1; } # ── parse updater.conf ──────────────────────────────────────────────────────── SOURCE_BASE="" declare -A ENTRY_TYPE # name → config | flat | ignore +declare -A ENTRY_EXCL # name → space-separated list of excluded subdirs while IFS= read -r line; do line="${line%%#*}" @@ -36,10 +45,19 @@ while IFS= read -r line; do continue fi - read -r type name _rest <<< "$line" + read -r type name rest <<< "$line" [[ -z "${name:-}" ]] && continue + case "$type" in - config|flat|ignore) ENTRY_TYPE["$name"]="$type" ;; + config|flat|ignore) + ENTRY_TYPE["$name"]="$type" + # Parse optional "except sub1 sub2 ..." + if [[ "${rest:-}" =~ ^except[[:space:]]+(.+)$ ]]; then + ENTRY_EXCL["$name"]="${BASH_REMATCH[1]}" + else + ENTRY_EXCL["$name"]="" + fi + ;; *) warn "Unknown type '$type' for '$name' — skipping" ;; esac done < "$CONF_FILE" @@ -91,11 +109,35 @@ for name in "${!ENTRY_TYPE[@]}"; do continue fi + excl="${ENTRY_EXCL[$name]:-}" + case "$type" in config) - rm -rf "${TARGET:?}/${name}" - cp -r "$src" "$TARGET/$name" - ok "config $name" + if [[ -z "$excl" ]]; then + rm -rf "${TARGET:?}/${name}" + cp -r "$src" "$TARGET/$name" + ok "config $name" + else + # Copy all top-level items of $src except excluded subdirs + mkdir -p "${TARGET}/${name}" + item_errors=0 + while IFS= read -r -d '' item; do + item_name="$(basename "$item")" + skip_item=false + for e in $excl; do + [[ "$item_name" == "$e" ]] && skip_item=true && break + done + [[ "$skip_item" == true ]] && continue + rm -rf "${TARGET:?}/${name}/${item_name}" + cp -r "$item" "${TARGET}/${name}/" || (( item_errors++ )) || true + done < <(find "$src" -maxdepth 1 -mindepth 1 -print0 | sort -z) + if (( item_errors > 0 )); then + err "config $name (${item_errors} error(s))" + (( errors++ )) || true + else + ok "config $name (excl: $excl)" + fi + fi ;; flat) [[ -d "$src" ]] || { diff --git a/desktopenvs/hyprlua/config-updater/updater.conf b/desktopenvs/hyprlua/config-updater/updater.conf index 203880b..db58e9e 100644 --- a/desktopenvs/hyprlua/config-updater/updater.conf +++ b/desktopenvs/hyprlua/config-updater/updater.conf @@ -7,14 +7,14 @@ # (for installation-specific files that live at the ~/.config root) # ignore present in source but intentionally not managed here -SOURCE_BASE = ~/Dotfiles/desktopenvs/hyprland +SOURCE_BASE = ~/Dotfiles/desktopenvs/hyprlua # ── deployed as ~/.config/ ───────────────────────────────────────────── config alacritty config btop config dunst config gtk-3.0 -config hypr +config hypr except usr config kitty config mimeapps.list config nwg-dock-hyprland @@ -27,9 +27,6 @@ config walker config wofi config xfce4 -# ── flat: directory contents copied directly into ~/.config/ ────────────────── -flat hypr-usr # installation-specific: binds, monitors, autostart, etc. - # ── intentionally not managed here ─────────────────────────────────────────── ignore config-updater # the updater itself ignore CRT # referenced from dotfiles path directly in binds.conf @@ -40,3 +37,7 @@ ignore greetd-tuigreet # deployed to /etc/greetd/ at install time ignore spicetify # managed separately (spicetify handles its own config) ignore Vencord # managed separately ignore waybar # present but inactive; eww bar is used instead +# hypr/usr/ contains device-specific lua files (monitors, binds, input, etc.). +# They are excluded from automated syncs to preserve per-device customisations. +# Deploy manually on a new device: +# cp -r ~/Dotfiles/desktopenvs/hyprlua/hypr/usr/ ~/.config/hypr/ diff --git a/desktopenvs/hyprlua/hypr/hyprland.lua b/desktopenvs/hyprlua/hypr/hyprland.lua index d1a05ce..40a1a1d 100644 --- a/desktopenvs/hyprlua/hypr/hyprland.lua +++ b/desktopenvs/hyprlua/hypr/hyprland.lua @@ -1,12 +1,12 @@ -- Hyprland Lua config — https://wiki.hypr.land/Configuring/Start/ --- User-side files are required from ~/.config/hypr/ alongside this file. +-- Device-specific files live in ~/.config/hypr/usr/ (deployed from hypr/usr/). -require("monitors") -require("envvars") -require("input") -require("binds") -require("windowrules") -require("autostart") +require("usr.monitors") +require("usr.envvars") +require("usr.input") +require("usr.binds") +require("usr.windowrules") +require("usr.autostart") -------------------- ---- MY PROGRAMS --- diff --git a/desktopenvs/hyprlua/hypr/hyprpaper.conf b/desktopenvs/hyprlua/hypr/hyprpaper.conf index 22a683b..74fbbc1 100644 --- a/desktopenvs/hyprlua/hypr/hyprpaper.conf +++ b/desktopenvs/hyprlua/hypr/hyprpaper.conf @@ -8,4 +8,4 @@ wallpaper { } # per-monitor state, written by ~/.config/scripts/wallpaper-picker -source = ~/.config/wallpaper.conf +source = ~/.config/hypr/usr/wallpaper.conf diff --git a/desktopenvs/hyprlua/hypr-usr/autostart.lua b/desktopenvs/hyprlua/hypr/usr/autostart.lua similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/autostart.lua rename to desktopenvs/hyprlua/hypr/usr/autostart.lua diff --git a/desktopenvs/hyprlua/hypr-usr/binds.lua b/desktopenvs/hyprlua/hypr/usr/binds.lua similarity index 99% rename from desktopenvs/hyprlua/hypr-usr/binds.lua rename to desktopenvs/hyprlua/hypr/usr/binds.lua index 1b52193..359d046 100644 --- a/desktopenvs/hyprlua/hypr-usr/binds.lua +++ b/desktopenvs/hyprlua/hypr/usr/binds.lua @@ -61,7 +61,7 @@ hl.bind(mainMod .. " + W", hl.dsp.exec_cmd("[tag +centered-L] kitt hl.bind(mainMod .. " + CTRL + R", hl.dsp.exec_cmd("[tag +centered-L] kitty -e ~/.config/scripts/amssh")) hl.bind(mainMod .. " + F1", hl.dsp.exec_cmd("[tag +centered] kitty ~/.config/scripts/helpmenu.sh")) hl.bind(mainMod .. " + CTRL + T", hl.dsp.exec_cmd("[tag +centered-S] kitty bash ~/.config/scripts/timer-pick")) -hl.bind(mainMod .. " + SHIFT + F1", hl.dsp.exec_cmd("[tag +centered-L] kitty nvim ~/.config/binds.lua")) +hl.bind(mainMod .. " + SHIFT + F1", hl.dsp.exec_cmd("[tag +centered-L] kitty nvim ~/.config/hypr/usr/binds.lua")) hl.bind(mainMod .. " + CTRL + P", hl.dsp.exec_cmd("~/.config/scripts/screenrec.sh")) diff --git a/desktopenvs/hyprlua/hypr-usr/envvars.lua b/desktopenvs/hyprlua/hypr/usr/envvars.lua similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/envvars.lua rename to desktopenvs/hyprlua/hypr/usr/envvars.lua diff --git a/desktopenvs/hyprlua/hypr-usr/input-device-exceptions.lua b/desktopenvs/hyprlua/hypr/usr/input-device-exceptions.lua similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/input-device-exceptions.lua rename to desktopenvs/hyprlua/hypr/usr/input-device-exceptions.lua diff --git a/desktopenvs/hyprlua/hypr-usr/input.lua b/desktopenvs/hyprlua/hypr/usr/input.lua similarity index 90% rename from desktopenvs/hyprlua/hypr-usr/input.lua rename to desktopenvs/hyprlua/hypr/usr/input.lua index 618c643..95928a5 100644 --- a/desktopenvs/hyprlua/hypr-usr/input.lua +++ b/desktopenvs/hyprlua/hypr/usr/input.lua @@ -15,4 +15,4 @@ hl.config({ }, }) -require("input-device-exceptions") +require("usr.input-device-exceptions") diff --git a/desktopenvs/hyprlua/hypr-usr/mk-device-block.sh b/desktopenvs/hyprlua/hypr/usr/mk-device-block.sh similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/mk-device-block.sh rename to desktopenvs/hyprlua/hypr/usr/mk-device-block.sh diff --git a/desktopenvs/hyprlua/hypr-usr/mk-device-exception.sh b/desktopenvs/hyprlua/hypr/usr/mk-device-exception.sh similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/mk-device-exception.sh rename to desktopenvs/hyprlua/hypr/usr/mk-device-exception.sh diff --git a/desktopenvs/hyprlua/hypr-usr/monitors.lua b/desktopenvs/hyprlua/hypr/usr/monitors.lua similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/monitors.lua rename to desktopenvs/hyprlua/hypr/usr/monitors.lua diff --git a/desktopenvs/hyprlua/hypr-usr/wallpaper.conf b/desktopenvs/hyprlua/hypr/usr/wallpaper.conf similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/wallpaper.conf rename to desktopenvs/hyprlua/hypr/usr/wallpaper.conf diff --git a/desktopenvs/hyprlua/hypr-usr/windowrules.conf.old b/desktopenvs/hyprlua/hypr/usr/windowrules.conf.old similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/windowrules.conf.old rename to desktopenvs/hyprlua/hypr/usr/windowrules.conf.old diff --git a/desktopenvs/hyprlua/hypr-usr/windowrules.lua b/desktopenvs/hyprlua/hypr/usr/windowrules.lua similarity index 100% rename from desktopenvs/hyprlua/hypr-usr/windowrules.lua rename to desktopenvs/hyprlua/hypr/usr/windowrules.lua diff --git a/desktopenvs/hyprlua/scripts/helpmenu.sh b/desktopenvs/hyprlua/scripts/helpmenu.sh index 5db8c81..02d4c6f 100755 --- a/desktopenvs/hyprlua/scripts/helpmenu.sh +++ b/desktopenvs/hyprlua/scripts/helpmenu.sh @@ -1,3 +1,3 @@ #!/bin/bash -cat ~/Dotfiles/desktopenvs/hyprlua/hypr-usr/binds.lua | less +cat ~/Dotfiles/desktopenvs/hyprlua/hypr/usr/binds.lua | less diff --git a/desktopenvs/hyprlua/scripts/monitorhandler.sh b/desktopenvs/hyprlua/scripts/monitorhandler.sh index 1ddc98d..c0deca0 100755 --- a/desktopenvs/hyprlua/scripts/monitorhandler.sh +++ b/desktopenvs/hyprlua/scripts/monitorhandler.sh @@ -1,4 +1,4 @@ #!/bin/bash -hyprpaper -c ~/.config/wallpaper.conf -~/Dotfiles/desktopenvs/hyprland/scripts/ewwstart.sh +hyprpaper -c ~/.config/hypr/usr/wallpaper.conf +~/Dotfiles/desktopenvs/hyprlua/scripts/ewwstart.sh diff --git a/desktopenvs/hyprlua/scripts/wallpaper-picker b/desktopenvs/hyprlua/scripts/wallpaper-picker index 66cab3c..1ded82a 100755 --- a/desktopenvs/hyprlua/scripts/wallpaper-picker +++ b/desktopenvs/hyprlua/scripts/wallpaper-picker @@ -6,7 +6,7 @@ set -u VERBOSE=0 DIR="" -STATE_FILE="${HOME}/.config/wallpaper.conf" +STATE_FILE="${HOME}/.config/hypr/usr/wallpaper.conf" HYPRLOCK_BG_FILE="${HOME}/.config/hypr/hyprlock-backgrounds.conf" FIT_MODE="cover" diff --git a/desktopenvs/migrate-hyprland-to-hyprlua.sh b/desktopenvs/migrate-hyprland-to-hyprlua.sh index b188a65..c651558 100755 --- a/desktopenvs/migrate-hyprland-to-hyprlua.sh +++ b/desktopenvs/migrate-hyprland-to-hyprlua.sh @@ -99,8 +99,8 @@ done # ── swap hypr-usr (the part that actually differs) ──────────────────────────── # hyprland: *.conf files live at ~/.config/ root (sourced by hyprland.conf) -# hyprlua: *.lua files live at ~/.config/hypr/ (required by hyprland.lua) -# wallpaper.conf stays at ~/.config/ root (hyprpaper still reads it) +# hyprlua: device-specific files live at ~/.config/hypr/usr/ +# (required via require("usr.*") in hyprland.lua) printf '\n' @@ -108,20 +108,17 @@ printf '\n' for f in "${HYPR_USR_CONFS[@]}"; do [[ -f "$TARGET/$f" ]] && run "rm '$TARGET/$f'" && note "removed ~/.config/$f" done +# Remove wallpaper.conf from ~/.config/ root if present (old location) +[[ -f "$TARGET/wallpaper.conf" ]] && run "rm '$TARGET/wallpaper.conf'" && note "removed ~/.config/wallpaper.conf" -# Deploy new .lua files into ~/.config/hypr/ -if [[ -d "$SRC/hypr-usr" ]]; then - run "mkdir -p '$TARGET/hypr'" - for lua in "$SRC/hypr-usr"/*.lua; do - [[ -e "$lua" ]] || continue - run "cp '$lua' '$TARGET/hypr/'" - ok "hypr-usr $(basename "$lua") → ~/.config/hypr/" +# Deploy device-specific files into ~/.config/hypr/usr/ +if [[ -d "$SRC/hypr/usr" ]]; then + run "mkdir -p '$TARGET/hypr/usr'" + for f in "$SRC/hypr/usr"/*; do + [[ -e "$f" ]] || continue + run "cp '$f' '$TARGET/hypr/usr/'" + ok "hypr/usr $(basename "$f") → ~/.config/hypr/usr/" done - # wallpaper.conf stays at ~/.config/ root - if [[ -f "$SRC/hypr-usr/wallpaper.conf" ]]; then - run "cp '$SRC/hypr-usr/wallpaper.conf' '$TARGET/'" - ok "hypr-usr wallpaper.conf → ~/.config/" - fi fi # ── update config-updater ───────────────────────────────────────────────────── diff --git a/setup/modules/Desktop-Environments/hyprlua.sh b/setup/modules/Desktop-Environments/hyprlua.sh index 8deb82b..5d44571 100755 --- a/setup/modules/Desktop-Environments/hyprlua.sh +++ b/setup/modules/Desktop-Environments/hyprlua.sh @@ -103,11 +103,8 @@ for cfg in "${CONFIGS[@]}"; do rm -rf ~/.config/"$cfg" cp -r ~/Dotfiles/desktopenvs/hyprlua/"$cfg" ~/.config/ done - -# User-side Lua files live inside ~/.config/hypr/ so require() finds them -cp ~/Dotfiles/desktopenvs/hyprlua/hypr-usr/*.lua ~/.config/hypr/ -# wallpaper.conf stays at ~/.config/ for hyprpaper -cp ~/Dotfiles/desktopenvs/hyprlua/hypr-usr/wallpaper.conf ~/.config/ +# hypr/usr/ (device-specific) is already inside hypr/ and copied above. +# Customise ~/.config/hypr/usr/ per device after install. cp ~/Dotfiles/colors.conf ~/.config/colors.conf diff --git a/sysupdate.sh b/sysupdate.sh index 945151b..615a18b 100755 --- a/sysupdate.sh +++ b/sysupdate.sh @@ -14,6 +14,7 @@ set -uo pipefail readonly STATE_FILE="/updatestate" readonly SCRIPT_PREFIX="/updatescript" readonly NEWS_FEED="https://archlinux.org/feeds/news/" +DOTFILES="${DOTFILES:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}" AI_MODE=false for _arg in "$@"; do [[ "$_arg" == "--AI" ]] && AI_MODE=true; done @@ -485,6 +486,169 @@ PROMPT_EOF fi } +# ═══════════════════════════════════════════════════════════════════════════════ +# CONFIG SYNC +# ═══════════════════════════════════════════════════════════════════════════════ + +# Items always skipped in the direct-copy fallback (managed by separate +# installers, or intentionally not auto-synced). hypr/usr/ (device-specific) +# is handled separately inside the copy loop rather than via this list. +declare -a _CFG_SKIP=( + config-updater # meta: the updater script itself + CRT eww eww-nobattery eww-touch greetd-tuigreet spicetify Vencord waybar +) + +# Resolve the dotfiles DE source directory for the current machine. +# Priority: installed updater.conf SOURCE_BASE → running session detection. +_de_source_dir() { + local conf="${XDG_CONFIG_HOME:-$HOME/.config}/config-updater/updater.conf" + if [[ -f "$conf" ]]; then + local src + src=$(awk -F'[[:space:]]*=[[:space:]]*' '/^SOURCE_BASE/{print $2; exit}' "$conf") + src="${src/#\~/$HOME}" + [[ -d "${src:-}" ]] && printf '%s' "$src" && return + fi + if pgrep -x Hyprland &>/dev/null || [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then + printf '%s' "$DOTFILES/desktopenvs/hyprlua" + elif pgrep -x niri &>/dev/null || [[ -n "${NIRI_SOCKET:-}" ]]; then + printf '%s' "$DOTFILES/desktopenvs/niri" + fi +} + +# Detect and offer to migrate the old hyprlua flat layout: +# old: ~/.config/hypr/monitors.lua etc. (pre-usr/ era) +# new: ~/.config/hypr/usr/monitors.lua +_migrate_hypr_usr() { + local target="${XDG_CONFIG_HOME:-$HOME/.config}" + local hypr_dir="$target/hypr" + local usr_dir="$hypr_dir/usr" + + # Already in the right place — nothing to do + [[ -d "$usr_dir" ]] && return 0 + + # ── Case 1: old flat layout — lua files at ~/.config/hypr/ root ────────── + if [[ -d "$hypr_dir" ]]; then + local -a old_files=() + for f in monitors.lua envvars.lua input.lua binds.lua windowrules.lua \ + autostart.lua input-device-exceptions.lua; do + [[ -f "$hypr_dir/$f" ]] && old_files+=("$f") + done + + if [[ ${#old_files[@]} -gt 0 ]]; then + echo + warn "Old hyprlua layout: device-specific files at ${BO}~/.config/hypr/${RS} root." + warn "New location: ${BO}~/.config/hypr/usr/${RS}" + echo + if ! ask "Migrate now?"; then + warn "Skipped — hyprland.lua will fail to start until migrated." + return 1 + fi + mkdir -p "$usr_dir" + for f in "${old_files[@]}"; do + mv "$hypr_dir/$f" "$usr_dir/" + ok "moved hypr/$f → hypr/usr/$f" + done + if [[ -f "$target/wallpaper.conf" && ! -f "$usr_dir/wallpaper.conf" ]]; then + mv "$target/wallpaper.conf" "$usr_dir/wallpaper.conf" + ok "moved wallpaper.conf → hypr/usr/wallpaper.conf" + fi + echo + ok "Migration complete — device configs now at ${BO}~/.config/hypr/usr/${RS}" + return 0 + fi + fi + + # ── Case 2: no usr/ and no old files — copy template from dotfiles ─────── + local de_dir; de_dir=$(_de_source_dir) + local src_usr="${de_dir:+$de_dir/hypr/usr}" + if [[ -n "${src_usr:-}" && -d "$src_usr" ]]; then + mkdir -p "$usr_dir" + cp -r "$src_usr/." "$usr_dir/" + ok "Copied ${BO}hypr/usr/${RS} from dotfiles ${DI}(no local config found)${RS}" + fi +} + +sync_configs() { + section "Config Sync" + + # ── Migration: old flat layout → hypr/usr/ ─────────────────────────────── + _migrate_hypr_usr + + # ── Preferred: use the installed update-configs.sh ─────────────────────── + local cfg_script + for cfg_script in "$HOME/update-configs.sh" \ + "${XDG_CONFIG_HOME:-$HOME/.config}/config-updater/update-configs.sh"; do + [[ -x "$cfg_script" ]] && break || cfg_script="" + done + + if [[ -n "${cfg_script:-}" ]]; then + log "Using installed config-updater (${DI}${cfg_script}${RS})" + echo + if "$cfg_script"; then + echo + ok "Config sync complete" + else + echo + warn "Config sync completed with errors" + fi + return + fi + + # ── Fallback: direct copy from dotfiles ────────────────────────────────── + local de_dir; de_dir=$(_de_source_dir) + if [[ -z "${de_dir:-}" || ! -d "$de_dir" ]]; then + warn "Cannot determine DE source directory — config sync skipped" + warn "Hint: deploy config-updater or ensure a supported DE session is running" + return + fi + + local target="${XDG_CONFIG_HOME:-$HOME/.config}" + log "Source → ${BO}${de_dir}${RS}" + log "Target → ${BO}${target}${RS}" + warn "${BO}hypr/usr/${RS} preserved (device-specific — customise manually)" + echo + + local synced=0 errs=0 + while IFS= read -r -d '' item; do + local name; name="$(basename "$item")" + local skip=false + for s in "${_CFG_SKIP[@]}"; do [[ "$name" == "$s" ]] && skip=true && break; done + [[ "$skip" == true ]] && continue + + if [[ "$name" == "hypr" ]]; then + # Copy hypr/ contents but preserve ~/.config/hypr/usr/ + mkdir -p "$target/hypr" + local hypr_ok=true + while IFS= read -r -d '' hitem; do + local hname; hname="$(basename "$hitem")" + [[ "$hname" == "usr" ]] && continue + rm -rf "${target}/hypr/${hname}" && cp -r "$hitem" "$target/hypr/" \ + || hypr_ok=false + done < <(find "$item" -maxdepth 1 -mindepth 1 -print0 | sort -z) + if $hypr_ok; then + ok "synced hypr ${DI}(usr/ preserved)${RS}" + (( synced++ )) || true + else + err "failed hypr" + (( errs++ )) || true + fi + elif rm -rf "${target:?}/${name}" && cp -r "$item" "$target/"; then + ok "synced ${name}" + (( synced++ )) || true + else + err "failed ${name}" + (( errs++ )) || true + fi + done < <(find "$de_dir" -maxdepth 1 -mindepth 1 -not -name '.*' -print0 | sort -z) + + echo + if (( errs > 0 )); then + warn "Config sync: ${synced} synced, ${errs} error(s)" + else + ok "Config sync: ${BO}${synced}${RS} config(s) synced" + fi +} + # ═══════════════════════════════════════════════════════════════════════════════ # MAIN # ═══════════════════════════════════════════════════════════════════════════════ @@ -526,6 +690,10 @@ main() { echo ok "${BO}System is up to date.${RS}" write_state + echo + if ask "Sync dotfiles configs to ~/.config?"; then + sync_configs + fi rm -f "$_NEWS_PY" exit 0 fi @@ -678,6 +846,11 @@ main() { fi echo + # ── Config sync ────────────────────────────────────────────────────────── + if ask "Sync dotfiles configs to ~/.config?"; then + sync_configs + fi + rm -f "$_NEWS_PY" }