From 46e342ceb3a2757554685853597e12a9e70427e0 Mon Sep 17 00:00:00 2001 From: Donald Williams <129223418+dwilliam62@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:47:42 -0500 Subject: Copy menu - 1st step in menu driven dot files install / upgrade process (#917) * Phase 1 of creating TUI for copy.sh for installs and upgrades On branch copy-menu Changes to be committed: modified: copy.sh new file: scripts/copy_menu.sh * Fixing formatting in copy-menu On branch copy-menu Your branch is up to date with 'origin/copy-menu'. Changes to be committed: modified: scripts/copy_menu.sh * More formatting and color first letter as selectable option On branch copy-menu Your branch is up to date with 'origin/copy-menu'. Changes to be committed: modified: copy.sh modified: scripts/copy_menu.sh * Fixing syntax error * Some whiptail versions don't support color Added check before displaying colors On branch copy-menu Your branch is up to date with 'origin/copy-menu'. Changes to be committed: modified: scripts/copy_menu.sh * fixing formatting On branch copy-menu Your branch is up to date with 'origin/copy-menu'. Changes to be committed: modified: scripts/copy_menu.sh * More formatting for whiptail * Formatting whiptail is so much fun * Changed descrption to two lines * Whiltail 4, human 0 * Whiltail 5, human 0 - shortened text * Whiltail 6, human 1 - remove dup items * Whiltail 6, human 2 - removed color highlight --- scripts/copy_menu.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100755 scripts/copy_menu.sh (limited to 'scripts') diff --git a/scripts/copy_menu.sh b/scripts/copy_menu.sh new file mode 100755 index 00000000..18482b18 --- /dev/null +++ b/scripts/copy_menu.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# show_copy_menu +# Arguments: +# $1 - express_supported flag (1 if available, 0 otherwise) +# Sets global COPY_MENU_CHOICE to one of: install, upgrade, express, quit +show_copy_menu() { + local express_supported="${1:-0}" + local menu_title=" KooL's Hyprland Dotfiles " + local prompt="Select what you would like to do:" + + local install_tag="Install" + local upgrade_tag="Upgrade" + local express_tag="Express" + local quit_tag="Quit" + + local install_desc="Fresh copy" + local upgrade_desc="Backups + prompts" + local express_desc="Skips restores & wallpapers" + local quit_desc="Exit without changes" + if [ "$express_supported" -ne 1 ]; then + express_body="xpress - Requires dots >= ${MIN_EXPRESS_VERSION}" + fi + + local choice="" + + if command -v whiptail >/dev/null 2>&1; then + if ! choice=$(whiptail --title "$menu_title" --menu "$prompt" 17 60 8 \ + "$install_tag" "$install_desc" \ + "$upgrade_tag" "$upgrade_desc" \ + "$express_tag" "$express_desc" \ + "$quit_tag" "$quit_desc" 3>&1 1>&2 2>&3); then + COPY_MENU_CHOICE="quit" + return 1 + fi + else + while true; do + printf "\n%s\n" "$menu_title" + printf "%s\n" "$prompt" + printf " 1) Install - %s\n" "$install_desc" + printf " 2) Upgrade - %s\n" "$upgrade_desc" + printf " 3) Express - %s\n" "$express_desc" + printf " 4) Quit - %s\n" "$quit_desc" + printf "Enter choice [1-4]: " + read -r text_choice + case "$text_choice" in + 1) choice="$install_tag"; break ;; + 2) choice="$upgrade_tag"; break ;; + 3) choice="$express_tag"; break ;; + 4) choice="$quit_tag"; break ;; + *) echo "Invalid selection. Please choose 1-4." ;; + esac + done + fi + + # shellcheck disable=SC2034 # used by parent script after sourcing this file + COPY_MENU_CHOICE="$choice" +} -- cgit v1.2.3 From 2f09b78e20c68c60e171f71979bae3551c51eb08 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:17:07 -0500 Subject: Phase 2a of copy.sh modularization lib_backup functions This module takes care of backing up objects with date-time Removes the duplicate code in copy.sh On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh new file: scripts/lib_backup.sh --- copy.sh | 113 ++++++++++++++++---------------------------------- scripts/lib_backup.sh | 72 ++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 77 deletions(-) create mode 100644 scripts/lib_backup.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 0e88b65e..eba99fbd 100755 --- a/copy.sh +++ b/copy.sh @@ -1,5 +1,31 @@ #!/usr/bin/env bash # /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ # +# Purpose: +# Orchestrates copying/upgrading JaKooLit's Hyprland dotfiles into ~/.config. +# Handles interactive prompts, backups/restores, per-app tweaks, and express mode. +# +# Layout (high-level; future modularization targets): +# - Constants/colors, helper sourcing (copy_menu.sh). +# - Version helpers and CLI parsing (install/upgrade/express). +# - Safety checks (non-root), banners/notices. +# - Environment/distro checks and warnings. +# - GPU/VM/NixOS detection tweaks. +# - Input prompts (keyboard, resolution, clock format, animations). +# - Workflow selection effects (express vs standard). +# - Backup/restore helpers (inline today; planned to move to scripts/lib_backup.sh). +# - Copy phases: +# * Part 1: fastfetch/kitty/rofi/swaync (prompted replace). +# * Waybar special handling (symlinks, configs/styles restore). +# * Part 2: other configs (btop, cava, hypr, etc.). +# * App-specific installs (ghostty, wezterm, ags, quickshell). +# - UserConfigs/UserScripts and hypr file restores. +# - Wallpaper handling (default + optional 1GB pack). +# - Backup cleanup (auto in express). +# - Final symlinks (waybar) and wallust init. +# +# Next modular step: +# Extract backup/restore/cleanup functions into scripts/lib_backup.sh +# and source them similar to scripts/copy_menu.sh. clear wallpaper=$HOME/.config/hypr/wallpaper_effects/.wallpaper_current @@ -25,10 +51,18 @@ RESET="$(tput sgr0)" MIN_EXPRESS_VERSION="2.3.18" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MENU_HELPER="$SCRIPT_DIR/scripts/copy_menu.sh" +BACKUP_HELPER="$SCRIPT_DIR/scripts/lib_backup.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" fi +if [ -f "$BACKUP_HELPER" ]; then + # shellcheck source=./scripts/lib_backup.sh + . "$BACKUP_HELPER" +else + echo "${ERROR} Backup helper not found at $BACKUP_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -647,13 +681,6 @@ fi set -e -# Function to create a unique backup directory name with month, day, hours, and minutes -get_backup_dirname() { - local timestamp - timestamp=$(date +"%m%d_%H%M") - echo "back-up_${timestamp}" -} - # Check if the ~/.config/ directory exists if [ ! -d "$HOME/.config" ]; then echo "${ERROR} - $HOME/.config directory does not exist. Creating it now." @@ -1395,79 +1422,11 @@ else done fi -# CLeaning up of ~/.config/ backups -cleanup_backups() { - local mode="${1:-prompt}" - CONFIG_DIR="$HOME/.config" - BACKUP_PREFIX="-backup" - - # Loop through directories in $HOME/.config - for DIR in "$CONFIG_DIR"/*; do - if [ -d "$DIR" ]; then - BACKUP_DIRS=() - - # Check for backup directories - for BACKUP in "$DIR"$BACKUP_PREFIX*; do - if [ -d "$BACKUP" ]; then - BACKUP_DIRS+=("$BACKUP") - fi - done - - # If more than one backup found - if [ ${#BACKUP_DIRS[@]} -gt 1 ]; then - if [ "$mode" = "auto" ]; then - latest_backup="${BACKUP_DIRS[0]}" - for BACKUP in "${BACKUP_DIRS[@]}"; do - if [ "$BACKUP" -nt "$latest_backup" ]; then - latest_backup="$BACKUP" - fi - done - for BACKUP in "${BACKUP_DIRS[@]}"; do - if [ "$BACKUP" != "$latest_backup" ]; then - rm -rf "$BACKUP" - fi - done - echo "${INFO} Express mode: trimmed backups for ${YELLOW}${DIR##*/}${RESET}, keeping ${MAGENTA}${latest_backup##*/}${RESET}." 2>&1 | tee -a "$LOG" - continue - fi - printf "\n%.0s" {1..2} - echo -e "${INFO} Found ${MAGENTA}multiple backups${RESET} for: ${YELLOW}${DIR##*/}${RESET}" - echo "${YELLOW}Backups: ${RESET}" - - # List the backups - for BACKUP in "${BACKUP_DIRS[@]}"; do - echo " - ${BACKUP##*/}" - done - - echo -n "${CAT} Do you want to delete the older backups of ${YELLOW}${DIR##*/}${RESET} and keep the latest backup only? (y/N): " - read back_choice - - if [[ "$back_choice" == [Yy]* ]]; then - # Sort backups by modification time - latest_backup="${BACKUP_DIRS[0]}" - for BACKUP in "${BACKUP_DIRS[@]}"; do - if [ "$BACKUP" -nt "$latest_backup" ]; then - latest_backup="$BACKUP" - fi - done - - for BACKUP in "${BACKUP_DIRS[@]}"; do - if [ "$BACKUP" != "$latest_backup" ]; then - echo "Deleting: ${BACKUP##*/}" - rm -rf "$BACKUP" - fi - done - echo "Old backups of ${YELLOW}${DIR##*/}${RESET} deleted, keeping: ${MAGENTA}${latest_backup##*/}${RESET}" - fi - fi - fi - done -} # Execute the cleanup function if [ "$EXPRESS_MODE" -eq 1 ]; then - cleanup_backups auto + cleanup_backups auto "$LOG" else - cleanup_backups prompt + cleanup_backups prompt "$LOG" fi # Check if ~/.config/waybar/style.css does not exist or is a symlink diff --git a/scripts/lib_backup.sh b/scripts/lib_backup.sh new file mode 100644 index 00000000..6867fb6d --- /dev/null +++ b/scripts/lib_backup.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# Backup helper utilities shared by copy.sh (and future scripts). + +# Create a unique backup directory name with month, day, hours, and minutes. +get_backup_dirname() { + echo "back-up_$(date +"%m%d_%H%M")" +} + +# Move a directory to a timestamped backup alongside the original. +# Usage: backup_dir "/path/to/dir" [logfile] +backup_dir() { + local dir="$1" + local log="${2:-/dev/null}" + local backup_suffix + + [ -z "$dir" ] && return 1 + backup_suffix=$(get_backup_dirname) + mv "$dir" "${dir}-backup-${backup_suffix}" 2>&1 | tee -a "$log" +} + +# Cleanup old backups under ~/.config, keeping the newest for each base dir. +# mode: "auto" (no prompts) or "prompt" (asks before delete); log optional. +cleanup_backups() { + local mode="${1:-prompt}" + local log="${2:-/dev/null}" + local CONFIG_DIR="$HOME/.config" + local BACKUP_PREFIX="-backup" + + for DIR in "$CONFIG_DIR"/*; do + [ -d "$DIR" ] || continue + local BACKUP_DIRS=() + + for BACKUP in "$DIR"$BACKUP_PREFIX*; do + [ -d "$BACKUP" ] && BACKUP_DIRS+=("$BACKUP") + done + + [ ${#BACKUP_DIRS[@]} -gt 1 ] || continue + + # Determine latest backup by mtime + local latest_backup="${BACKUP_DIRS[0]}" + for BACKUP in "${BACKUP_DIRS[@]}"; do + [ "$BACKUP" -nt "$latest_backup" ] && latest_backup="$BACKUP" + done + + if [ "$mode" = "auto" ]; then + for BACKUP in "${BACKUP_DIRS[@]}"; do + if [ "$BACKUP" != "$latest_backup" ]; then + rm -rf "$BACKUP" + fi + done + echo "${INFO:-[INFO]} Express mode: trimmed backups for ${YELLOW:-}${DIR##*/}${RESET:-}, keeping ${MAGENTA:-}${latest_backup##*/}${RESET:-}." 2>&1 | tee -a "$log" + continue + fi + + printf "\n%s Found multiple backups for: %s\n" "${INFO:-[INFO]}" "${DIR##*/}" + echo "${YELLOW:-}Backups:${RESET:-}" + for BACKUP in "${BACKUP_DIRS[@]}"; do + echo " - ${BACKUP##*/}" + done + echo -n "${CAT:-[ACTION]} Delete older backups and keep only the latest? (y/N): " + read back_choice + if [[ "$back_choice" == [Yy]* ]]; then + for BACKUP in "${BACKUP_DIRS[@]}"; do + if [ "$BACKUP" != "$latest_backup" ]; then + rm -rf "$BACKUP" + echo "Deleted: ${BACKUP##*/}" + fi + done + echo "Kept: ${latest_backup##*/}" + fi + done +} -- cgit v1.2.3 From b7115794b4419affe58d751b80fed99d49246e6d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:25:37 -0500 Subject: Phase 3 Moved nvidia, vm, nixos code to lib_detect.sh This code make configuration adjustsments On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh new file: scripts/lib_detect.sh --- copy.sh | 51 +++++++++++++-------------------------------------- scripts/lib_detect.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 38 deletions(-) create mode 100644 scripts/lib_detect.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index eba99fbd..386cbe17 100755 --- a/copy.sh +++ b/copy.sh @@ -52,6 +52,7 @@ MIN_EXPRESS_VERSION="2.3.18" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MENU_HELPER="$SCRIPT_DIR/scripts/copy_menu.sh" BACKUP_HELPER="$SCRIPT_DIR/scripts/lib_backup.sh" +DETECT_HELPER="$SCRIPT_DIR/scripts/lib_detect.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" @@ -63,6 +64,13 @@ else echo "${ERROR} Backup helper not found at $BACKUP_HELPER. Exiting." exit 1 fi +if [ -f "$DETECT_HELPER" ]; then + # shellcheck source=./scripts/lib_detect.sh + . "$DETECT_HELPER" +else + echo "${ERROR} Detect helper not found at $DETECT_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -246,42 +254,9 @@ if [ "$EXPRESS_MODE" -eq 1 ]; then echo "${INFO} Express mode enabled. Optional restore prompts will be skipped." 2>&1 | tee -a "$LOG" fi -# setting up for NVIDIA -if lspci -k | grep -A 2 -E "(VGA|3D)" | grep -iq nvidia; then - echo "${INFO} Nvidia GPU detected. Setting up proper env's and configs" 2>&1 | tee -a "$LOG" || true - sed -i '/env = LIBVA_DRIVER_NAME,nvidia/s/^#//' config/hypr/configs/ENVariables.conf - sed -i '/env = __GLX_VENDOR_LIBRARY_NAME,nvidia/s/^#//' config/hypr/configs/ENVariables.conf - sed -i '/env = NVD_BACKEND,direct/s/^#//' config/hypr/configs/ENVariables.conf - sed -i '/env = GSK_RENDERER,ngl/s/^#//' config/hypr/configs/ENVariables.conf - - # no hardware cursors if nvidia detected - sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/configs/SystemSettings.conf -fi - -# uncommenting WLR_RENDERER_ALLOW_SOFTWARE,1 if running in a VM is detected -if hostnamectl | grep -q 'Chassis: vm'; then - echo "${INFO} System is running in a virtual machine. Setting up proper env's and configs" 2>&1 | tee -a "$LOG" || true - sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/configs/SystemSettings.conf - # enabling proper ENV's for Virtual Environment which should help - sed -i '/env = WLR_RENDERER_ALLOW_SOFTWARE,1/s/^#//' config/hypr/configs/ENVariables.conf - sed -i '/monitor = Virtual-1, 1920x1080@60,auto,1/s/^#//' config/hypr/monitors.conf -fi - -# Proper Polkit for NixOS -if hostnamectl | grep -q 'Operating System: NixOS'; then - echo "${INFO} NixOS Distro Detected. Setting up proper env's and configs." 2>&1 | tee -a "$LOG" || true - # Ensure NixOS polkit is enabled via overlay and default polkit is disabled via disable list - OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" - DISABLE_SA="config/hypr/configs/Startup_Apps.disable" - mkdir -p "$(dirname "$OVERLAY_SA")" - touch "$OVERLAY_SA" "$DISABLE_SA" - if ! grep -qx 'exec-once = $scriptsDir/Polkit-NixOS.sh' "$OVERLAY_SA"; then - echo 'exec-once = $scriptsDir/Polkit-NixOS.sh' >>"$OVERLAY_SA" - fi - if ! grep -qx '\$scriptsDir/Polkit.sh' "$DISABLE_SA"; then - echo '$scriptsDir/Polkit.sh' >>"$DISABLE_SA" - fi -fi +detect_nvidia_adjust "$LOG" +detect_vm_adjust "$LOG" +detect_nixos_adjust "$LOG" # activating hyprcursor on env by checking if the directory ~/.icons/Bibata-Modern-Ice/hyprcursors exists if [ -d "$HOME/.icons/Bibata-Modern-Ice/hyprcursors" ]; then @@ -1322,8 +1297,8 @@ chmod +x "$HOME/.config/hypr/UserScripts/"* 2>&1 | tee -a "$LOG" # Set executable for initial-boot.sh chmod +x "$HOME/.config/hypr/initial-boot.sh" 2>&1 | tee -a "$LOG" -# Waybar config to symlink & retain based on machine type -if hostnamectl | grep -q 'Chassis: desktop'; then +chassis_type=$(detect_waybar_config) +if [ "$chassis_type" = "desktop" ]; then config_file="$waybar_config" config_remove=" Laptop" else diff --git a/scripts/lib_detect.sh b/scripts/lib_detect.sh new file mode 100644 index 00000000..5cb26c1b --- /dev/null +++ b/scripts/lib_detect.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Detection and environment adjustment helpers shared by copy.sh. + +# Nvidia tweaks: uncomments envs and adjusts hardware cursor setting. +detect_nvidia_adjust() { + local log="$1" + if lspci -k | grep -A 2 -E "(VGA|3D)" | grep -iq nvidia; then + echo "${INFO:-[INFO]} Nvidia GPU detected. Setting up proper env's and configs" 2>&1 | tee -a "$log" || true + sed -i '/env = LIBVA_DRIVER_NAME,nvidia/s/^#//' config/hypr/configs/ENVariables.conf + sed -i '/env = __GLX_VENDOR_LIBRARY_NAME,nvidia/s/^#//' config/hypr/configs/ENVariables.conf + sed -i '/env = NVD_BACKEND,direct/s/^#//' config/hypr/configs/ENVariables.conf + sed -i '/env = GSK_RENDERER,ngl/s/^#//' config/hypr/configs/ENVariables.conf + sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/configs/SystemSettings.conf + fi +} + +# VM tweaks: enable software renderer envs and virtual monitor defaults. +detect_vm_adjust() { + local log="$1" + if hostnamectl | grep -q 'Chassis: vm'; then + echo "${INFO:-[INFO]} System is running in a virtual machine. Setting up proper env's and configs" 2>&1 | tee -a "$log" || true + sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/configs/SystemSettings.conf + sed -i '/env = WLR_RENDERER_ALLOW_SOFTWARE,1/s/^#//' config/hypr/configs/ENVariables.conf + sed -i '/monitor = Virtual-1, 1920x1080@60,auto,1/s/^#//' config/hypr/monitors.conf + fi +} + +# NixOS tweaks: ensure polkit overlay is enabled and default disabled. +detect_nixos_adjust() { + local log="$1" + if hostnamectl | grep -q 'Operating System: NixOS'; then + echo "${INFO:-[INFO]} NixOS Distro Detected. Setting up proper env's and configs." 2>&1 | tee -a "$log" || true + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + local DISABLE_SA="config/hypr/configs/Startup_Apps.disable" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" "$DISABLE_SA" + grep -qx 'exec-once = $scriptsDir/Polkit-NixOS.sh' "$OVERLAY_SA" || echo 'exec-once = $scriptsDir/Polkit-NixOS.sh' >>"$OVERLAY_SA" + grep -qx '\$scriptsDir/Polkit.sh' "$DISABLE_SA" || echo '$scriptsDir/Polkit.sh' >>"$DISABLE_SA" + fi +} + +# Decide waybar config/style based on chassis type. Echoes chosen config path. +detect_waybar_config() { + if hostnamectl | grep -q 'Chassis: desktop'; then + echo "desktop" + else + echo "laptop" + fi +} -- cgit v1.2.3 From a31e55ca4acac4bc256b6bb38915b6e414da90ad Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:30:05 -0500 Subject: Moved the prompts for keyboard, resolution, clock, rainbow borders Further modularizing the copy.sh script The express upgrade is almost moved here On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh new file: scripts/lib_prompts.sh --- copy.sh | 303 ++++--------------------------------------------- scripts/lib_prompts.sh | 256 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 283 deletions(-) create mode 100644 scripts/lib_prompts.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 386cbe17..aa634fd3 100755 --- a/copy.sh +++ b/copy.sh @@ -5,14 +5,14 @@ # Handles interactive prompts, backups/restores, per-app tweaks, and express mode. # # Layout (high-level; future modularization targets): -# - Constants/colors, helper sourcing (copy_menu.sh). +# - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh). # - Version helpers and CLI parsing (install/upgrade/express). # - Safety checks (non-root), banners/notices. # - Environment/distro checks and warnings. -# - GPU/VM/NixOS detection tweaks. -# - Input prompts (keyboard, resolution, clock format, animations). +# - GPU/VM/NixOS detection tweaks (lib_detect.sh). +# - Input prompts (keyboard, resolution, clock format, animations) (lib_prompts.sh). # - Workflow selection effects (express vs standard). -# - Backup/restore helpers (inline today; planned to move to scripts/lib_backup.sh). +# - Backup/restore helpers (in scripts/lib_backup.sh). # - Copy phases: # * Part 1: fastfetch/kitty/rofi/swaync (prompted replace). # * Waybar special handling (symlinks, configs/styles restore). @@ -24,8 +24,8 @@ # - Final symlinks (waybar) and wallust init. # # Next modular step: -# Extract backup/restore/cleanup functions into scripts/lib_backup.sh -# and source them similar to scripts/copy_menu.sh. +# Extract per-app installers (ags/quickshell/ghostty/wezterm) and editor selection +# into scripts/lib_apps.sh; then consider splitting copy phases into dedicated helpers. clear wallpaper=$HOME/.config/hypr/wallpaper_effects/.wallpaper_current @@ -53,6 +53,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MENU_HELPER="$SCRIPT_DIR/scripts/copy_menu.sh" BACKUP_HELPER="$SCRIPT_DIR/scripts/lib_backup.sh" DETECT_HELPER="$SCRIPT_DIR/scripts/lib_detect.sh" +PROMPTS_HELPER="$SCRIPT_DIR/scripts/lib_prompts.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" @@ -71,6 +72,13 @@ else echo "${ERROR} Detect helper not found at $DETECT_HELPER. Exiting." exit 1 fi +if [ -f "$PROMPTS_HELPER" ]; then + # shellcheck source=./scripts/lib_prompts.sh + . "$PROMPTS_HELPER" +else + echo "${ERROR} Prompts helper not found at $PROMPTS_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -137,7 +145,6 @@ EXPRESS_SUPPORTED=0 if express_supported; then EXPRESS_SUPPORTED=1 fi - if [ "$EXPRESS_MODE" -eq 1 ] && [ "$EXPRESS_SUPPORTED" -eq 0 ]; then echo "${WARN} Express upgrade requires installed dotfiles v${MIN_EXPRESS_VERSION} or newer. Falling back to standard upgrade." EXPRESS_MODE=0 @@ -268,114 +275,8 @@ fi printf "\n%.0s" {1..1} -# Function to detect keyboard layout using localectl or setxkbmap -detect_layout() { - if command -v localectl >/dev/null 2>&1; then - layout=$(localectl status --no-pager | awk '/X11 Layout/ {print $3}') - if [ -n "$layout" ]; then - echo "$layout" - fi - elif command -v setxkbmap >/dev/null 2>&1; then - layout=$(setxkbmap -query | grep layout | awk '{print $2}') - if [ -n "$layout" ]; then - echo "$layout" - fi - fi -} - -# Detect the current keyboard layout -layout=$(detect_layout) - -if [ "$layout" = "(unset)" ]; then - while true; do - printf "\n%.0s" {1..1} - print_color $WARNING " - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - STOP AND READ - █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ - - !!! IMPORTANT WARNING !!! - -The Default Keyboard Layout could not be detected -You need to set it Manually - - !!! WARNING !!! - -Setting a wrong Keyboard Layout will cause Hyprland to crash -If you are not sure, just type ${YELLOW}us${RESET} -${SKYBLUE}You can change later in ~/.config/hypr/UserConfigs/UserSettings.conf${RESET} - -${MAGENTA} NOTE:${RESET} -• You can also set more than 2 keyboard layouts -• For example: ${YELLOW}us, kr, gb, ru${RESET} -" - printf "\n%.0s" {1..1} - - echo -n "${CAT} - Please enter the correct keyboard layout: " - read new_layout - - if [ -n "$new_layout" ]; then - layout="$new_layout" - break - else - echo "${CAT} Please enter a keyboard layout." - fi - done -fi - -printf "${NOTE} Detecting keyboard layout to prepare proper Hyprland Settings\n" - -# Prompt the user to confirm whether the detected layout is correct -while true; do - printf "${INFO} Current keyboard layout is ${MAGENTA}$layout${RESET}\n" - echo -n "${CAT} Is this correct? [y/n] " - read keyboard_layout - - case $keyboard_layout in - [yY]) - awk -v layout="$layout" '/kb_layout/ {$0 = " kb_layout = " layout} 1' config/hypr/configs/SystemSettings.conf >temp.conf - mv temp.conf config/hypr/configs/SystemSettings.conf - - echo "${NOTE} kb_layout ${MAGENTA}$layout${RESET} configured in settings." 2>&1 | tee -a "$LOG" - break - ;; - [nN]) - printf "\n%.0s" {1..2} - print_color $WARNING " - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - STOP AND READ - █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ - - !!! IMPORTANT WARNING !!! - -The Default Keyboard Layout could not be detected -You need to set it Manually - - !!! WARNING !!! - -Setting a wrong Keyboard Layout will cause Hyprland to crash -If you are not sure, just type ${YELLOW}us${RESET} -${SKYBLUE}You can change later in ~/.config/hypr/UserConfigs/UserSettings.conf${RESET} - -${MAGENTA} NOTE:${RESET} -• You can also set more than 2 keyboard layouts -• For example: ${YELLOW}us, kr, gb, ru${RESET} -" - printf "\n%.0s" {1..1} - - echo -n "${CAT} - Please enter the correct keyboard layout: " - read new_layout - - awk -v new_layout="$new_layout" '/kb_layout/ {$0 = " kb_layout = " new_layout} 1' config/hypr/configs/SystemSettings.conf >temp.conf - mv temp.conf config/hypr/configs/SystemSettings.conf - echo "${OK} kb_layout $new_layout configured in settings." 2>&1 | tee -a "$LOG" - break - ;; - *) - echo "${ERROR} Please enter either 'y' or 'n'." - ;; - esac -done +layout=$(prompt_detect_layout) +prompt_keyboard_layout "$layout" "$LOG" # Check if asusctl is installed and add rog-control-center on Startup if command -v asusctl >/dev/null 2>&1; then @@ -460,37 +361,8 @@ fi printf "\n" -# Action to do for better appearance -while true; do - echo "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured for 1440p or 2k." - echo "${WARN} If you dont select proper resolution, Hyprlock will look FUNKY!" - echo "${INFO} If you are not sure what is your resolution, choose 1 here!" - echo "${MAGENTA}Select monitor resolution to properly configure appearance and fonts:" - echo "$YELLOW -- Enter 1. for monitor resolution less than 1440p (< 1440p)" - echo "$YELLOW -- Enter 2. for monitor resolution equal to or higher than 1440p (≥ 1440p)" - - echo -n "$CAT Enter the number of your choice (1 or 2): " - read res_choice - - case $res_choice in - 1) - resolution="< 1440p" - break - ;; - 2) - resolution="≥ 1440p" - break - ;; - *) - echo "${ERROR} Invalid choice. Please enter 1 for < 1440p or 2 for ≥ 1440p." - ;; - esac -done - -# Use the selected resolution in your existing script +resolution=$(prompt_resolution_choice) echo "${OK} You have chosen $resolution resolution." 2>&1 | tee -a "$LOG" - -# actions if < 1440p is chosen if [ "$resolution" == "< 1440p" ]; then # kitty font size sed -i 's/font_size 16.0/font_size 14.0/' config/kitty/kitty.conf @@ -513,146 +385,11 @@ fi printf "\n%.0s" {1..1} -# Ask whether to change to 12hr format -while true; do - echo -e "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured in 24H clock format." - echo -n "$CAT Do you want to change to 12H (AM/PM) clock format? (y/n): " - read answer - - # Convert the answer to lowercase for comparison - answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') - - # Check if the answer is valid - if [[ "$answer" == "y" ]]; then - # Modify waybar clock modules if 12hr is selected - # Clock 1 - sed -i 's#^\(\s*\)//\("format": " {:%I:%M %p}",\) #\1\2 #g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": " {:%H:%M:%S}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 2 - sed -i 's#^\(\s*\)\("format": " {:%H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 3 - sed -i 's#^\(\s*\)//\("format": "{:%I:%M %p - %d/%b}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%H:%M - %d/%b}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 4 - sed -i 's#^\(\s*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%B | %a %d, %Y | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 5 - sed -i 's#^\(\s*\)//\("format": "{:%A, %I:%M %P}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%a %d | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # for hyprlock - HYPRLOCK_FILE="config/hypr/hyprlock.conf" - if [ ! -f "$HYPRLOCK_FILE" ] && [ -f "config/hypr/hyprlock-1080p.conf" ]; then - HYPRLOCK_FILE="config/hypr/hyprlock-1080p.conf" - fi - if [ -f "$HYPRLOCK_FILE" ]; then - sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%H")"/# &/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$LOG" - sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$LOG" - - sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%S")"/# &/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$LOG" - sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$LOG" - else - echo "${WARN} hyprlock template not found; skipping 12H lock format edits" 2>&1 | tee -a "$LOG" - fi - - echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$LOG" - - # Function to apply 12H format to SDDM themes - apply_sddm_12h_format() { - local sddm_directory=$1 - - # Check if the directory exists - if [ -d "$sddm_directory" ]; then - echo "Editing ${SKY_BLUE}$sddm_directory${RESET} to 12H format" 2>&1 | tee -a "$LOG" - - sudo sed -i 's|^## HourFormat="hh:mm AP"|HourFormat="hh:mm AP"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$LOG" || true - sudo sed -i 's|^HourFormat="HH:mm"|## HourFormat="HH:mm"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$LOG" || true - fi - } - - # Applying to different SDDM themes - apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" - apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" - - # For SDDM (sequoia_2) - sddm_directory_3="/usr/share/sddm/themes/sequoia_2" - if [ -d "$sddm_directory_3" ]; then - echo "${YELLOW}sddm sequoia_2${RESET} theme exists. Editing to 12H format" 2>&1 | tee -a "$LOG" - - # Comment out the existing clockFormat="HH:mm" line - sudo sed -i 's|^clockFormat="HH:mm"|## clockFormat="HH:mm"|' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true - - # Insert the new clockFormat="hh:mm AP" line if it's not already present - if ! grep -q 'clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf"; then - sudo sed -i '/^clockFormat=/a clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true - fi - - echo "${OK} 12H format set to SDDM successfully." 2>&1 | tee -a "$LOG" - fi - - break - - elif [[ "$answer" == "n" ]]; then - echo "${NOTE} You chose not to change to 12H format." 2>&1 | tee -a "$LOG" - break # Exit the loop if the user chooses "n" - else - echo "${ERROR} Invalid choice. Please enter y for yes or n for no." - fi -done +prompt_clock_12h "$LOG" printf "\n%.0s" {1..1} - -# Check if the user wants to disable Rainbow borders -echo "${NOTE} ${SKY_BLUE}By default, Rainbow Borders animation is enabled" -echo "${WARN} However, this uses a bit more CPU and Memory resources." - -# Ask whether to disable Rainbow Borders animation -echo -n "${CAT} Do you want to disable Rainbow Borders animation? (y/N): " -read border_choice - -# Check user's choice -if [[ "$border_choice" =~ ^[Yy]$ ]]; then - # Disable Rainbow Borders - mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh - - # Comment out the exec-once and animation lines - sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/configs/Startup_Apps.conf - sed -i '/^[[:space:]]*animation = borderangle, 1, 180, liner, loop/s/^/#/' config/hypr/configs/UserAnimations.conf - - echo "${OK} Rainbow borders are now disabled." 2>&1 | tee -a "$LOG" -else - echo "${NOTE} No changes made. Rainbow borders remain enabled." 2>&1 | tee -a "$LOG" -fi +prompt_rainbow_borders "$LOG" >/dev/null printf "\n%.0s" {1..1} - -if [ "$UPGRADE_MODE" -eq 1 ] && [ "$EXPRESS_MODE" -eq 0 ]; then - if [ "$EXPRESS_SUPPORTED" -eq 0 ]; then - echo "${NOTE} Express mode requires installed dotfiles v${MIN_EXPRESS_VERSION} or newer. Continuing with standard upgrade prompts." 2>&1 | tee -a "$LOG" - else - while true; do - echo "${NOTE} Express mode skips config restore prompts, SDDM/background questions, and trims old backups." - echo -n "${CAT} Do you want to continue with EXPRESS upgrade mode? (y/N): " - read express_choice - case "$express_choice" in - [Yy]) - EXPRESS_MODE=1 - echo "${INFO} Express mode enabled for this upgrade." 2>&1 | tee -a "$LOG" - break - ;; - [Nn] | "") - echo "${NOTE} Continuing with standard upgrade prompts." 2>&1 | tee -a "$LOG" - break - ;; - *) - echo "${WARN} Please answer y or n." - ;; - esac - done - fi -fi +prompt_express_upgrade "$EXPRESS_SUPPORTED" "$LOG" set -e diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh new file mode 100644 index 00000000..16931892 --- /dev/null +++ b/scripts/lib_prompts.sh @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +# User interaction helpers extracted from copy.sh. Each helper echoes state or sets +# globals deliberately to minimize side effects. + +# Detect keyboard layout via localectl or setxkbmap. +prompt_detect_layout() { + if command -v localectl >/dev/null 2>&1; then + local layout + layout=$(localectl status --no-pager | awk '/X11 Layout/ {print $3}') + [ -n "$layout" ] && { echo "$layout"; return; } + fi + if command -v setxkbmap >/dev/null 2>&1; then + local layout + layout=$(setxkbmap -query | awk '/layout/ {print $2}') + [ -n "$layout" ] && { echo "$layout"; return; } + fi + echo "(unset)" +} + +# Confirm or set keyboard layout; writes to SystemSettings.conf. +prompt_keyboard_layout() { + local layout="$1" + local log="$2" + + if [ "$layout" = "(unset)" ]; then + while true; do + printf "\n%.0s" {1..1} + print_color $WARNING "\n █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ + STOP AND READ + █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ + + !!! IMPORTANT WARNING !!! + +The Default Keyboard Layout could not be detected +You need to set it Manually + + !!! WARNING !!! + +Setting a wrong Keyboard Layout will cause Hyprland to crash +If you are not sure, just type ${YELLOW}us${RESET} +${SKYBLUE}You can change later in ~/.config/hypr/UserConfigs/UserSettings.conf${RESET} + +${MAGENTA} NOTE:${RESET} +• You can also set more than 2 keyboard layouts +• For example: ${YELLOW}us, kr, gb, ru${RESET} +" + printf "\n%.0s" {1..1} + + echo -n "${CAT} - Please enter the correct keyboard layout: " + read new_layout + + if [ -n "$new_layout" ]; then + layout="$new_layout" + break + else + echo "${CAT} Please enter a keyboard layout." + fi + done + fi + + printf "${NOTE} Detecting keyboard layout to prepare proper Hyprland Settings\n" + while true; do + printf "${INFO} Current keyboard layout is ${MAGENTA}$layout${RESET}\n" + echo -n "${CAT} Is this correct? [y/n] " + read keyboard_layout + case $keyboard_layout in + [yY]) + awk -v layout="$layout" '/kb_layout/ {$0 = " kb_layout = " layout} 1' config/hypr/configs/SystemSettings.conf >temp.conf + mv temp.conf config/hypr/configs/SystemSettings.conf + echo "${NOTE} kb_layout ${MAGENTA}$layout${RESET} configured in settings." 2>&1 | tee -a "$log" + break + ;; + [nN]) + printf "\n%.0s" {1..2} + print_color $WARNING " + █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ + STOP AND READ + █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ + + !!! IMPORTANT WARNING !!! + +The Default Keyboard Layout could not be detected +You need to set it Manually + + !!! WARNING !!! + +Setting a wrong Keyboard Layout will cause Hyprland to crash +If you are not sure, just type ${YELLOW}us${RESET} +${SKYBLUE}You can change later in ~/.config/hypr/UserConfigs/UserSettings.conf${RESET} + +${MAGENTA} NOTE:${RESET} +• You can also set more than 2 keyboard layouts +• For example: ${YELLOW}us, kr, gb, ru${RESET} +" + printf "\n%.0s" {1..1} + echo -n "${CAT} - Please enter the correct keyboard layout: " + read new_layout + awk -v new_layout="$new_layout" '/kb_layout/ {$0 = " kb_layout = " new_layout} 1' config/hypr/configs/SystemSettings.conf >temp.conf + mv temp.conf config/hypr/configs/SystemSettings.conf + echo "${OK} kb_layout $new_layout configured in settings." 2>&1 | tee -a "$log" + break + ;; + *) + echo "${ERROR} Please enter either 'y' or 'n'." + ;; + esac + done +} + +# Prompt for resolution choice; echoes "< 1440p" or "≥ 1440p". +prompt_resolution_choice() { + local choice + while true; do + echo "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured for 1440p or 2k." + echo "${WARN} If you dont select proper resolution, Hyprlock will look FUNKY!" + echo "${INFO} If you are not sure what is your resolution, choose 1 here!" + echo "${MAGENTA}Select monitor resolution to properly configure appearance and fonts:" + echo "$YELLOW -- Enter 1. for monitor resolution less than 1440p (< 1440p)" + echo "$YELLOW -- Enter 2. for monitor resolution equal to or higher than 1440p (≥ 1440p)" + + echo -n "$CAT Enter the number of your choice (1 or 2): " + read choice + case $choice in + 1) echo "< 1440p"; return ;; + 2) echo "≥ 1440p"; return ;; + *) echo "${ERROR} Invalid choice. Please enter 1 for < 1440p or 2 for ≥ 1440p." ;; + esac + done +} + +# Prompt for 12H clock; sets waybar/hyprlock/SDDM changes when accepted. +prompt_clock_12h() { + local log="$1" + while true; do + echo -e "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured in 24H clock format." + echo -n "$CAT Do you want to change to 12H (AM/PM) clock format? (y/n): " + read answer + answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') + if [[ "$answer" == "y" ]]; then + # waybar clocks + sed -i 's#^\(\s*\)//\("format": " {:%I:%M %p}",\) #\1\2 #g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)\("format": " {:%H:%M:%S}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)\("format": " {:%H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)//\("format": "{:%I:%M %p - %d/%b}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)\("format": "{:%H:%M - %d/%b}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)\("format": "{:%B | %a %d, %Y | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)//\("format": "{:%A, %I:%M %P}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + sed -i 's#^\(\s*\)\("format": "{:%a %d | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$log" + + # hyprlock + local HYPRLOCK_FILE="config/hypr/hyprlock.conf" + if [ ! -f "$HYPRLOCK_FILE" ] && [ -f "config/hypr/hyprlock-1080p.conf" ]; then + HYPRLOCK_FILE="config/hypr/hyprlock-1080p.conf" + fi + if [ -f "$HYPRLOCK_FILE" ]; then + sed -i 's/^\s*text = cmd\[update:1000\] echo \"\$(date +\"%H\")\"/# &/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$log" + sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo \"\$(date +\"%I\")\" #AM\/PM/\1 text = cmd\[update:1000\] echo \"\$(date +\"%I\")\" #AM\/PM/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$log" + sed -i 's/^\s*text = cmd\[update:1000\] echo \"\$(date +\"%S\")\"/# &/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$log" + sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo \"\$(date +\"%S %p\")\" #AM\/PM/\1 text = cmd\[update:1000\] echo \"\$(date +\"%S %p\")\" #AM\/PM/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$log" + else + echo "${WARN} hyprlock template not found; skipping 12H lock format edits" 2>&1 | tee -a "$log" + fi + + # SDDM themes + apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" "$log" + apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" "$log" + apply_sddm_12h_format_sequoia "/usr/share/sddm/themes/sequoia_2" "$log" + echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$log" + return + elif [[ "$answer" == "n" ]]; then + echo "${NOTE} You chose not to change to 12H format." 2>&1 | tee -a "$log" + return + else + echo "${ERROR} Invalid choice. Please enter y for yes or n for no." + fi + done +} + +apply_sddm_12h_format() { + local sddm_directory="$1" + local log="$2" + if [ -d "$sddm_directory" ]; then + echo "Editing ${SKY_BLUE}$sddm_directory${RESET} to 12H format" 2>&1 | tee -a "$log" + sudo sed -i 's|^## HourFormat=\"hh:mm AP\"|HourFormat=\"hh:mm AP\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + sudo sed -i 's|^HourFormat=\"HH:mm\"|## HourFormat=\"HH:mm\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + fi +} + +apply_sddm_12h_format_sequoia() { + local sddm_directory="$1" + local log="$2" + if [ -d "$sddm_directory" ]; then + echo "${YELLOW}sddm sequoia_2${RESET} theme exists. Editing to 12H format" 2>&1 | tee -a "$log" + sudo sed -i 's|^clockFormat=\"HH:mm\"|## clockFormat=\"HH:mm\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + if ! grep -q 'clockFormat=\"hh:mm AP\"' "$sddm_directory/theme.conf"; then + sudo sed -i '/^clockFormat=/a clockFormat=\"hh:mm AP\"' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + fi + echo "${OK} 12H format set to SDDM successfully." 2>&1 | tee -a "$log" + fi +} + +# Rainbow borders toggle; returns "disabled" or "kept". +prompt_rainbow_borders() { + local log="$1" + echo "${NOTE} ${SKY_BLUE}By default, Rainbow Borders animation is enabled" + echo "${WARN} However, this uses a bit more CPU and Memory resources." + echo -n "${CAT} Do you want to disable Rainbow Borders animation? (y/N): " + read border_choice + if [[ "$border_choice" =~ ^[Yy]$ ]]; then + mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh + sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/configs/Startup_Apps.conf + sed -i '/^[[:space:]]*animation = borderangle, 1, 180, liner, loop/s/^/#/' config/hypr/configs/UserAnimations.conf + echo "${OK} Rainbow borders are now disabled." 2>&1 | tee -a "$log" + echo "disabled" + else + echo "${NOTE} No changes made. Rainbow borders remain enabled." 2>&1 | tee -a "$log" + echo "kept" + fi +} + +# Express upgrade confirmation; may set EXPRESS_MODE=1. +prompt_express_upgrade() { + local express_supported="$1" + local log="$2" + if [ "$EXPRESS_MODE" -eq 1 ] && [ "$express_supported" -eq 0 ]; then + echo "${NOTE} Express mode requires installed dotfiles v${MIN_EXPRESS_VERSION} or newer. Continuing with standard upgrade prompts." 2>&1 | tee -a "$log" + EXPRESS_MODE=0 + return + fi + if [ "$UPGRADE_MODE" -eq 1 ] && [ "$EXPRESS_MODE" -eq 0 ]; then + if [ "$express_supported" -eq 0 ]; then + echo "${NOTE} Express mode requires installed dotfiles v${MIN_EXPRESS_VERSION} or newer. Continuing with standard upgrade prompts." 2>&1 | tee -a "$log" + else + while true; do + echo "${NOTE} Express mode skips config restore prompts, SDDM/background questions, and trims old backups." + echo -n "${CAT} Do you want to continue with EXPRESS upgrade mode? (y/N): " + read express_choice + case "$express_choice" in + [Yy]) + EXPRESS_MODE=1 + echo "${INFO} Express mode enabled for this upgrade." 2>&1 | tee -a "$log" + break + ;; + [Nn] | "") + echo "${NOTE} Continuing with standard upgrade prompts." 2>&1 | tee -a "$log" + break + ;; + *) + echo "${WARN} Please answer y or n." + ;; + esac + done + fi + fi +} -- cgit v1.2.3 From e73e6a5ce96a7fd0e849cd112321e3160bedff80 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:39:15 -0500 Subject: fixing prompts for resolution, clock, etc On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh modified: scripts/lib_prompts.sh --- copy.sh | 3 +-- scripts/lib_prompts.sh | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index aa634fd3..0a68ea02 100755 --- a/copy.sh +++ b/copy.sh @@ -360,7 +360,7 @@ if [[ "$EDITOR_SET" -eq 0 ]] && command -v vim &>/dev/null; then fi printf "\n" - +echo "${INFO} Awaiting monitor resolution selection (1=<1440p, 2=≥1440p)..." 2>&1 | tee -a "$LOG" resolution=$(prompt_resolution_choice) echo "${OK} You have chosen $resolution resolution." 2>&1 | tee -a "$LOG" if [ "$resolution" == "< 1440p" ]; then @@ -384,7 +384,6 @@ if [ "$resolution" == "< 1440p" ]; then fi printf "\n%.0s" {1..1} - prompt_clock_12h "$LOG" printf "\n%.0s" {1..1} prompt_rainbow_borders "$LOG" >/dev/null diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index 16931892..ae493842 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -111,6 +111,7 @@ ${MAGENTA} NOTE:${RESET} prompt_resolution_choice() { local choice while true; do + echo "${INFO:-[INFO]} Resolution selection required (1 = <1440p, 2 = ≥1440p)" echo "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured for 1440p or 2k." echo "${WARN} If you dont select proper resolution, Hyprlock will look FUNKY!" echo "${INFO} If you are not sure what is your resolution, choose 1 here!" -- cgit v1.2.3 From 292bbd0bce87926157a58f2f1f6a73046a122130 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:43:22 -0500 Subject: Fixing resoltion prmpt --- copy.sh | 1 - scripts/lib_prompts.sh | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 0a68ea02..d35af646 100755 --- a/copy.sh +++ b/copy.sh @@ -360,7 +360,6 @@ if [[ "$EDITOR_SET" -eq 0 ]] && command -v vim &>/dev/null; then fi printf "\n" -echo "${INFO} Awaiting monitor resolution selection (1=<1440p, 2=≥1440p)..." 2>&1 | tee -a "$LOG" resolution=$(prompt_resolution_choice) echo "${OK} You have chosen $resolution resolution." 2>&1 | tee -a "$LOG" if [ "$resolution" == "< 1440p" ]; then diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index ae493842..45772abb 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -119,9 +119,8 @@ prompt_resolution_choice() { echo "$YELLOW -- Enter 1. for monitor resolution less than 1440p (< 1440p)" echo "$YELLOW -- Enter 2. for monitor resolution equal to or higher than 1440p (≥ 1440p)" - echo -n "$CAT Enter the number of your choice (1 or 2): " - read choice - case $choice in + read -r -p "${CAT} Enter the number of your choice (1 or 2): " choice + case "$choice" in 1) echo "< 1440p"; return ;; 2) echo "≥ 1440p"; return ;; *) echo "${ERROR} Invalid choice. Please enter 1 for < 1440p or 2 for ≥ 1440p." ;; -- cgit v1.2.3 From 27dae2e40ac4fa27cc55a7fa90927fb47a641a85 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:44:51 -0500 Subject: Fixed res prompt --- scripts/lib_prompts.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index 45772abb..ce75462c 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -111,13 +111,9 @@ ${MAGENTA} NOTE:${RESET} prompt_resolution_choice() { local choice while true; do - echo "${INFO:-[INFO]} Resolution selection required (1 = <1440p, 2 = ≥1440p)" - echo "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured for 1440p or 2k." - echo "${WARN} If you dont select proper resolution, Hyprlock will look FUNKY!" - echo "${INFO} If you are not sure what is your resolution, choose 1 here!" - echo "${MAGENTA}Select monitor resolution to properly configure appearance and fonts:" - echo "$YELLOW -- Enter 1. for monitor resolution less than 1440p (< 1440p)" - echo "$YELLOW -- Enter 2. for monitor resolution equal to or higher than 1440p (≥ 1440p)" + echo "${INFO:-[INFO]} Select monitor resolution for scaling:" + echo " 1) < 1440p (lower DPI; smaller displays)" + echo " 2) ≥ 1440p (default; 1440p/2k/4k)" read -r -p "${CAT} Enter the number of your choice (1 or 2): " choice case "$choice" in -- cgit v1.2.3 From bf494381829c904425b8bda46b087572b09e7ca4 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:46:11 -0500 Subject: Fixed banner --- scripts/lib_prompts.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index ce75462c..6f426b53 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -115,7 +115,11 @@ prompt_resolution_choice() { echo " 1) < 1440p (lower DPI; smaller displays)" echo " 2) ≥ 1440p (default; 1440p/2k/4k)" - read -r -p "${CAT} Enter the number of your choice (1 or 2): " choice + if ! read -r -p "${CAT} Enter the number of your choice (1 or 2): " choice Date: Sun, 11 Jan 2026 02:50:31 -0500 Subject: Fixd issues with sddm wallpaper set code --- copy.sh | 2 +- scripts/lib_prompts.sh | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 0553865a..5275eeb5 100755 --- a/copy.sh +++ b/copy.sh @@ -1083,7 +1083,7 @@ elif [ -d "$sddm_simple_sddm_2" ]; then case $SDDM_WALL in [Yy]) # Copy the wallpaper, ignore errors if the file exists or fails - sudo cp -r "config/hypr/wallpaper_effects/.wallpaper_current" "/usr/share/sddm/themes/simple_sddm_2/Backgrounds/default" || true + sudo -n cp -r "config/hypr/wallpaper_effects/.wallpaper_current" "/usr/share/sddm/themes/simple_sddm_2/Backgrounds/default" || true echo "${NOTE} Current wallpaper applied as default SDDM background" 2>&1 | tee -a "$LOG" break ;; diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index 6f426b53..dcad7682 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -182,8 +182,11 @@ apply_sddm_12h_format() { local log="$2" if [ -d "$sddm_directory" ]; then echo "Editing ${SKY_BLUE}$sddm_directory${RESET} to 12H format" 2>&1 | tee -a "$log" - sudo sed -i 's|^## HourFormat=\"hh:mm AP\"|HourFormat=\"hh:mm AP\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true - sudo sed -i 's|^HourFormat=\"HH:mm\"|## HourFormat=\"HH:mm\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + if ! sudo -n sed -i 's|^## HourFormat="hh:mm AP"|HourFormat="hh:mm AP"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log"; then + echo "${WARN:-[WARN]} Skipping SDDM 12H edit (sudo password required)." 2>&1 | tee -a "$log" + return + fi + sudo -n sed -i 's|^HourFormat="HH:mm"|## HourFormat="HH:mm"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true fi } @@ -192,9 +195,12 @@ apply_sddm_12h_format_sequoia() { local log="$2" if [ -d "$sddm_directory" ]; then echo "${YELLOW}sddm sequoia_2${RESET} theme exists. Editing to 12H format" 2>&1 | tee -a "$log" - sudo sed -i 's|^clockFormat=\"HH:mm\"|## clockFormat=\"HH:mm\"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true - if ! grep -q 'clockFormat=\"hh:mm AP\"' "$sddm_directory/theme.conf"; then - sudo sed -i '/^clockFormat=/a clockFormat=\"hh:mm AP\"' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true + if ! sudo -n sed -i 's|^clockFormat="HH:mm"|## clockFormat="HH:mm"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log"; then + echo "${WARN:-[WARN]} Skipping sequoia SDDM 12H edit (sudo password required)." 2>&1 | tee -a "$log" + return + fi + if ! grep -q 'clockFormat="hh:mm AP"' "$sddm_directory/theme.conf"; then + sudo -n sed -i '/^clockFormat=/a clockFormat="hh:mm AP"' "$sddm_directory/theme.conf" 2>&1 | tee -a "$log" || true fi echo "${OK} 12H format set to SDDM successfully." 2>&1 | tee -a "$log" fi -- cgit v1.2.3 From d10333068edefd57a354332c3d32cb8ae3fb81b2 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:53:39 -0500 Subject: Got caught in sudo/sddm loop --- scripts/lib_prompts.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index dcad7682..c79c9da6 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -162,10 +162,13 @@ prompt_clock_12h() { echo "${WARN} hyprlock template not found; skipping 12H lock format edits" 2>&1 | tee -a "$log" fi - # SDDM themes - apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" "$log" - apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" "$log" - apply_sddm_12h_format_sequoia "/usr/share/sddm/themes/sequoia_2" "$log" + if [ "${EXPRESS_MODE:-0}" -eq 0 ]; then + apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" "$log" + apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" "$log" + apply_sddm_12h_format_sequoia "/usr/share/sddm/themes/sequoia_2" "$log" + else + echo "${NOTE:-[NOTE]} Express mode: skipping SDDM 12H edits to avoid sudo prompts." 2>&1 | tee -a "$log" + fi echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$log" return elif [[ "$answer" == "n" ]]; then -- cgit v1.2.3 From 3392c883f24c62e011775fa41c2cfc93086bfd7d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 02:59:35 -0500 Subject: Still working on prompts code On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: scripts/lib_prompts.sh --- scripts/lib_prompts.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index c79c9da6..a63afde3 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -214,8 +214,11 @@ prompt_rainbow_borders() { local log="$1" echo "${NOTE} ${SKY_BLUE}By default, Rainbow Borders animation is enabled" echo "${WARN} However, this uses a bit more CPU and Memory resources." - echo -n "${CAT} Do you want to disable Rainbow Borders animation? (y/N): " - read border_choice + if ! read -r -p "${CAT} Do you want to disable Rainbow Borders animation? (y/N): " border_choice &1 | tee -a "$log" + echo "kept" + return + fi if [[ "$border_choice" =~ ^[Yy]$ ]]; then mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/configs/Startup_Apps.conf @@ -243,8 +246,10 @@ prompt_express_upgrade() { else while true; do echo "${NOTE} Express mode skips config restore prompts, SDDM/background questions, and trims old backups." - echo -n "${CAT} Do you want to continue with EXPRESS upgrade mode? (y/N): " - read express_choice + if ! read -r -p "${CAT} Do you want to continue with EXPRESS upgrade mode? (y/N): " express_choice &1 | tee -a "$log" + break + fi case "$express_choice" in [Yy]) EXPRESS_MODE=1 -- cgit v1.2.3 From 997a522e5aca800392c93c42446991bd46a76a0d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 03:17:29 -0500 Subject: created next modules for apps, editr,bt,rog,rog,ags,qs Phase 4 moving apps to its own module On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh new file: scripts/lib_apps.sh --- copy.sh | 100 ++++++++++------------------------------------------ scripts/lib_apps.sh | 87 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 82 deletions(-) create mode 100644 scripts/lib_apps.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 5275eeb5..11a6223b 100755 --- a/copy.sh +++ b/copy.sh @@ -5,7 +5,7 @@ # Handles interactive prompts, backups/restores, per-app tweaks, and express mode. # # Layout (high-level; future modularization targets): -# - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh). +# - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh, lib_apps.sh). # - Version helpers and CLI parsing (install/upgrade/express). # - Safety checks (non-root), banners/notices. # - Environment/distro checks and warnings. @@ -13,6 +13,7 @@ # - Input prompts (keyboard, resolution, clock format, animations) (lib_prompts.sh). # - Workflow selection effects (express vs standard). # - Backup/restore helpers (in scripts/lib_backup.sh). +# - App enablement/editor selection (lib_apps.sh). # - Copy phases: # * Part 1: fastfetch/kitty/rofi/swaync (prompted replace). # * Waybar special handling (symlinks, configs/styles restore). @@ -24,8 +25,8 @@ # - Final symlinks (waybar) and wallust init. # # Next modular step: -# Extract per-app installers (ags/quickshell/ghostty/wezterm) and editor selection -# into scripts/lib_apps.sh; then consider splitting copy phases into dedicated helpers. +# Split copy phases into dedicated helpers (phase1, waybar, phase2) and consider +# moving ghostty/wezterm install logic into lib_apps.sh. clear wallpaper=$HOME/.config/hypr/wallpaper_effects/.wallpaper_current @@ -54,6 +55,7 @@ MENU_HELPER="$SCRIPT_DIR/scripts/copy_menu.sh" BACKUP_HELPER="$SCRIPT_DIR/scripts/lib_backup.sh" DETECT_HELPER="$SCRIPT_DIR/scripts/lib_detect.sh" PROMPTS_HELPER="$SCRIPT_DIR/scripts/lib_prompts.sh" +APPS_HELPER="$SCRIPT_DIR/scripts/lib_apps.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" @@ -79,6 +81,13 @@ else echo "${ERROR} Prompts helper not found at $PROMPTS_HELPER. Exiting." exit 1 fi +if [ -f "$APPS_HELPER" ]; then + # shellcheck source=./scripts/lib_apps.sh + . "$APPS_HELPER" +else + echo "${ERROR} Apps helper not found at $APPS_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -278,88 +287,15 @@ printf "\n%.0s" {1..1} layout=$(prompt_detect_layout) prompt_keyboard_layout "$layout" "$LOG" -# Check if asusctl is installed and add rog-control-center on Startup -if command -v asusctl >/dev/null 2>&1; then - OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")" - touch "$OVERLAY_SA" - grep -qx 'exec-once = rog-control-center' "$OVERLAY_SA" || echo 'exec-once = rog-control-center' >>"$OVERLAY_SA" -fi - -# Check if blueman-applet is installed and add blueman-applet on Startup -if command -v blueman-applet >/dev/null 2>&1; then - OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")" - touch "$OVERLAY_SA" - grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >>"$OVERLAY_SA" -fi - -# Check if ags is installed and enable it -if command -v ags >/dev/null 2>&1; then - echo "${INFO} AGS detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$LOG" - OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")" - touch "$OVERLAY_SA" - grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >>"$OVERLAY_SA" - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh -fi - -# Check if quickshell is installed and enable it -if command -v qs >/dev/null 2>&1; then - echo "${INFO} Quickshell detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$LOG" - OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")" - touch "$OVERLAY_SA" - grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >>"$OVERLAY_SA" - sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh - sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh -fi - -# Ensure layout-aware keybinds init runs on startup (adds to user overlay so it survives composes) -OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" -mkdir -p "$(dirname "$OVERLAY_SA")" -if ! grep -qx 'exec-once = \$scriptsDir/KeybindsLayoutInit.sh' "$OVERLAY_SA"; then - echo 'exec-once = $scriptsDir/KeybindsLayoutInit.sh' >>"$OVERLAY_SA" - echo "${INFO} Added KeybindsLayoutInit.sh to user Startup_Apps overlay" 2>&1 | tee -a "$LOG" -fi +enable_asusctl "$LOG" +enable_blueman "$LOG" +enable_ags "$LOG" +enable_quickshell "$LOG" +ensure_keybinds_init "$LOG" printf "\n%.0s" {1..1} -# Checking if neovim or vim is installed and offer user if they want to make as default editor -# Function to modify the ENVariables.conf file -update_editor() { - local editor=$1 - sed -i "s/#env = EDITOR,.*/env = EDITOR,$editor #default editor/" config/hypr/UserConfigs/01-UserDefaults.conf - echo "${OK} Default editor set to ${MAGENTA}$editor${RESET}." 2>&1 | tee -a "$LOG" -} - -EDITOR_SET=0 -# Check for neovim if installed -if command -v nvim &>/dev/null; then - printf "${INFO} ${MAGENTA}neovim${RESET} is detected as installed\n" - echo -n "${CAT} Do you want to make ${MAGENTA}neovim${RESET} the default editor? (y/N): " - read EDITOR_CHOICE - if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then - update_editor "nvim" - EDITOR_SET=1 - fi -fi - -printf "\n" - -# Check for vim if installed, but only if neovim wasn't chosen -if [[ "$EDITOR_SET" -eq 0 ]] && command -v vim &>/dev/null; then - printf "${INFO} ${MAGENTA}vim${RESET} is detected as installed\n" - echo -n "${CAT} Do you want to make ${MAGENTA}vim${RESET} the default editor? (y/N): " - read EDITOR_CHOICE - if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then - update_editor "vim" - EDITOR_SET=1 - fi -fi - -printf "\n" +choose_default_editor "$LOG" resolution="" while true; do echo "${INFO} Select monitor resolution for scaling:" diff --git a/scripts/lib_apps.sh b/scripts/lib_apps.sh new file mode 100644 index 00000000..a1ee2fe5 --- /dev/null +++ b/scripts/lib_apps.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# App enablement and editor selection helpers. + +enable_asusctl() { + local log="$1" + if command -v asusctl >/dev/null 2>&1; then + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = rog-control-center' "$OVERLAY_SA" || echo 'exec-once = rog-control-center' >>"$OVERLAY_SA" + fi +} + +enable_blueman() { + local log="$1" + if command -v blueman-applet >/dev/null 2>&1; then + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >>"$OVERLAY_SA" + fi +} + +enable_ags() { + local log="$1" + if command -v ags >/dev/null 2>&1; then + echo "${INFO:-[INFO]} AGS detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$log" + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >>"$OVERLAY_SA" + sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh + sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh + fi +} + +enable_quickshell() { + local log="$1" + if command -v qs >/dev/null 2>&1; then + echo "${INFO:-[INFO]} Quickshell detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$log" + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >>"$OVERLAY_SA" + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh + fi +} + +ensure_keybinds_init() { + local log="$1" + local OVERLAY_SA="config/hypr/configs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")" + if ! grep -qx 'exec-once = \$scriptsDir/KeybindsLayoutInit.sh' "$OVERLAY_SA"; then + echo 'exec-once = $scriptsDir/KeybindsLayoutInit.sh' >>"$OVERLAY_SA" + echo "${INFO:-[INFO]} Added KeybindsLayoutInit.sh to user Startup_Apps overlay" 2>&1 | tee -a "$log" + fi +} + +choose_default_editor() { + local log="$1" + local editor_set=0 + update_editor() { + local editor=$1 + sed -i "s/#env = EDITOR,.*/env = EDITOR,$editor #default editor/" config/hypr/UserConfigs/01-UserDefaults.conf + echo "${OK:-[OK]} Default editor set to ${MAGENTA:-}$editor${RESET:-}." 2>&1 | tee -a "$log" + } + if command -v nvim &>/dev/null; then + printf "${INFO:-[INFO]} ${MAGENTA:-}neovim${RESET:-} is detected as installed\n" + if ! read -r -p "${CAT:-[ACTION]} Do you want to make ${MAGENTA:-}neovim${RESET:-} the default editor? (y/N): " EDITOR_CHOICE /dev/null; then + printf "${INFO:-[INFO]} ${MAGENTA:-}vim${RESET:-} is detected as installed\n" + if read -r -p "${CAT:-[ACTION]} Do you want to make ${MAGENTA:-}vim${RESET:-} the default editor? (y/N): " EDITOR_CHOICE Date: Sun, 11 Jan 2026 03:37:07 -0500 Subject: Created lib_copy phase1/2 waybar,fastfetch,kitty,rofi,swaync Also btop,cava, hypr,ghostty, wezterm On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh new file: scripts/lib_copy.sh --- copy.sh | 257 ++++------------------------------------------------ scripts/lib_copy.sh | 141 ++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 241 deletions(-) create mode 100644 scripts/lib_copy.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 11a6223b..8d143800 100755 --- a/copy.sh +++ b/copy.sh @@ -5,7 +5,7 @@ # Handles interactive prompts, backups/restores, per-app tweaks, and express mode. # # Layout (high-level; future modularization targets): -# - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh, lib_apps.sh). +# - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh, lib_apps.sh, lib_copy.sh). # - Version helpers and CLI parsing (install/upgrade/express). # - Safety checks (non-root), banners/notices. # - Environment/distro checks and warnings. @@ -14,19 +14,18 @@ # - Workflow selection effects (express vs standard). # - Backup/restore helpers (in scripts/lib_backup.sh). # - App enablement/editor selection (lib_apps.sh). -# - Copy phases: +# - Copy phases (lib_copy.sh): # * Part 1: fastfetch/kitty/rofi/swaync (prompted replace). # * Waybar special handling (symlinks, configs/styles restore). -# * Part 2: other configs (btop, cava, hypr, etc.). -# * App-specific installs (ghostty, wezterm, ags, quickshell). +# * Part 2: other configs (btop, cava, hypr, etc.) + ghostty/wezterm installs. # - UserConfigs/UserScripts and hypr file restores. # - Wallpaper handling (default + optional 1GB pack). # - Backup cleanup (auto in express). # - Final symlinks (waybar) and wallust init. # # Next modular step: -# Split copy phases into dedicated helpers (phase1, waybar, phase2) and consider -# moving ghostty/wezterm install logic into lib_apps.sh. +# Move ghostty/wezterm install logic into lib_apps.sh (optional) and consider +# breaking user restore logic into helpers for clarity. clear wallpaper=$HOME/.config/hypr/wallpaper_effects/.wallpaper_current @@ -56,6 +55,7 @@ BACKUP_HELPER="$SCRIPT_DIR/scripts/lib_backup.sh" DETECT_HELPER="$SCRIPT_DIR/scripts/lib_detect.sh" PROMPTS_HELPER="$SCRIPT_DIR/scripts/lib_prompts.sh" APPS_HELPER="$SCRIPT_DIR/scripts/lib_apps.sh" +COPY_HELPER="$SCRIPT_DIR/scripts/lib_copy.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" @@ -88,6 +88,13 @@ else echo "${ERROR} Apps helper not found at $APPS_HELPER. Exiting." exit 1 fi +if [ -f "$COPY_HELPER" ]; then + # shellcheck source=./scripts/lib_copy.sh + . "$COPY_HELPER" +else + echo "${ERROR} Copy helper not found at $COPY_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -346,244 +353,12 @@ if [ ! -d "$HOME/.config" ]; then fi printf "${INFO} - copying dotfiles ${SKY_BLUE}first${RESET} part\n" -# Config directories which will ask the user whether to replace or not -DIRS="fastfetch kitty rofi swaync" - -for DIR2 in $DIRS; do - DIRPATH="$HOME/.config/$DIR2" - - if [ -d "$DIRPATH" ]; then - while true; do - printf "\n${INFO} Found ${YELLOW}$DIR2${RESET} config found in ~/.config/\n" - echo -n "${CAT} Do you want to replace ${YELLOW}$DIR2${RESET} config? (y/n): " - read DIR1_CHOICE - - case "$DIR1_CHOICE" in - [Yy]*) - BACKUP_DIR=$(get_backup_dirname) - # Backup the existing directory - mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" - - # Copy the new config - cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$LOG" - echo -e "${OK} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$LOG" - - # Restoring rofi themes directory unique themes - if [ "$DIR2" = "rofi" ]; then - if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then - for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do - [ -e "$file" ] || continue # Skip if no files are found - echo "Copying $file to $HOME/.config/rofi/themes/" >>"$LOG" - cp -n "$file" "$HOME/.config/rofi/themes/" >>"$LOG" 2>&1 - done || true - fi - - # restoring global 0-shared-fonts.rasi - if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then - echo "Restoring $DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi to $HOME/.config/rofi/" >>"$LOG" - cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >>"$LOG" 2>&1 - fi - - fi - - break - ;; - [Nn]*) - echo -e "${NOTE} - Skipping ${YELLOW}$DIR2${RESET}" 2>&1 | tee -a "$LOG" - break - ;; - *) - echo -e "${WARN} - Invalid choice. Please enter Y or N." - ;; - esac - done - else - # Copy new config if directory does not exist - cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$LOG" - echo -e "${OK} - Copy completed for ${YELLOW}$DIR2${RESET}" 2>&1 | tee -a "$LOG" - fi -done - +copy_phase1 "$LOG" printf "\n%.0s" {1..1} - -# for waybar special part since it contains symlink -DIRW="waybar" -DIRPATHw="$HOME/.config/$DIRW" -if [ -d "$DIRPATHw" ]; then - while true; do - echo -n "${CAT} Do you want to replace ${YELLOW}$DIRW${RESET} config? (y/n): " - read DIR1_CHOICE - - case "$DIR1_CHOICE" in - [Yy]*) - BACKUP_DIR=$(get_backup_dirname) - cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" - - # Remove the old $DIRPATHw and copy the new one - rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" - - # Step 1: Handle waybar symlinks - for file in "config" "style.css"; do - symlink="$DIRPATHw-backup-$BACKUP_DIR/$file" - target_file="$DIRPATHw/$file" - - if [ -L "$symlink" ]; then - symlink_target=$(readlink "$symlink") - if [ -f "$symlink_target" ]; then - rm -f "$target_file" && cp -f "$symlink_target" "$target_file" - echo -e "${NOTE} - Copied $file as a regular file." - else - echo -e "${WARN} - Symlink target for $file does not exist." - fi - fi - done - - # Step 2: Copy non-existing directories and files under waybar/configs - for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do - [ -e "$dir" ] || continue # Skip if no files are found - if [ -d "$dir" ]; then - target_dir="$HOME/.config/waybar/configs/$(basename "$dir")" - if [ ! -d "$target_dir" ]; then - echo "Copying directory $dir to $HOME/.config/waybar/configs/" >>"$LOG" - cp -r "$dir" "$HOME/.config/waybar/configs/" - else - echo "Directory $target_dir already exists. Skipping." >>"$LOG" - fi - fi - done - - for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do - [ -e "$file" ] || continue - target_file="$HOME/.config/waybar/configs/$(basename "$file")" - if [ ! -e "$target_file" ]; then - echo "Copying $file to $HOME/.config/waybar/configs/" >>"$LOG" - cp "$file" "$HOME/.config/waybar/configs/" - else - echo "File $target_file already exists. Skipping." >>"$LOG" - fi - done || true - - # Step 3: Copy unique files in waybar/style - for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do - [ -e "$file" ] || continue - - if [ -d "$file" ]; then - target_dir="$HOME/.config/waybar/style/$(basename "$file")" - if [ ! -d "$target_dir" ]; then - echo "Copying directory $file to $HOME/.config/waybar/style/" >>"$LOG" - cp -r "$file" "$HOME/.config/waybar/style/" - else - echo "Directory $target_dir already exists. Skipping." >>"$LOG" - fi - else - target_file="$HOME/.config/waybar/style/$(basename "$file")" - if [ ! -e "$target_file" ]; then - echo "Copying file $file to $HOME/.config/waybar/style/" >>"$LOG" - cp "$file" "$HOME/.config/waybar/style/" - else - echo "File $target_file already exists. Skipping." >>"$LOG" - fi - fi - done || true - - # Step 4: restore Modules_Extras - BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules" - if [ -f "$BACKUP_FILEw" ]; then - cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules" - fi - - break - ;; - [Nn]*) - echo -e "${NOTE} - Skipping ${YELLOW}$DIRW${RESET} config replacement." 2>&1 | tee -a "$LOG" - break - ;; - *) - echo -e "${WARN} - Invalid choice. Please enter Y or N." - ;; - esac - done -else - cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" - echo -e "${OK} - Copy completed for ${YELLOW}$DIRW${RESET}" 2>&1 | tee -a "$LOG" -fi - +copy_waybar "$LOG" printf "\n%.0s" {1..1} - printf "${INFO} - Copying dotfiles ${SKY_BLUE}second${RESET} part\n" - -# Check if the config directory exists -if [ ! -d "config" ]; then - echo "${ERROR} - The 'config' directory does not exist." - exit 1 -fi - -DIR="btop cava hypr Kvantum qt5ct qt6ct swappy wallust wlogout" - -for DIR_NAME in $DIR; do - DIRPATH="$HOME/.config/$DIR_NAME" - - # Backup the existing directory if it exists - if [ -d "$DIRPATH" ]; then - echo -e "\n${NOTE} - Config for ${YELLOW}$DIR_NAME${RESET} found, attempting to back up." - BACKUP_DIR=$(get_backup_dirname) - - # Backup the existing directory - mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - if [ $? -eq 0 ]; then - echo -e "${NOTE} - Backed up $DIR_NAME to $DIRPATH-backup-$BACKUP_DIR." - else - echo "${ERROR} - Failed to back up $DIR_NAME." - exit 1 - fi - fi - - # Copy the new config - if [ -d "config/$DIR_NAME" ]; then - cp -r "config/$DIR_NAME/" "$HOME/.config/$DIR_NAME" 2>&1 | tee -a "$LOG" - if [ $? -eq 0 ]; then - echo "${OK} - Copy of config for ${YELLOW}$DIR_NAME${RESET} completed!" - else - echo "${ERROR} - Failed to copy $DIR_NAME." - exit 1 - fi - else - echo "${ERROR} - Directory config/$DIR_NAME does not exist to copy." - fi -done - -# Install Ghostty config -GHOSTTY_SRC="config/ghostty/ghostty.config" -GHOSTTY_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" -GHOSTTY_DEST="$GHOSTTY_DIR/config" - -if [ -f "$GHOSTTY_SRC" ]; then - mkdir -p "$GHOSTTY_DIR" - install -m 0644 "$GHOSTTY_SRC" "$GHOSTTY_DEST" 2>&1 | tee -a "$LOG" - echo "${OK} - Installed Ghostty config to ${MAGENTA}$GHOSTTY_DEST${RESET}" 2>&1 | tee -a "$LOG" - # Normalize existing wallust.conf palette syntax if present (convert ':' to '=') - if [ -f "$GHOSTTY_DIR/wallust.conf" ]; then - sed -i -E 's/^(\s*palette\s*=\s*)([0-9]{1,2}):/\1\2=/' "$GHOSTTY_DIR/wallust.conf" 2>&1 | tee -a "$LOG" || true - fi -else - echo "${ERROR} - $GHOSTTY_SRC not found; skipping Ghostty config install." 2>&1 | tee -a "$LOG" -fi - -# Install WezTerm config -WEZTERM_SRC="config/wezterm/wezterm.lua" -WEZTERM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/wezterm" -WEZTERM_DEST="$WEZTERM_DIR/wezterm.lua" - -if [ -f "$WEZTERM_SRC" ]; then - mkdir -p "$WEZTERM_DIR" - install -m 0644 "$WEZTERM_SRC" "$WEZTERM_DEST" 2>&1 | tee -a "$LOG" - echo "${OK} - Installed WezTerm config to ${MAGENTA}$WEZTERM_DEST${RESET}" 2>&1 | tee -a "$LOG" -else - echo "${ERROR} - $WEZTERM_SRC not found; skipping WezTerm config install." 2>&1 | tee -a "$LOG" -fi - +copy_phase2 "$LOG" printf "\\n%.0s" {1..1} # ags config diff --git a/scripts/lib_copy.sh b/scripts/lib_copy.sh new file mode 100644 index 00000000..e449d668 --- /dev/null +++ b/scripts/lib_copy.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# Copy helpers split into phases to keep copy.sh lean. + +copy_phase1() { + local log="$1" + local dirs="fastfetch kitty rofi swaync" + for DIR2 in $dirs; do + local DIRPATH="$HOME/.config/$DIR2" + if [ -d "$DIRPATH" ]; then + while true; do + printf "\n${INFO:-[INFO]} Found ${YELLOW:-}$DIR2${RESET:-} config found in ~/.config/\n" + echo -n "${CAT:-[ACTION]} Do you want to replace ${YELLOW:-}$DIR2${RESET:-} config? (y/n): " + read DIR1_CHOICE + case "$DIR1_CHOICE" in + [Yy]*) BACKUP_DIR=$(get_backup_dirname) + mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$log" + echo -e "${NOTE:-[NOTE]} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$log" + cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$log" + echo -e "${OK:-[OK]} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$log" + if [ "$DIR2" = "rofi" ]; then + if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then + for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do + [ -e "$file" ] || continue + cp -n "$file" "$HOME/.config/rofi/themes/" >>"$log" 2>&1 || true + done || true + fi + if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then + cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >>"$log" 2>&1 + fi + fi + break ;; + [Nn]*) echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIR2${RESET:-}" 2>&1 | tee -a "$log"; break ;; + *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;; + esac + done + else + cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$log" + echo -e "${OK:-[OK]} - Copy completed for ${YELLOW:-}$DIR2${RESET:-}" 2>&1 | tee -a "$log" + fi + done +} + +copy_waybar() { + local log="$1" + local DIRW="waybar" + local DIRPATHw="$HOME/.config/$DIRW" + if [ -d "$DIRPATHw" ]; then + while true; do + echo -n "${CAT:-[ACTION]} Do you want to replace ${YELLOW:-}$DIRW${RESET:-} config? (y/n): " + read DIR1_CHOICE + case "$DIR1_CHOICE" in + [Yy]*) BACKUP_DIR=$(get_backup_dirname) + cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$log" + echo -e "${NOTE:-[NOTE]} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$log" + rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$log" + for file in "config" "style.css"; do + symlink="$DIRPATHw-backup-$BACKUP_DIR/$file" + target_file="$DIRPATHw/$file" + if [ -L "$symlink" ]; then + symlink_target=$(readlink "$symlink") + if [ -f "$symlink_target" ]; then + rm -f "$target_file" && cp -f "$symlink_target" "$target_file" + fi + fi + done + for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do + [ -e "$dir" ] || continue + if [ -d "$dir" ]; then + target_dir="$HOME/.config/waybar/configs/$(basename "$dir")" + [ -d "$target_dir" ] || cp -r "$dir" "$HOME/.config/waybar/configs/" + fi + done + for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do + [ -e "$file" ] || continue + target_file="$HOME/.config/waybar/configs/$(basename "$file")" + [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/configs/" + done || true + for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do + [ -e "$file" ] || continue + if [ -d "$file" ]; then + target_dir="$HOME/.config/waybar/style/$(basename "$file")" + [ -d "$target_dir" ] || cp -r "$file" "$HOME/.config/waybar/style/" + else + target_file="$HOME/.config/waybar/style/$(basename "$file")" + [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/style/" + fi + done || true + BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules" + [ -f "$BACKUP_FILEw" ] && cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules" + break ;; + [Nn]*) echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIRW${RESET:-} config replacement." 2>&1 | tee -a "$log"; break ;; + *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;; + esac + done + else + cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$log" + echo -e "${OK:-[OK]} - Copy completed for ${YELLOW:-}$DIRW${RESET:-}" 2>&1 | tee -a "$log" + fi +} + +copy_phase2() { + local log="$1" + local DIR="btop cava hypr Kvantum qt5ct qt6ct swappy wallust wlogout" + for DIR_NAME in $DIR; do + local DIRPATH="$HOME/.config/$DIR_NAME" + if [ -d "$DIRPATH" ]; then + echo -e "\n${NOTE:-[NOTE]} - Config for ${YELLOW:-}$DIR_NAME${RESET:-} found, attempting to back up." + BACKUP_DIR=$(get_backup_dirname) + mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$log" + fi + if [ -d "config/$DIR_NAME" ]; then + cp -r "config/$DIR_NAME/" "$HOME/.config/$DIR_NAME" 2>&1 | tee -a "$log" + echo "${OK:-[OK]} - Copy of config for ${YELLOW:-}$DIR_NAME${RESET:-} completed!" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - Directory config/$DIR_NAME does not exist to copy." 2>&1 | tee -a "$log" + fi + done + # Ghostty + local GHOSTTY_SRC="config/ghostty/ghostty.config" + local GHOSTTY_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" + local GHOSTTY_DEST="$GHOSTTY_DIR/config" + if [ -f "$GHOSTTY_SRC" ]; then + mkdir -p "$GHOSTTY_DIR" + install -m 0644 "$GHOSTTY_SRC" "$GHOSTTY_DEST" 2>&1 | tee -a "$log" + if [ -f "$GHOSTTY_DIR/wallust.conf" ]; then + sed -i -E 's/^(\\s*palette\\s*=\\s*)([0-9]{1,2}):/\\1\\2=/' "$GHOSTTY_DIR/wallust.conf" 2>&1 | tee -a "$log" || true + fi + else + echo "${ERROR:-[ERROR]} - $GHOSTTY_SRC not found; skipping Ghostty config install." 2>&1 | tee -a "$log" + fi + # WezTerm + local WEZTERM_SRC="config/wezterm/wezterm.lua" + local WEZTERM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/wezterm" + local WEZTERM_DEST="$WEZTERM_DIR/wezterm.lua" + if [ -f "$WEZTERM_SRC" ]; then + mkdir -p "$WEZTERM_DIR" + install -m 0644 "$WEZTERM_SRC" "$WEZTERM_DEST" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - $WEZTERM_SRC not found; skipping WezTerm config install." 2>&1 | tee -a "$log" + fi +} -- cgit v1.2.3 From a8415be54a1cbb194a8fd915e570681f13cdce92 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 20:01:40 -0500 Subject: Moved ghostty/wezterm config file process out of copy.sh On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh modified: scripts/lib_apps.sh modified: scripts/lib_copy.sh --- copy.sh | 2 +- scripts/lib_apps.sh | 29 +++++++++++++++++++++++++++++ scripts/lib_copy.sh | 24 +----------------------- 3 files changed, 31 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 8d143800..398f72d0 100755 --- a/copy.sh +++ b/copy.sh @@ -24,7 +24,7 @@ # - Final symlinks (waybar) and wallust init. # # Next modular step: -# Move ghostty/wezterm install logic into lib_apps.sh (optional) and consider +# Ghostty/WezTerm install logic lives in lib_apps.sh now; consider # breaking user restore logic into helpers for clarity. clear diff --git a/scripts/lib_apps.sh b/scripts/lib_apps.sh index a1ee2fe5..562e5c5b 100644 --- a/scripts/lib_apps.sh +++ b/scripts/lib_apps.sh @@ -57,6 +57,35 @@ ensure_keybinds_init() { fi } +install_terminal_configs() { + local log="$1" + + # Ghostty + local GHOSTTY_SRC="config/ghostty/ghostty.config" + local GHOSTTY_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" + local GHOSTTY_DEST="$GHOSTTY_DIR/config" + if [ -f "$GHOSTTY_SRC" ]; then + mkdir -p "$GHOSTTY_DIR" + install -m 0644 "$GHOSTTY_SRC" "$GHOSTTY_DEST" 2>&1 | tee -a "$log" + if [ -f "$GHOSTTY_DIR/wallust.conf" ]; then + sed -i -E 's/^(\\s*palette\\s*=\\s*)([0-9]{1,2}):/\\1\\2=/' "$GHOSTTY_DIR/wallust.conf" 2>&1 | tee -a "$log" || true + fi + else + echo "${ERROR:-[ERROR]} - $GHOSTTY_SRC not found; skipping Ghostty config install." 2>&1 | tee -a "$log" + fi + + # WezTerm + local WEZTERM_SRC="config/wezterm/wezterm.lua" + local WEZTERM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/wezterm" + local WEZTERM_DEST="$WEZTERM_DIR/wezterm.lua" + if [ -f "$WEZTERM_SRC" ]; then + mkdir -p "$WEZTERM_DIR" + install -m 0644 "$WEZTERM_SRC" "$WEZTERM_DEST" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - $WEZTERM_SRC not found; skipping WezTerm config install." 2>&1 | tee -a "$log" + fi +} + choose_default_editor() { local log="$1" local editor_set=0 diff --git a/scripts/lib_copy.sh b/scripts/lib_copy.sh index e449d668..7d76cfc4 100644 --- a/scripts/lib_copy.sh +++ b/scripts/lib_copy.sh @@ -115,27 +115,5 @@ copy_phase2() { echo "${ERROR:-[ERROR]} - Directory config/$DIR_NAME does not exist to copy." 2>&1 | tee -a "$log" fi done - # Ghostty - local GHOSTTY_SRC="config/ghostty/ghostty.config" - local GHOSTTY_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" - local GHOSTTY_DEST="$GHOSTTY_DIR/config" - if [ -f "$GHOSTTY_SRC" ]; then - mkdir -p "$GHOSTTY_DIR" - install -m 0644 "$GHOSTTY_SRC" "$GHOSTTY_DEST" 2>&1 | tee -a "$log" - if [ -f "$GHOSTTY_DIR/wallust.conf" ]; then - sed -i -E 's/^(\\s*palette\\s*=\\s*)([0-9]{1,2}):/\\1\\2=/' "$GHOSTTY_DIR/wallust.conf" 2>&1 | tee -a "$log" || true - fi - else - echo "${ERROR:-[ERROR]} - $GHOSTTY_SRC not found; skipping Ghostty config install." 2>&1 | tee -a "$log" - fi - # WezTerm - local WEZTERM_SRC="config/wezterm/wezterm.lua" - local WEZTERM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/wezterm" - local WEZTERM_DEST="$WEZTERM_DIR/wezterm.lua" - if [ -f "$WEZTERM_SRC" ]; then - mkdir -p "$WEZTERM_DIR" - install -m 0644 "$WEZTERM_SRC" "$WEZTERM_DEST" 2>&1 | tee -a "$log" - else - echo "${ERROR:-[ERROR]} - $WEZTERM_SRC not found; skipping WezTerm config install." 2>&1 | tee -a "$log" - fi + install_terminal_configs "$log" } -- cgit v1.2.3 From a7c359e377d6daed4af9158ea0cc915d804ea359 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 11 Jan 2026 21:13:07 -0500 Subject: Moved UserScripts/UserConfigs restore function to lib_copy helper copy.sh is nearly 50% smaller now a little over 600 lines now down from over 1200 at the start On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh modified: scripts/lib_copy.sh --- copy.sh | 256 +--------------------------------------------------- scripts/lib_copy.sh | 243 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 251 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 398f72d0..c36e73e9 100755 --- a/copy.sh +++ b/copy.sh @@ -462,263 +462,17 @@ if command -v qs >/dev/null 2>&1; then fi printf "\n%.0s" {1..1} -# Restore automatically Animations and Monitor-Profiles -# including monitors.conf and workspaces.conf -HYPR_DIR="$HOME/.config/hypr" -BACKUP_DIR=$(get_backup_dirname) -BACKUP_HYPR_PATH="$HYPR_DIR-backup-$BACKUP_DIR" - -if [ -d "$BACKUP_HYPR_PATH" ]; then - if [ "$EXPRESS_MODE" -eq 1 ]; then - echo "${NOTE} Express mode: skipping automatic restoration of animations and monitor profiles." 2>&1 | tee -a "$LOG" - else - echo -e "\n${NOTE} Restoring ${SKY_BLUE}Animations & Monitor Profiles${RESET} directories into ${YELLOW}$HYPR_DIR${RESET}..." - - DIR_B=("Monitor_Profiles" "animations" "wallpaper_effects") - # Restore directories automatically - for DIR_RESTORE in "${DIR_B[@]}"; do - BACKUP_SUBDIR="$BACKUP_HYPR_PATH/$DIR_RESTORE" - if [ -d "$BACKUP_SUBDIR" ]; then - cp -r "$BACKUP_SUBDIR" "$HYPR_DIR/" - echo "${OK} - Restored directory: ${MAGENTA}$DIR_RESTORE${RESET}" 2>&1 | tee -a "$LOG" - fi - done - - # Restore files automatically - FILE_B=("monitors.conf" "workspaces.conf") - for FILE_RESTORE in "${FILE_B[@]}"; do - BACKUP_FILE="$BACKUP_HYPR_PATH/$FILE_RESTORE" - - if [ -f "$BACKUP_FILE" ]; then - cp "$BACKUP_FILE" "$HYPR_DIR/$FILE_RESTORE" - echo "${OK} - Restored file: ${MAGENTA}$FILE_RESTORE${RESET}" 2>&1 | tee -a "$LOG" - fi - done - fi -fi - +restore_hypr_assets "$LOG" "$EXPRESS_MODE" printf "\n%.0s" {1..1} -# Restoring UserConfigs and UserScripts -# Helper to extract overlay (additions) and optional disables from a previous user file compared to vendor base -compose_overlay_from_backup() { - local type="$1" # startup|windowrules - local base_file="$2" - local old_user_file="$3" - local new_user_file="$4" - local disable_file="$5" - - mkdir -p "$(dirname "$new_user_file")" - : >"$new_user_file" - : >"$disable_file" - - if [ "$type" = "startup" ]; then - # additions: exec-once lines present in old user but not in base - grep -E '^\s*exec-once\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.exec" - grep -E '^\s*exec-once\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.exec" - comm -23 "$old_user_file.tmp.exec" "$base_file.tmp.exec" >"$new_user_file" - # treat commented exec-once in old user as disables - grep -E '^\s*#\s*exec-once\s*=' "$old_user_file" | - sed -E 's/^\s*#\s*exec-once\s*=\s*//' | - sed -E 's/^\s+//;s/\s+$//' | - grep -Ev '^\$scriptsDir/KeybindsLayoutInit\.sh$' | - sort -u >"$disable_file" - rm -f "$old_user_file.tmp.exec" "$base_file.tmp.exec" - elif [ "$type" = "windowrules" ]; then - # additions - grep -E '^(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.rules" - grep -E '^(windowrule|layerrule)\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.rules" - comm -23 "$old_user_file.tmp.rules" "$base_file.tmp.rules" >"$new_user_file" - # disables: lines commented in old user - grep -E '^\s*#\s*(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s*#\s*//' | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$disable_file" - rm -f "$old_user_file.tmp.rules" "$base_file.tmp.rules" - fi -} - - -DIRH="hypr" -DIRPATH="$HOME/.config/$DIRH" -BACKUP_DIR=$(get_backup_dirname) -BACKUP_DIR_PATH="$DIRPATH-backup-$BACKUP_DIR/UserConfigs" - -if [ -z "$BACKUP_DIR" ]; then - echo "${ERROR} - Backup directory name is empty. Exiting." - exit 1 -fi - -if [ -d "$BACKUP_DIR_PATH" ] && [ "$EXPRESS_MODE" -eq 1 ]; then - echo "${NOTE} Express mode: skipping UserConfigs restoration prompts." 2>&1 | tee -a "$LOG" -fi - -if [ -d "$BACKUP_DIR_PATH" ] && [ "$EXPRESS_MODE" -eq 0 ]; then - # Detect version - VERSION_FILE=$(find "$DIRPATH" -maxdepth 1 -name "v*.*.*" | head -n 1) - CURRENT_VERSION="999.9.9" - if [ -n "$VERSION_FILE" ]; then - CURRENT_VERSION=$(basename "$VERSION_FILE" | sed 's/^v//') - fi - - TARGET_VERSION="2.3.19" - - echo -e "${NOTE} Restoring previous ${MAGENTA}User-Configs${RESET}... " - print_color $WARNING " - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - NOTES for RESTORING PREVIOUS CONFIGS - █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ - - The 'UserConfigs' directory is for all your personal settings. - Files in this directory will override the default configurations, - so your customizations are not lost when you update. - " - - if version_gte "$CURRENT_VERSION" "$TARGET_VERSION"; then - # NEW BEHAVIOR (>= 2.3.19) - Bulk Restore - echo -n "${CAT} Do you want to restore your previous UserConfigs directory? (Y/n): " - read -r restore_userconfigs_dir - - if [[ "$restore_userconfigs_dir" != [Nn]* ]]; then - echo "${NOTE} Restoring UserConfigs directory..." 2>&1 | tee -a "$LOG" - # Use rsync to copy contents, overwriting existing files. - rsync -a "$BACKUP_DIR_PATH/" "$DIRPATH/UserConfigs/" 2>&1 | tee -a "$LOG" - echo "${OK} - UserConfigs directory restored." 2>&1 | tee -a "$LOG" - else - echo "${NOTE} - Skipped restoring UserConfigs." 2>&1 | tee -a "$LOG" - fi - - else - # OLD BEHAVIOR (<= 2.3.18) - Selective Restore - echo -e "${NOTE} Detected version ${YELLOW}v$CURRENT_VERSION${RESET} (older than v$TARGET_VERSION). Using legacy restoration mode." - - FILES_TO_RESTORE=( - "01-UserDefaults.conf" - "ENVariables.conf" - "LaptopDisplay.conf" - "Laptops.conf" - "Startup_Apps.conf" - "UserDecorations.conf" - "UserAnimations.conf" - "UserKeybinds.conf" - "UserSettings.conf" - "WindowRules.conf" - ) - - for FILE_NAME in "${FILES_TO_RESTORE[@]}"; do - BACKUP_FILE="$BACKUP_DIR_PATH/$FILE_NAME" - if [ -f "$BACKUP_FILE" ]; then - # Special handling for Startup_Apps.conf and WindowRules.conf - if [ "$FILE_NAME" = "Startup_Apps.conf" ]; then - compose_overlay_from_backup "startup" "$DIRPATH/configs/Startup_Apps.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/Startup_Apps.conf" "$DIRPATH/UserConfigs/Startup_Apps.disable" - echo "${OK} - Migrated overlay for ${YELLOW}$FILE_NAME${RESET}" 2>&1 | tee -a "$LOG" - continue - fi - if [ "$FILE_NAME" = "WindowRules.conf" ]; then - compose_overlay_from_backup "windowrules" "$DIRPATH/configs/WindowRules.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/WindowRules.conf" "$DIRPATH/UserConfigs/WindowRules.disable" - echo "${OK} - Migrated overlay for ${YELLOW}$FILE_NAME${RESET}" 2>&1 | tee -a "$LOG" - continue - fi - - printf "\n${INFO} Found ${YELLOW}$FILE_NAME${RESET} in hypr backup...\n" - echo -n "${CAT} Do you want to restore ${YELLOW}$FILE_NAME${RESET} from backup? (Y/n): " - read file_restore - - if [[ "$file_restore" != [Nn]* ]]; then - if cp "$BACKUP_FILE" "$DIRPATH/UserConfigs/$FILE_NAME"; then - echo "${OK} - $FILE_NAME restored!" 2>&1 | tee -a "$LOG" - else - echo "${ERROR} - Failed to restore $FILE_NAME!" 2>&1 | tee -a "$LOG" - fi - else - echo "${NOTE} - Skipped restoring $FILE_NAME." 2>&1 | tee -a "$LOG" - fi - fi - done - fi -fi - +restore_user_configs "$LOG" "$EXPRESS_MODE" printf "\n%.0s" {1..1} -# Restoring previous UserScripts -DIRSH="hypr" -SCRIPTS_TO_RESTORE=( - "RofiBeats.sh" - "Weather.py" - "Weather.sh" -) - -DIRSHPATH="$HOME/.config/$DIRSH" -BACKUP_DIR_PATH_S="$DIRSHPATH-backup-$BACKUP_DIR/UserScripts" - -if [ -d "$BACKUP_DIR_PATH_S" ] && [ "$EXPRESS_MODE" -eq 1 ]; then - echo "${NOTE} Express mode: skipping UserScripts restoration prompts." 2>&1 | tee -a "$LOG" -fi - -if [ -d "$BACKUP_DIR_PATH_S" ] && [ "$EXPRESS_MODE" -eq 0 ]; then - echo -e "${NOTE} Restoring previous ${MAGENTA}User-Scripts${RESET}..." - - for SCRIPT_NAME in "${SCRIPTS_TO_RESTORE[@]}"; do - BACKUP_SCRIPT="$BACKUP_DIR_PATH_S/$SCRIPT_NAME" - - if [ -f "$BACKUP_SCRIPT" ]; then - printf "\n${INFO} Found ${YELLOW}$SCRIPT_NAME${RESET} in hypr backup...\n" - echo -n "${CAT} Do you want to restore ${YELLOW}$SCRIPT_NAME${RESET} from backup? (y/N): " - read script_restore - - if [[ "$script_restore" == [Yy]* ]]; then - if cp "$BACKUP_SCRIPT" "$DIRSHPATH/UserScripts/$SCRIPT_NAME"; then - echo "${OK} - $SCRIPT_NAME restored!" 2>&1 | tee -a "$LOG" - else - echo "${ERROR} - Failed to restore $SCRIPT_NAME!" 2>&1 | tee -a "$LOG" - fi - else - echo "${NOTE} - Skipped restoring $SCRIPT_NAME." 2>&1 | tee -a "$LOG" - fi - fi - done -fi - +restore_user_scripts "$LOG" "$EXPRESS_MODE" printf "\n%.0s" {1..1} -# restoring some files in ~/.config/hypr -DIR_H="hypr" -FILES_2_RESTORE=( - "hyprlock.conf" - "hypridle.conf" -) - -DIRPATH="$HOME/.config/$DIR_H" -BACKUP_DIR=$(get_backup_dirname) -BACKUP_DIR_PATH_F="$DIRPATH-backup-$BACKUP_DIR" - -if [ -d "$BACKUP_DIR_PATH_F" ] && [ "$EXPRESS_MODE" -eq 1 ]; then - echo "${NOTE} Express mode: skipping individual hypr file restoration prompts." 2>&1 | tee -a "$LOG" -fi - -if [ -d "$BACKUP_DIR_PATH_F" ] && [ "$EXPRESS_MODE" -eq 0 ]; then - echo -e "${NOTE} Restoring some files in ${MAGENTA}$HOME/.config/hypr directory${RESET}..." - - for FILE_RESTORE in "${FILES_2_RESTORE[@]}"; do - BACKUP_FILE="$BACKUP_DIR_PATH_F/$FILE_RESTORE" - - if [ -f "$BACKUP_FILE" ]; then - echo -e "\n${INFO} Found ${YELLOW}$FILE_RESTORE${RESET} in hypr backup..." - echo -n "${CAT} Do you want to restore ${YELLOW}$FILE_RESTORE${RESET} from backup? (y/N): " - read file2restore - - if [[ "$file2restore" == [Yy]* ]]; then - if cp "$BACKUP_FILE" "$DIRPATH/$FILE_RESTORE"; then - echo "${OK} - $FILE_RESTORE restored!" 2>&1 | tee -a "$LOG" - else - echo "${ERROR} - Failed to restore $FILE_RESTORE!" 2>&1 | tee -a "$LOG" - fi - else - echo "${NOTE} - Skipped restoring $FILE_RESTORE." 2>&1 | tee -a "$LOG" - fi - else - echo "${ERROR} - Backup file $BACKUP_FILE does not exist." - fi - done -fi - +restore_hypr_files "$LOG" "$EXPRESS_MODE" +printf "\n%.0s" {1..1} printf "\n%.0s" {1..1} # Define the target directory for rofi themes diff --git a/scripts/lib_copy.sh b/scripts/lib_copy.sh index 7d76cfc4..fa1231c5 100644 --- a/scripts/lib_copy.sh +++ b/scripts/lib_copy.sh @@ -117,3 +117,246 @@ copy_phase2() { done install_terminal_configs "$log" } + +# Restore Animations and Monitor Profiles plus key hypr files from backup +restore_hypr_assets() { + local log="$1" + local express_mode="$2" + + local HYPR_DIR="$HOME/.config/hypr" + local BACKUP_DIR + BACKUP_DIR=$(get_backup_dirname) + local BACKUP_HYPR_PATH="$HYPR_DIR-backup-$BACKUP_DIR" + + if [ -d "$BACKUP_HYPR_PATH" ]; then + if [ "$express_mode" -eq 1 ]; then + echo "${NOTE:-[NOTE]} Express mode: skipping automatic restoration of animations and monitor profiles." 2>&1 | tee -a "$log" + return + fi + + echo -e "\n${NOTE:-[NOTE]} Restoring ${SKY_BLUE:-}Animations & Monitor Profiles${RESET:-} into ${YELLOW:-}$HYPR_DIR${RESET:-}..." + + local DIR_B=("Monitor_Profiles" "animations" "wallpaper_effects") + for DIR_RESTORE in "${DIR_B[@]}"; do + local BACKUP_SUBDIR="$BACKUP_HYPR_PATH/$DIR_RESTORE" + if [ -d "$BACKUP_SUBDIR" ]; then + cp -r "$BACKUP_SUBDIR" "$HYPR_DIR/" 2>&1 | tee -a "$log" + echo "${OK:-[OK]} - Restored directory: ${MAGENTA:-}$DIR_RESTORE${RESET:-}" 2>&1 | tee -a "$log" + fi + done + + local FILE_B=("monitors.conf" "workspaces.conf") + for FILE_RESTORE in "${FILE_B[@]}"; do + local BACKUP_FILE="$BACKUP_HYPR_PATH/$FILE_RESTORE" + if [ -f "$BACKUP_FILE" ]; then + cp "$BACKUP_FILE" "$HYPR_DIR/$FILE_RESTORE" 2>&1 | tee -a "$log" + echo "${OK:-[OK]} - Restored file: ${MAGENTA:-}$FILE_RESTORE${RESET:-}" 2>&1 | tee -a "$log" + fi + done + fi +} + +# Helper to extract overlay additions/disables from previous user file vs base +compose_overlay_from_backup() { + local type="$1" # startup|windowrules + local base_file="$2" + local old_user_file="$3" + local new_user_file="$4" + local disable_file="$5" + + mkdir -p "$(dirname "$new_user_file")" + : >"$new_user_file" + : >"$disable_file" + + if [ "$type" = "startup" ]; then + grep -E '^\s*exec-once\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.exec" + grep -E '^\s*exec-once\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.exec" + comm -23 "$old_user_file.tmp.exec" "$base_file.tmp.exec" >"$new_user_file" + grep -E '^\s*#\s*exec-once\s*=' "$old_user_file" | + sed -E 's/^\s*#\s*exec-once\s*=\s*//' | + sed -E 's/^\s+//;s/\s+$//' | + grep -Ev '^\$scriptsDir/KeybindsLayoutInit\.sh$' | + sort -u >"$disable_file" + rm -f "$old_user_file.tmp.exec" "$base_file.tmp.exec" + elif [ "$type" = "windowrules" ]; then + grep -E '^(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.rules" + grep -E '^(windowrule|layerrule)\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.rules" + comm -23 "$old_user_file.tmp.rules" "$base_file.tmp.rules" >"$new_user_file" + grep -E '^\s*#\s*(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s*#\s*//' | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$disable_file" + rm -f "$old_user_file.tmp.rules" "$base_file.tmp.rules" + fi +} + +restore_user_configs() { + local log="$1" + local express_mode="$2" + + local DIRPATH="$HOME/.config/hypr" + local BACKUP_DIR + BACKUP_DIR=$(get_backup_dirname) + local BACKUP_DIR_PATH="$DIRPATH-backup-$BACKUP_DIR/UserConfigs" + + if [ -z "$BACKUP_DIR" ]; then + echo "${ERROR:-[ERROR]} - Backup directory name is empty. Exiting." 2>&1 | tee -a "$log" + exit 1 + fi + + if [ -d "$BACKUP_DIR_PATH" ] && [ "$express_mode" -eq 1 ]; then + echo "${NOTE:-[NOTE]} Express mode: skipping UserConfigs restoration prompts." 2>&1 | tee -a "$log" + return + fi + + if [ -d "$BACKUP_DIR_PATH" ] && [ "$express_mode" -eq 0 ]; then + local VERSION_FILE + VERSION_FILE=$(find "$DIRPATH" -maxdepth 1 -name "v*.*.*" | head -n 1) + local CURRENT_VERSION="999.9.9" + if [ -n "$VERSION_FILE" ]; then + CURRENT_VERSION=$(basename "$VERSION_FILE" | sed 's/^v//') + fi + + local TARGET_VERSION="2.3.19" + + echo -e "${NOTE:-[NOTE]} Restoring previous ${MAGENTA:-}User-Configs${RESET:-}... " 2>&1 | tee -a "$log" + printf "${WARNING:-}\ + █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█\n\ + NOTES for RESTORING PREVIOUS CONFIGS\n\ + █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\n\n\ + The 'UserConfigs' directory is for all your personal settings.\n\ + Files in this directory will override the default configurations,\n\ + so your customizations are not lost when you update.\n\ +" >&2 + + if version_gte "$CURRENT_VERSION" "$TARGET_VERSION"; then + read -r -p "${CAT:-[ACTION]} Do you want to restore your previous UserConfigs directory? (Y/n): " restore_userconfigs_dir + if [[ "$restore_userconfigs_dir" != [Nn]* ]]; then + echo "${NOTE:-[NOTE]} Restoring UserConfigs directory..." 2>&1 | tee -a "$log" + rsync -a "$BACKUP_DIR_PATH/" "$DIRPATH/UserConfigs/" 2>&1 | tee -a "$log" + echo "${OK:-[OK]} - UserConfigs directory restored." 2>&1 | tee -a "$log" + else + echo "${NOTE:-[NOTE]} - Skipped restoring UserConfigs." 2>&1 | tee -a "$log" + fi + else + echo -e "${NOTE:-[NOTE]} Detected version ${YELLOW:-}v$CURRENT_VERSION${RESET:-} (older than v$TARGET_VERSION). Using legacy restoration mode." 2>&1 | tee -a "$log" + + local FILES_TO_RESTORE=( + "01-UserDefaults.conf" + "ENVariables.conf" + "LaptopDisplay.conf" + "Laptops.conf" + "Startup_Apps.conf" + "UserDecorations.conf" + "UserAnimations.conf" + "UserKeybinds.conf" + "UserSettings.conf" + "WindowRules.conf" + ) + + for FILE_NAME in "${FILES_TO_RESTORE[@]}"; do + local BACKUP_FILE="$BACKUP_DIR_PATH/$FILE_NAME" + if [ -f "$BACKUP_FILE" ]; then + if [ "$FILE_NAME" = "Startup_Apps.conf" ]; then + compose_overlay_from_backup "startup" "$DIRPATH/configs/Startup_Apps.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/Startup_Apps.conf" "$DIRPATH/UserConfigs/Startup_Apps.disable" + echo "${OK:-[OK]} - Migrated overlay for ${YELLOW:-}$FILE_NAME${RESET:-}" 2>&1 | tee -a "$log" + continue + fi + if [ "$FILE_NAME" = "WindowRules.conf" ]; then + compose_overlay_from_backup "windowrules" "$DIRPATH/configs/WindowRules.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/WindowRules.conf" "$DIRPATH/UserConfigs/WindowRules.disable" + echo "${OK:-[OK]} - Migrated overlay for ${YELLOW:-}$FILE_NAME${RESET:-}" 2>&1 | tee -a "$log" + continue + fi + + printf "\n${INFO:-[INFO]} Found ${YELLOW:-}$FILE_NAME${RESET:-} in hypr backup...\n" + read -r -p "${CAT:-[ACTION]} Do you want to restore ${YELLOW:-}$FILE_NAME${RESET:-} from backup? (Y/n): " file_restore + + if [[ "$file_restore" != [Nn]* ]]; then + if cp "$BACKUP_FILE" "$DIRPATH/UserConfigs/$FILE_NAME"; then + echo "${OK:-[OK]} - $FILE_NAME restored!" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - Failed to restore $FILE_NAME!" 2>&1 | tee -a "$log" + fi + else + echo "${NOTE:-[NOTE]} - Skipped restoring $FILE_NAME." 2>&1 | tee -a "$log" + fi + fi + done + fi + fi +} + +restore_user_scripts() { + local log="$1" + local express_mode="$2" + + local DIRSHPATH="$HOME/.config/hypr" + local BACKUP_DIR + BACKUP_DIR=$(get_backup_dirname) + local BACKUP_DIR_PATH_S="$DIRSHPATH-backup-$BACKUP_DIR/UserScripts" + local SCRIPTS_TO_RESTORE=("RofiBeats.sh" "Weather.py" "Weather.sh") + + if [ -d "$BACKUP_DIR_PATH_S" ] && [ "$express_mode" -eq 1 ]; then + echo "${NOTE:-[NOTE]} Express mode: skipping UserScripts restoration prompts." 2>&1 | tee -a "$log" + return + fi + + if [ -d "$BACKUP_DIR_PATH_S" ] && [ "$express_mode" -eq 0 ]; then + echo -e "${NOTE:-[NOTE]} Restoring previous ${MAGENTA:-}User-Scripts${RESET:-}..." 2>&1 | tee -a "$log" + + for SCRIPT_NAME in "${SCRIPTS_TO_RESTORE[@]}"; do + local BACKUP_SCRIPT="$BACKUP_DIR_PATH_S/$SCRIPT_NAME" + if [ -f "$BACKUP_SCRIPT" ]; then + printf "\n${INFO:-[INFO]} Found ${YELLOW:-}$SCRIPT_NAME${RESET:-} in hypr backup...\n" + read -r -p "${CAT:-[ACTION]} Do you want to restore ${YELLOW:-}$SCRIPT_NAME${RESET:-} from backup? (y/N): " script_restore + + if [[ "$script_restore" == [Yy]* ]]; then + if cp "$BACKUP_SCRIPT" "$DIRSHPATH/UserScripts/$SCRIPT_NAME"; then + echo "${OK:-[OK]} - $SCRIPT_NAME restored!" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - Failed to restore $SCRIPT_NAME!" 2>&1 | tee -a "$log" + fi + else + echo "${NOTE:-[NOTE]} - Skipped restoring $SCRIPT_NAME." 2>&1 | tee -a "$log" + fi + fi + done + fi +} + +restore_hypr_files() { + local log="$1" + local express_mode="$2" + + local DIRPATH="$HOME/.config/hypr" + local BACKUP_DIR + BACKUP_DIR=$(get_backup_dirname) + local BACKUP_DIR_PATH_F="$DIRPATH-backup-$BACKUP_DIR" + local FILES_2_RESTORE=("hyprlock.conf" "hypridle.conf") + + if [ -d "$BACKUP_DIR_PATH_F" ] && [ "$express_mode" -eq 1 ]; then + echo "${NOTE:-[NOTE]} Express mode: skipping individual hypr file restoration prompts." 2>&1 | tee -a "$log" + return + fi + + if [ -d "$BACKUP_DIR_PATH_F" ] && [ "$express_mode" -eq 0 ]; then + echo -e "${NOTE:-[NOTE]} Restoring some files in ${MAGENTA:-}$HOME/.config/hypr directory${RESET:-}..." 2>&1 | tee -a "$log" + + for FILE_RESTORE in "${FILES_2_RESTORE[@]}"; do + local BACKUP_FILE="$BACKUP_DIR_PATH_F/$FILE_RESTORE" + if [ -f "$BACKUP_FILE" ]; then + echo -e "\n${INFO:-[INFO]} Found ${YELLOW:-}$FILE_RESTORE${RESET:-} in hypr backup..." + read -r -p "${CAT:-[ACTION]} Do you want to restore ${YELLOW:-}$FILE_RESTORE${RESET:-} from backup? (y/N): " file2restore + + if [[ "$file2restore" == [Yy]* ]]; then + if cp "$BACKUP_FILE" "$DIRPATH/$FILE_RESTORE"; then + echo "${OK:-[OK]} - $FILE_RESTORE restored!" 2>&1 | tee -a "$log" + else + echo "${ERROR:-[ERROR]} - Failed to restore $FILE_RESTORE!" 2>&1 | tee -a "$log" + fi + else + echo "${NOTE:-[NOTE]} - Skipped restoring $FILE_RESTORE." 2>&1 | tee -a "$log" + fi + else + echo "${ERROR:-[ERROR]} - Backup file $BACKUP_FILE does not exist." 2>&1 | tee -a "$log" + fi + done + fi +} -- cgit v1.2.3 From a988f706e0080cde8aad3966948ac68ea0075da7 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Mon, 12 Jan 2026 10:12:20 -0500 Subject: Added update dotfiles option to men On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh modified: scripts/copy_menu.sh new file: scripts/lib_update.sh --- copy.sh | 14 +++++++++ scripts/copy_menu.sh | 13 +++++--- scripts/lib_update.sh | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 scripts/lib_update.sh (limited to 'scripts') diff --git a/copy.sh b/copy.sh index 8df2532d..def8b209 100755 --- a/copy.sh +++ b/copy.sh @@ -6,6 +6,7 @@ # # Layout (high-level; future modularization targets): # - Constants/colors, helper sourcing (copy_menu.sh, lib_backup.sh, lib_detect.sh, lib_prompts.sh, lib_apps.sh, lib_copy.sh). +# - New update helper (lib_update.sh) provides menu-driven repo update: verifies Hyprland-Dots root, stashes changes, git pull, logs, summarizes, waits for keypress. # - Version helpers and CLI parsing (install/upgrade/express). # - Safety checks (non-root), banners/notices. # - Environment/distro checks and warnings. @@ -57,6 +58,7 @@ DETECT_HELPER="$SCRIPT_DIR/scripts/lib_detect.sh" PROMPTS_HELPER="$SCRIPT_DIR/scripts/lib_prompts.sh" APPS_HELPER="$SCRIPT_DIR/scripts/lib_apps.sh" COPY_HELPER="$SCRIPT_DIR/scripts/lib_copy.sh" +UPDATE_HELPER="$SCRIPT_DIR/scripts/lib_update.sh" if [ -f "$MENU_HELPER" ]; then # shellcheck source=./scripts/copy_menu.sh . "$MENU_HELPER" @@ -96,6 +98,13 @@ else echo "${ERROR} Copy helper not found at $COPY_HELPER. Exiting." exit 1 fi +if [ -f "$UPDATE_HELPER" ]; then + # shellcheck source=./scripts/lib_update.sh + . "$UPDATE_HELPER" +else + echo "${ERROR} Update helper not found at $UPDATE_HELPER. Exiting." + exit 1 +fi version_gte() { [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] @@ -193,6 +202,11 @@ if [ -z "$RUN_MODE" ]; then UPGRADE_MODE=1 EXPRESS_MODE=1 ;; + update) + run_repo_update "$SCRIPT_DIR" + # After update, continue showing the menu without exiting + continue + ;; quit) echo "${NOTE} Exiting per user selection." exit 0 diff --git a/scripts/copy_menu.sh b/scripts/copy_menu.sh index 18482b18..78fb4070 100755 --- a/scripts/copy_menu.sh +++ b/scripts/copy_menu.sh @@ -12,11 +12,13 @@ show_copy_menu() { local install_tag="Install" local upgrade_tag="Upgrade" local express_tag="Express" + local update_tag="Update" local quit_tag="Quit" local install_desc="Fresh copy" local upgrade_desc="Backups + prompts" local express_desc="Skips restores & wallpapers" + local update_desc="Stash + git pull" local quit_desc="Exit without changes" if [ "$express_supported" -ne 1 ]; then express_body="xpress - Requires dots >= ${MIN_EXPRESS_VERSION}" @@ -29,6 +31,7 @@ show_copy_menu() { "$install_tag" "$install_desc" \ "$upgrade_tag" "$upgrade_desc" \ "$express_tag" "$express_desc" \ + "$update_tag" "$update_desc" \ "$quit_tag" "$quit_desc" 3>&1 1>&2 2>&3); then COPY_MENU_CHOICE="quit" return 1 @@ -40,15 +43,17 @@ show_copy_menu() { printf " 1) Install - %s\n" "$install_desc" printf " 2) Upgrade - %s\n" "$upgrade_desc" printf " 3) Express - %s\n" "$express_desc" - printf " 4) Quit - %s\n" "$quit_desc" - printf "Enter choice [1-4]: " + printf " 4) Update - %s\n" "$update_desc" + printf " 5) Quit - %s\n" "$quit_desc" + printf "Enter choice [1-5]: " read -r text_choice case "$text_choice" in 1) choice="$install_tag"; break ;; 2) choice="$upgrade_tag"; break ;; 3) choice="$express_tag"; break ;; - 4) choice="$quit_tag"; break ;; - *) echo "Invalid selection. Please choose 1-4." ;; + 4) choice="$update_tag"; break ;; + 5) choice="$quit_tag"; break ;; + *) echo "Invalid selection. Please choose 1-5." ;; esac done fi diff --git a/scripts/lib_update.sh b/scripts/lib_update.sh new file mode 100644 index 00000000..0a70dff0 --- /dev/null +++ b/scripts/lib_update.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# run_repo_update +# Arguments: +# $1 - expected repository root (typically SCRIPT_DIR from copy.sh) +# Behavior: +# * Verifies the script is executed from Hyprland-Dots root. +# * Stashes local changes (including untracked), pulls latest changes. +# * Shows progress, reports errors, and summarizes results. +# * Waits for user input before returning control to caller. +run_repo_update() { + local repo_dir="${1:-$(pwd)}" + local expected_name="Hyprland-Dots" + local log_dir="$repo_dir/Copy-Logs" + local log_file="$log_dir/update-$(date +%d-%H%M%S)_git.log" + + mkdir -p "$log_dir" + + echo "${INFO} Starting repository update..." | tee -a "$log_file" + + if [ ! -d "$repo_dir" ] || [ "$(basename "$repo_dir")" != "$expected_name" ]; then + echo "${ERROR} This helper must be run from the $expected_name directory. Current: $(pwd)" | tee -a "$log_file" + read -n1 -s -r -p "Press any key to return to the menu..." + echo + return 1 + fi + + if [ "$PWD" != "$repo_dir" ]; then + echo "${INFO} Changing directory to $repo_dir" | tee -a "$log_file" + cd "$repo_dir" || { + echo "${ERROR} Failed to change directory to $repo_dir" | tee -a "$log_file" + read -n1 -s -r -p "Press any key to return to the menu..." + echo + return 1 + } + fi + + local head_before stash_msg pull_status=0 + head_before=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + + echo "${INFO} Checking working tree..." | tee -a "$log_file" + if git diff --quiet && git diff --cached --quiet; then + stash_msg="No local changes; no stash created." + echo "${NOTE} $stash_msg" | tee -a "$log_file" + else + echo "${INFO} Stashing local changes (tracked + untracked)..." | tee -a "$log_file" + if stash_output=$(git stash push -u 2>&1); then + stash_msg="Created stash: $(echo "$stash_output" | head -n1)" + echo "${OK} $stash_msg" | tee -a "$log_file" + else + echo "${ERROR} git stash failed. Details:" | tee -a "$log_file" + echo "$stash_output" | tee -a "$log_file" + read -n1 -s -r -p "Press any key to return to the menu..." + echo + return 1 + fi + fi + + echo "${INFO} Pulling latest changes..." | tee -a "$log_file" + if git pull --ff-only 2>&1 | tee -a "$log_file"; then + pull_status=0 + echo "${OK} Repository updated successfully." | tee -a "$log_file" + else + pull_status=$? + echo "${ERROR} git pull failed (exit $pull_status)." | tee -a "$log_file" + fi + + local head_after + head_after=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + + echo "----------------------------------------" | tee -a "$log_file" + echo "Summary:" | tee -a "$log_file" + echo " Repo : $repo_dir" | tee -a "$log_file" + echo " HEAD before : $head_before" | tee -a "$log_file" + echo " HEAD after : $head_after" | tee -a "$log_file" + echo " Stash : $stash_msg" | tee -a "$log_file" + echo " Pull status : $( [ $pull_status -eq 0 ] && echo success || echo failure )" | tee -a "$log_file" + echo "----------------------------------------" | tee -a "$log_file" + + read -n1 -s -r -p "Press any key to return to the main menu..." + echo + + return $pull_status +} -- cgit v1.2.3 From 1451c8f90cab6a28216872f017083a77dad54be1 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 15 Jan 2026 01:46:51 -0500 Subject: Adding python based tui to replace whiptail On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: scripts/copy_menu.sh new file: scripts/tui_menu.py --- scripts/copy_menu.sh | 19 ++- scripts/tui_menu.py | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 344 insertions(+), 3 deletions(-) create mode 100755 scripts/tui_menu.py (limited to 'scripts') diff --git a/scripts/copy_menu.sh b/scripts/copy_menu.sh index 78fb4070..212cab84 100755 --- a/scripts/copy_menu.sh +++ b/scripts/copy_menu.sh @@ -20,12 +20,24 @@ show_copy_menu() { local express_desc="Skips restores & wallpapers" local update_desc="Stash + git pull" local quit_desc="Exit without changes" - if [ "$express_supported" -ne 1 ]; then - express_body="xpress - Requires dots >= ${MIN_EXPRESS_VERSION}" - fi local choice="" + # Prefer Python TUI if available (mouse + keyboard, styled hotkeys, help) + # Determine repo dir robustly: prefer SCRIPT_DIR if set by caller (copy.sh); fallback to this file's parent + local __self_dir __repo_dir + __self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + __repo_dir="${SCRIPT_DIR:-$(cd "${__self_dir}/.." 2>/dev/null && pwd)}" + local py_menu="${__repo_dir}/scripts/tui_menu.py" + if command -v python3 >/dev/null 2>&1 && [ -f "$py_menu" ]; then + if choice=$(python3 "$py_menu" --express-supported "$express_supported"); then + # shellcheck disable=SC2034 # used by parent script after sourcing this file + COPY_MENU_CHOICE="$choice" + return 0 + fi + fi + + # Fallback to whiptail if present if command -v whiptail >/dev/null 2>&1; then if ! choice=$(whiptail --title "$menu_title" --menu "$prompt" 17 60 8 \ "$install_tag" "$install_desc" \ @@ -37,6 +49,7 @@ show_copy_menu() { return 1 fi else + # Plain-text fallback while true; do printf "\n%s\n" "$menu_title" printf "%s\n" "$prompt" diff --git a/scripts/tui_menu.py b/scripts/tui_menu.py new file mode 100755 index 00000000..abf35751 --- /dev/null +++ b/scripts/tui_menu.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python3 +# Simple TUI menu for Hyprland-Dots copy workflow +# - Prefers Textual (rich) for a nicer UI with mouse + keyboard +# - Falls back to curses if Textual is unavailable +# - Prints the chosen action (Install|Upgrade|Express|Update|Quit) to stdout + +from __future__ import annotations + +import argparse +import os +import sys + +CHOICES = [ + ("Install", "Fresh copy of the dotfiles into ~/.config"), + ("Upgrade", "Backups + interactive prompts"), + ("Express", "Skips restore prompts and large wallpaper download"), + ("Update", "Update this repo: stash local changes, git pull"), + ("Help", "Explain the options shown here"), + ("Quit", "Exit without making changes"), +] + +HELP_TEXT = ( + "Install: Perform a fresh copy of configs into ~/.config.\n" + "Upgrade: Back up existing configs and prompt to restore what you want.\n" + "Express: Faster upgrade (requires installed dots >= the minimum version).\n" + "Update: Safely update this Git repo (stash local changes, then git pull).\n" + "Quit: Exit without making changes.\n\n" + "Tips:\n" + "- Use Up/Down or mouse to select, Enter to confirm.\n" + "- Press the highlighted first letter (I/U/E/U/Q/H) as a shortcut.\n" + "- Press h or ? at any time to view this help.\n" +) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--express-supported", default="0", choices=["0", "1"], help="Whether Express is allowed (1) or not (0)") + args = parser.parse_args() + express_supported = args.express_supported == "1" + + # Try Textual first + try: + return run_textual(express_supported) + except Exception: # noqa: BLE001 - silently fall back + pass + + # Then try curses + try: + return run_curses(express_supported) + except Exception: + # Final fallback to a very simple stdin prompt to avoid breaking workflows + return run_basic(express_supported) + + +def stylize_first_letter(label: str) -> tuple[str, str]: + # returns (styled_label_for_ui, hotkey) + hotkey = label[0].upper() + rest = label[1:] + # Textual Rich markup: bold + accent color for the first letter + styled = f"[b][cyan]{hotkey}[/cyan][/b]{rest}" + return styled, hotkey + + +def run_textual(express_supported: bool) -> int: + from textual.app import App, ComposeResult + from textual.widgets import Header, Footer, Static, Button + from textual.containers import Vertical + from textual.reactive import reactive + from textual import events + + class MenuButton(Button): + def __init__(self, label: str, choice_key: str, disabled: bool = False) -> None: + super().__init__(label, disabled=disabled) + self.choice_key = choice_key + + class MenuApp(App): + CSS = """ + Screen { background: black; } + #title { content-align: center middle; height: 3; color: white; } + Vertical { width: 80; max-width: 90; margin: 1 auto; } + Button { margin: 1 0; padding: 1 2; border: round cornflowerblue; } + Button:hover { background: rgba(100,100,255,0.1); } + Button.-disabled { color: grey50; border: round grey35; } + #help { padding: 1 2; border: round grey42; height: auto; } + """ + + selected: reactive[str | None] = reactive(None) + + def compose(self) -> ComposeResult: # type: ignore[override] + yield Header(show_clock=False) + yield Static("KooL's Hyprland Dotfiles", id="title") + with Vertical(): + # Build buttons + for (name, _desc) in CHOICES: + if name == "Express" and not express_supported: + styled, _hk = stylize_first_letter(name) + yield MenuButton(f"{styled} [grey62](requires newer installed dots)\n[/grey62]", name, disabled=True) + else: + styled, _hk = stylize_first_letter(name) + yield MenuButton(styled, name) + yield Static("Press h or ? for help", id="help") + yield Footer() + + def on_button_pressed(self, event: Button.Pressed) -> None: # type: ignore[override] + btn = event.button + if isinstance(btn, MenuButton): + if btn.choice_key == "Help": + self.show_help() + return + if btn.choice_key == "Express" and not express_supported: + return + self.selected = btn.choice_key + self.exit_app() + + def action_quit(self) -> None: # Esc + self.exit_app("Quit") + + BINDINGS = [ + ("escape", "quit", "Quit"), + ("i", "select('Install')", "Install"), + ("u", "select('Upgrade')", "Upgrade"), + ("e", "select('Express')", "Express"), + ("d", "select('Update')", "Update"), + ("q", "select('Quit')", "Quit"), + ("h", "help", "Help"), + ("?", "help", "Help"), + ("enter", "activate", "Select"), + ] + + def action_select(self, name: str) -> None: + if name == "Express" and not express_supported: + return + if name == "Help": + self.show_help() + return + self.selected = name + self.exit_app() + + def action_help(self) -> None: + self.show_help() + + def action_activate(self) -> None: + # Activate focused button + focused = self.focused + if isinstance(focused, MenuButton): + self.on_button_pressed(Button.Pressed(focused)) + + def show_help(self) -> None: + self.push_screen(HelpScreen()) + + def exit_app(self, fallback: str | None = None) -> None: + result = self.selected or fallback + if result: + print(result) + self.exit(0) + + from textual.screen import ModalScreen + + class HelpScreen(ModalScreen[None]): + def compose(self) -> ComposeResult: # type: ignore[override] + yield Static("[b]Help[/b]\n\n" + HELP_TEXT, id="help") + + BINDINGS = [("escape", "dismiss", "Close"), ("q", "dismiss", "Close")] + + def action_dismiss(self) -> None: + self.dismiss(None) + + app = MenuApp() + app.run() + return 0 + + +def run_curses(express_supported: bool) -> int: + import curses + + labels = [name for (name, _d) in CHOICES] + + def draw_menu(stdscr, idx: int, show_help: bool) -> None: + stdscr.clear() + h, w = stdscr.getmaxyx() + title = "KooL's Hyprland Dotfiles" + stdscr.attron(curses.A_BOLD) + stdscr.addstr(1, (w - len(title)) // 2, title) + stdscr.attroff(curses.A_BOLD) + + y = 4 + for i, name in enumerate(labels): + disabled = (name == "Express" and not express_supported) + hk = name[0].upper() + rest = name[1:] + if i == idx: + stdscr.attron(curses.A_REVERSE) + if disabled: + color = curses.color_pair(2) + else: + color = curses.color_pair(1) + # First letter styled + stdscr.attron(color | curses.A_BOLD) + stdscr.addstr(y, 4, hk) + stdscr.attroff(color | curses.A_BOLD) + stdscr.addstr(y, 5, rest) + if disabled: + msg = " (requires newer installed dots)" + stdscr.attron(curses.color_pair(2)) + stdscr.addstr(y, 5 + len(rest), msg) + stdscr.attroff(curses.color_pair(2)) + if i == idx: + stdscr.attroff(curses.A_REVERSE) + y += 2 + + info = "Enter=Select ↑/↓=Move Mouse=Click h/?=Help q=Quit" + stdscr.addstr(h - 2, 2, info) + + if show_help: + box_w = min(w - 6, 76) + box_h = min(12, h - 6) + bx = (w - box_w) // 2 + by = (h - box_h) // 2 + # simple box + for yy in range(by, by + box_h): + stdscr.addstr(yy, bx, " " * box_w, curses.color_pair(3)) + stdscr.attron(curses.A_BOLD) + stdscr.addstr(by, bx + 2, "Help") + stdscr.attroff(curses.A_BOLD) + for i, line in enumerate(HELP_TEXT.splitlines()[: box_h - 3]): + stdscr.addstr(by + 2 + i, bx + 2, line) + stdscr.addstr(by + box_h - 2, bx + 2, "Press q or Esc to close help") + + stdscr.refresh() + + def loop(stdscr) -> str: + curses.curs_set(0) + curses.mousemask(1) + curses.start_color() + curses.init_pair(1, curses.COLOR_CYAN, -1) + curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_BLACK) + curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) + idx = 0 + showing_help = False + + while True: + draw_menu(stdscr, idx, showing_help) + ch = stdscr.getch() + if showing_help: + if ch in (ord('q'), ord('Q'), 27): + showing_help = False + continue + + if ch in (curses.KEY_UP, ord('k')): + idx = (idx - 1) % len(labels) + elif ch in (curses.KEY_DOWN, ord('j')): + idx = (idx + 1) % len(labels) + elif ch in (ord('h'), ord('?')): + showing_help = True + elif ch in (ord('q'), 27): + return "Quit" + elif ch == curses.KEY_MOUSE: + try: + _, mx, my, _, _ = curses.getmouse() + # map click row to item + base_y = 4 + if my >= base_y: + clicked = (my - base_y) // 2 + if 0 <= clicked < len(labels): + name = labels[clicked] + if name == "Help": + showing_help = True + elif name == "Express" and not express_supported: + pass + else: + return name + except Exception: + pass + elif ch in (curses.KEY_ENTER, 10, 13): + name = labels[idx] + if name == "Help": + showing_help = True + elif name == "Express" and not express_supported: + pass + else: + return name + else: + # hotkeys by first letter + key = chr(ch).lower() if 0 <= ch < 256 else "" + mapping = {"i": "Install", "u": "Upgrade", "e": "Express", "d": "Update", "q": "Quit", "h": "Help"} + if key in mapping: + name = mapping[key] + if name == "Help": + showing_help = True + elif name == "Express" and not express_supported: + pass + else: + return name + + choice = curses.wrapper(loop) + print(choice) + return 0 + + +def run_basic(express_supported: bool) -> int: + # Minimal stdin-only fallback + options = [n for (n, _d) in CHOICES] + while True: + print("Select:") + for i, name in enumerate(options, 1): + if name == "Express" and not express_supported: + print(f" {i}) {name} (disabled)") + else: + print(f" {i}) {name}") + try: + sel = input("> ").strip() + except EOFError: + print("Quit") + return 0 + if sel.isdigit(): + idx = int(sel) - 1 + if 0 <= idx < len(options): + choice = options[idx] + if choice == "Express" and not express_supported: + continue + if choice == "Help": + print(HELP_TEXT) + continue + print(choice) + return 0 + +if __name__ == "__main__": + sys.exit(main()) -- cgit v1.2.3 From 0886304d0fe31f88343391f5405465f90d2ac8fe Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 15 Jan 2026 01:56:42 -0500 Subject: Fixing menu and version detection code for express upgrade On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh modified: scripts/copy_menu.sh modified: scripts/tui_menu.py --- copy.sh | 10 ++++---- scripts/copy_menu.sh | 17 +++++++++---- scripts/tui_menu.py | 70 ++++++++++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 39 deletions(-) (limited to 'scripts') diff --git a/copy.sh b/copy.sh index def8b209..31c66a0b 100755 --- a/copy.sh +++ b/copy.sh @@ -112,12 +112,12 @@ version_gte() { get_installed_dotfiles_version() { local hypr_dir="$HOME/.config/hypr" - local version_file if [ -d "$hypr_dir" ]; then - version_file=$(find "$hypr_dir" -maxdepth 1 -name "v*.*.*" | head -n 1) - if [ -n "$version_file" ]; then - basename "$version_file" | sed 's/^v//' - fi + # Pick the highest semantic version among files named vX.Y.Z + find "$hypr_dir" -maxdepth 1 -type f -name 'v*.*.*' -printf '%f\n' 2>/dev/null \ + | sed 's/^v//' \ + | sort -V \ + | tail -n1 fi } diff --git a/scripts/copy_menu.sh b/scripts/copy_menu.sh index 212cab84..258c2fae 100755 --- a/scripts/copy_menu.sh +++ b/scripts/copy_menu.sh @@ -29,11 +29,18 @@ show_copy_menu() { __self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" __repo_dir="${SCRIPT_DIR:-$(cd "${__self_dir}/.." 2>/dev/null && pwd)}" local py_menu="${__repo_dir}/scripts/tui_menu.py" - if command -v python3 >/dev/null 2>&1 && [ -f "$py_menu" ]; then - if choice=$(python3 "$py_menu" --express-supported "$express_supported"); then - # shellcheck disable=SC2034 # used by parent script after sourcing this file - COPY_MENU_CHOICE="$choice" - return 0 +if command -v python3 >/dev/null 2>&1 && [ -f "$py_menu" ]; then + # Allow forcing backend via COPY_TUI_BACKEND=auto|textual|curses|basic + if [ -n "$COPY_TUI_BACKEND" ]; then + if choice=$(python3 "$py_menu" --express-supported "$express_supported" --backend "$COPY_TUI_BACKEND"); then + COPY_MENU_CHOICE="$choice" + return 0 + fi + else + if choice=$(python3 "$py_menu" --express-supported "$express_supported"); then + COPY_MENU_CHOICE="$choice" + return 0 + fi fi fi diff --git a/scripts/tui_menu.py b/scripts/tui_menu.py index abf35751..d57ba1ac 100755 --- a/scripts/tui_menu.py +++ b/scripts/tui_menu.py @@ -35,20 +35,26 @@ HELP_TEXT = ( def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--express-supported", default="0", choices=["0", "1"], help="Whether Express is allowed (1) or not (0)") + parser.add_argument("--backend", default=os.environ.get("COPY_TUI_BACKEND", "auto"), choices=["auto", "textual", "curses", "basic"], help="Choose UI backend") args = parser.parse_args() express_supported = args.express_supported == "1" + backend = args.backend - # Try Textual first + if backend == "textual": + return run_textual(express_supported) + if backend == "curses": + return run_curses(express_supported) + if backend == "basic": + return run_basic(express_supported) + + # auto: Try Textual, then curses, then basic try: return run_textual(express_supported) - except Exception: # noqa: BLE001 - silently fall back + except Exception: pass - - # Then try curses try: return run_curses(express_supported) except Exception: - # Final fallback to a very simple stdin prompt to avoid breaking workflows return run_basic(express_supported) @@ -180,7 +186,7 @@ def run_curses(express_supported: bool) -> int: h, w = stdscr.getmaxyx() title = "KooL's Hyprland Dotfiles" stdscr.attron(curses.A_BOLD) - stdscr.addstr(1, (w - len(title)) // 2, title) + stdscr.addstr(1, max(2, (w - len(title)) // 2), title) stdscr.attroff(curses.A_BOLD) y = 4 @@ -190,40 +196,36 @@ def run_curses(express_supported: bool) -> int: rest = name[1:] if i == idx: stdscr.attron(curses.A_REVERSE) - if disabled: - color = curses.color_pair(2) - else: - color = curses.color_pair(1) # First letter styled - stdscr.attron(color | curses.A_BOLD) + stdscr.attron(curses.color_pair(1) | curses.A_BOLD) stdscr.addstr(y, 4, hk) - stdscr.attroff(color | curses.A_BOLD) + stdscr.attroff(curses.color_pair(1) | curses.A_BOLD) + if disabled: + stdscr.attron(curses.A_DIM) stdscr.addstr(y, 5, rest) if disabled: msg = " (requires newer installed dots)" - stdscr.attron(curses.color_pair(2)) - stdscr.addstr(y, 5 + len(rest), msg) - stdscr.attroff(curses.color_pair(2)) + stdscr.addstr(y, 5 + len(rest), msg, curses.A_DIM) + stdscr.attroff(curses.A_DIM) if i == idx: stdscr.attroff(curses.A_REVERSE) y += 2 - info = "Enter=Select ↑/↓=Move Mouse=Click h/?=Help q=Quit" - stdscr.addstr(h - 2, 2, info) + info = "Enter=Select Up/Down=Move Mouse=Click h/?=Help q=Quit" + stdscr.addstr(h - 2, 2, info[: max(0, w - 4)]) if show_help: box_w = min(w - 6, 76) box_h = min(12, h - 6) - bx = (w - box_w) // 2 - by = (h - box_h) // 2 - # simple box + bx = max(2, (w - box_w) // 2) + by = max(2, (h - box_h) // 2) for yy in range(by, by + box_h): - stdscr.addstr(yy, bx, " " * box_w, curses.color_pair(3)) + stdscr.addstr(yy, bx, " " * max(0, box_w), curses.color_pair(3)) stdscr.attron(curses.A_BOLD) stdscr.addstr(by, bx + 2, "Help") stdscr.attroff(curses.A_BOLD) - for i, line in enumerate(HELP_TEXT.splitlines()[: box_h - 3]): - stdscr.addstr(by + 2 + i, bx + 2, line) + for i, line in enumerate(HELP_TEXT.splitlines()[: max(0, box_h - 3)]): + stdscr.addstr(by + 2 + i, bx + 2, line[: max(0, box_w - 4)]) stdscr.addstr(by + box_h - 2, bx + 2, "Press q or Esc to close help") stdscr.refresh() @@ -232,9 +234,18 @@ def run_curses(express_supported: bool) -> int: curses.curs_set(0) curses.mousemask(1) curses.start_color() - curses.init_pair(1, curses.COLOR_CYAN, -1) - curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_BLACK) - curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) + try: + curses.use_default_colors() + except Exception: + pass + try: + curses.init_pair(1, curses.COLOR_CYAN, -1) + except Exception: + curses.init_pair(1, curses.COLOR_CYAN, 0) + try: + curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) + except Exception: + curses.init_pair(3, curses.COLOR_WHITE, 0) idx = 0 showing_help = False @@ -257,7 +268,6 @@ def run_curses(express_supported: bool) -> int: elif ch == curses.KEY_MOUSE: try: _, mx, my, _, _ = curses.getmouse() - # map click row to item base_y = 4 if my >= base_y: clicked = (my - base_y) // 2 @@ -280,8 +290,10 @@ def run_curses(express_supported: bool) -> int: else: return name else: - # hotkeys by first letter - key = chr(ch).lower() if 0 <= ch < 256 else "" + try: + key = chr(ch).lower() if 0 <= ch < 256 else "" + except Exception: + key = "" mapping = {"i": "Install", "u": "Upgrade", "e": "Express", "d": "Update", "q": "Quit", "h": "Help"} if key in mapping: name = mapping[key] -- cgit v1.2.3 From 122f607047b16488c95ea25e842084d88b394e1d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 15 Jan 2026 02:25:36 -0500 Subject: Removed python script didn't work On branch development Your branch is up to date with 'origin/development'. Changes to be committed: deleted: copy-menu-issue.txt modified: scripts/copy_menu.sh deleted: scripts/tui_menu.py --- copy-menu-issue.txt | 52 -------- scripts/copy_menu.sh | 73 ++++++----- scripts/tui_menu.py | 340 --------------------------------------------------- 3 files changed, 36 insertions(+), 429 deletions(-) delete mode 100644 copy-menu-issue.txt delete mode 100755 scripts/tui_menu.py (limited to 'scripts') diff --git a/copy-menu-issue.txt b/copy-menu-issue.txt deleted file mode 100644 index 94672040..00000000 --- a/copy-menu-issue.txt +++ /dev/null @@ -1,52 +0,0 @@ -Summary: copy.sh menu issues on Debian host - -Symptoms -- Running copy.sh shows a black screen with a cursor; no visible menu. -- Running scripts/tui_menu.py directly renders an ncurses menu, but Express appears disabled. -- The host has ~/.config/hypr/v2.3.18 present. - -Changes already made (in repo) -- Added Python TUI (scripts/tui_menu.py) with backends: Textual -> curses -> basic; mouse + keyboard; hotkeys; Help panel. -- Updated scripts/copy_menu.sh to prefer Python TUI and to accept COPY_TUI_BACKEND=auto|textual|curses|basic, passing --express-supported accordingly. -- Hardened curses drawing to avoid blank screens (use_default_colors, safer bounds). -- Fixed Express detection in copy.sh to pick the highest version marker (sort -V) under ~/.config/hypr (vX.Y.Z). - -Why Express shows disabled when running the TUI directly -- scripts/tui_menu.py defaults to --express-supported=0 unless told otherwise. When launched by copy.sh, it is passed the correct flag. Running it manually without the flag will show Express as disabled. - -Immediate workaround on the Debian host -1) Ensure you have the latest repo changes - git --no-pager status - git pull --ff-only - -2) Force the curses backend to avoid the black Textual screen - # one-shot - COPY_TUI_BACKEND=curses ./copy.sh - # or set permanently for the session - export COPY_TUI_BACKEND=curses - ./copy.sh - -3) If curses ever fails to render, use the basic fallback - COPY_TUI_BACKEND=basic ./copy.sh - -4) To test the TUI directly with Express allowed - python3 scripts/tui_menu.py --express-supported 1 --backend curses - -Verify Express detection on the host -- Confirm the installed version marker and what copy.sh will see: - find "$HOME/.config/hypr" -maxdepth 1 -type f -name 'v*.*.*' -printf '%f\n' | sed 's/^v//' | sort -V | tail -n1 -- Expected output: 2.3.18 (or newer). If empty, create the marker: - : > "$HOME/.config/hypr/v2.3.18" - -If black screen persists with copy.sh -- Dump debug logs for the menu selection phase: - set -x; COPY_TUI_BACKEND=curses bash -c 'source scripts/copy_menu.sh; show_copy_menu 1; echo "CHOICE=$COPY_MENU_CHOICE"'; set +x -- Check TERM and Python TUI dependency situations: - echo "$TERM" - command -v python3 || true - python3 -c "import curses; print('curses OK')" || true - -Notes for future session -- copy_menu.sh already honors COPY_TUI_BACKEND and falls back to whiptail/text if Python fails. -- copy.sh now uses highest version marker to enable Express; the marker must be a file named exactly vX.Y.Z under ~/.config/hypr. -- If this host lacks Textual (rich) and shows black screen in Textual, forcing curses via COPY_TUI_BACKEND=curses is the recommended run mode on Debian for now. diff --git a/scripts/copy_menu.sh b/scripts/copy_menu.sh index 258c2fae..87f9301f 100755 --- a/scripts/copy_menu.sh +++ b/scripts/copy_menu.sh @@ -22,47 +22,17 @@ show_copy_menu() { local quit_desc="Exit without changes" local choice="" - - # Prefer Python TUI if available (mouse + keyboard, styled hotkeys, help) - # Determine repo dir robustly: prefer SCRIPT_DIR if set by caller (copy.sh); fallback to this file's parent - local __self_dir __repo_dir - __self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - __repo_dir="${SCRIPT_DIR:-$(cd "${__self_dir}/.." 2>/dev/null && pwd)}" - local py_menu="${__repo_dir}/scripts/tui_menu.py" -if command -v python3 >/dev/null 2>&1 && [ -f "$py_menu" ]; then - # Allow forcing backend via COPY_TUI_BACKEND=auto|textual|curses|basic - if [ -n "$COPY_TUI_BACKEND" ]; then - if choice=$(python3 "$py_menu" --express-supported "$express_supported" --backend "$COPY_TUI_BACKEND"); then - COPY_MENU_CHOICE="$choice" - return 0 - fi - else - if choice=$(python3 "$py_menu" --express-supported "$express_supported"); then - COPY_MENU_CHOICE="$choice" - return 0 - fi - fi - fi - - # Fallback to whiptail if present - if command -v whiptail >/dev/null 2>&1; then - if ! choice=$(whiptail --title "$menu_title" --menu "$prompt" 17 60 8 \ - "$install_tag" "$install_desc" \ - "$upgrade_tag" "$upgrade_desc" \ - "$express_tag" "$express_desc" \ - "$update_tag" "$update_desc" \ - "$quit_tag" "$quit_desc" 3>&1 1>&2 2>&3); then - COPY_MENU_CHOICE="quit" - return 1 - fi - else - # Plain-text fallback + run_basic_menu() { while true; do printf "\n%s\n" "$menu_title" printf "%s\n" "$prompt" printf " 1) Install - %s\n" "$install_desc" printf " 2) Upgrade - %s\n" "$upgrade_desc" - printf " 3) Express - %s\n" "$express_desc" + if [ "$express_supported" -eq 1 ]; then + printf " 3) Express - %s\n" "$express_desc" + else + printf " 3) Express - %s (disabled)\n" "$express_desc" + fi printf " 4) Update - %s\n" "$update_desc" printf " 5) Quit - %s\n" "$quit_desc" printf "Enter choice [1-5]: " @@ -70,12 +40,41 @@ if command -v python3 >/dev/null 2>&1 && [ -f "$py_menu" ]; then case "$text_choice" in 1) choice="$install_tag"; break ;; 2) choice="$upgrade_tag"; break ;; - 3) choice="$express_tag"; break ;; + 3) + if [ "$express_supported" -eq 1 ]; then + choice="$express_tag" + break + else + echo "Express is disabled on this system." + fi + ;; 4) choice="$update_tag"; break ;; 5) choice="$quit_tag"; break ;; *) echo "Invalid selection. Please choose 1-5." ;; esac done + } + + if [ "$COPY_TUI_BACKEND" = "basic" ]; then + run_basic_menu + COPY_MENU_CHOICE="$choice" + return 0 + fi + + # Fallback to whiptail if present + if command -v whiptail >/dev/null 2>&1; then + if ! choice=$(whiptail --title "$menu_title" --menu "$prompt" 17 60 8 \ + "$install_tag" "$install_desc" \ + "$upgrade_tag" "$upgrade_desc" \ + "$express_tag" "$express_desc" \ + "$update_tag" "$update_desc" \ + "$quit_tag" "$quit_desc" 3>&1 1>&2 2>&3); then + COPY_MENU_CHOICE="quit" + return 1 + fi + else + # Plain-text fallback + run_basic_menu fi # shellcheck disable=SC2034 # used by parent script after sourcing this file diff --git a/scripts/tui_menu.py b/scripts/tui_menu.py deleted file mode 100755 index d57ba1ac..00000000 --- a/scripts/tui_menu.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python3 -# Simple TUI menu for Hyprland-Dots copy workflow -# - Prefers Textual (rich) for a nicer UI with mouse + keyboard -# - Falls back to curses if Textual is unavailable -# - Prints the chosen action (Install|Upgrade|Express|Update|Quit) to stdout - -from __future__ import annotations - -import argparse -import os -import sys - -CHOICES = [ - ("Install", "Fresh copy of the dotfiles into ~/.config"), - ("Upgrade", "Backups + interactive prompts"), - ("Express", "Skips restore prompts and large wallpaper download"), - ("Update", "Update this repo: stash local changes, git pull"), - ("Help", "Explain the options shown here"), - ("Quit", "Exit without making changes"), -] - -HELP_TEXT = ( - "Install: Perform a fresh copy of configs into ~/.config.\n" - "Upgrade: Back up existing configs and prompt to restore what you want.\n" - "Express: Faster upgrade (requires installed dots >= the minimum version).\n" - "Update: Safely update this Git repo (stash local changes, then git pull).\n" - "Quit: Exit without making changes.\n\n" - "Tips:\n" - "- Use Up/Down or mouse to select, Enter to confirm.\n" - "- Press the highlighted first letter (I/U/E/U/Q/H) as a shortcut.\n" - "- Press h or ? at any time to view this help.\n" -) - - -def main() -> int: - parser = argparse.ArgumentParser() - parser.add_argument("--express-supported", default="0", choices=["0", "1"], help="Whether Express is allowed (1) or not (0)") - parser.add_argument("--backend", default=os.environ.get("COPY_TUI_BACKEND", "auto"), choices=["auto", "textual", "curses", "basic"], help="Choose UI backend") - args = parser.parse_args() - express_supported = args.express_supported == "1" - backend = args.backend - - if backend == "textual": - return run_textual(express_supported) - if backend == "curses": - return run_curses(express_supported) - if backend == "basic": - return run_basic(express_supported) - - # auto: Try Textual, then curses, then basic - try: - return run_textual(express_supported) - except Exception: - pass - try: - return run_curses(express_supported) - except Exception: - return run_basic(express_supported) - - -def stylize_first_letter(label: str) -> tuple[str, str]: - # returns (styled_label_for_ui, hotkey) - hotkey = label[0].upper() - rest = label[1:] - # Textual Rich markup: bold + accent color for the first letter - styled = f"[b][cyan]{hotkey}[/cyan][/b]{rest}" - return styled, hotkey - - -def run_textual(express_supported: bool) -> int: - from textual.app import App, ComposeResult - from textual.widgets import Header, Footer, Static, Button - from textual.containers import Vertical - from textual.reactive import reactive - from textual import events - - class MenuButton(Button): - def __init__(self, label: str, choice_key: str, disabled: bool = False) -> None: - super().__init__(label, disabled=disabled) - self.choice_key = choice_key - - class MenuApp(App): - CSS = """ - Screen { background: black; } - #title { content-align: center middle; height: 3; color: white; } - Vertical { width: 80; max-width: 90; margin: 1 auto; } - Button { margin: 1 0; padding: 1 2; border: round cornflowerblue; } - Button:hover { background: rgba(100,100,255,0.1); } - Button.-disabled { color: grey50; border: round grey35; } - #help { padding: 1 2; border: round grey42; height: auto; } - """ - - selected: reactive[str | None] = reactive(None) - - def compose(self) -> ComposeResult: # type: ignore[override] - yield Header(show_clock=False) - yield Static("KooL's Hyprland Dotfiles", id="title") - with Vertical(): - # Build buttons - for (name, _desc) in CHOICES: - if name == "Express" and not express_supported: - styled, _hk = stylize_first_letter(name) - yield MenuButton(f"{styled} [grey62](requires newer installed dots)\n[/grey62]", name, disabled=True) - else: - styled, _hk = stylize_first_letter(name) - yield MenuButton(styled, name) - yield Static("Press h or ? for help", id="help") - yield Footer() - - def on_button_pressed(self, event: Button.Pressed) -> None: # type: ignore[override] - btn = event.button - if isinstance(btn, MenuButton): - if btn.choice_key == "Help": - self.show_help() - return - if btn.choice_key == "Express" and not express_supported: - return - self.selected = btn.choice_key - self.exit_app() - - def action_quit(self) -> None: # Esc - self.exit_app("Quit") - - BINDINGS = [ - ("escape", "quit", "Quit"), - ("i", "select('Install')", "Install"), - ("u", "select('Upgrade')", "Upgrade"), - ("e", "select('Express')", "Express"), - ("d", "select('Update')", "Update"), - ("q", "select('Quit')", "Quit"), - ("h", "help", "Help"), - ("?", "help", "Help"), - ("enter", "activate", "Select"), - ] - - def action_select(self, name: str) -> None: - if name == "Express" and not express_supported: - return - if name == "Help": - self.show_help() - return - self.selected = name - self.exit_app() - - def action_help(self) -> None: - self.show_help() - - def action_activate(self) -> None: - # Activate focused button - focused = self.focused - if isinstance(focused, MenuButton): - self.on_button_pressed(Button.Pressed(focused)) - - def show_help(self) -> None: - self.push_screen(HelpScreen()) - - def exit_app(self, fallback: str | None = None) -> None: - result = self.selected or fallback - if result: - print(result) - self.exit(0) - - from textual.screen import ModalScreen - - class HelpScreen(ModalScreen[None]): - def compose(self) -> ComposeResult: # type: ignore[override] - yield Static("[b]Help[/b]\n\n" + HELP_TEXT, id="help") - - BINDINGS = [("escape", "dismiss", "Close"), ("q", "dismiss", "Close")] - - def action_dismiss(self) -> None: - self.dismiss(None) - - app = MenuApp() - app.run() - return 0 - - -def run_curses(express_supported: bool) -> int: - import curses - - labels = [name for (name, _d) in CHOICES] - - def draw_menu(stdscr, idx: int, show_help: bool) -> None: - stdscr.clear() - h, w = stdscr.getmaxyx() - title = "KooL's Hyprland Dotfiles" - stdscr.attron(curses.A_BOLD) - stdscr.addstr(1, max(2, (w - len(title)) // 2), title) - stdscr.attroff(curses.A_BOLD) - - y = 4 - for i, name in enumerate(labels): - disabled = (name == "Express" and not express_supported) - hk = name[0].upper() - rest = name[1:] - if i == idx: - stdscr.attron(curses.A_REVERSE) - # First letter styled - stdscr.attron(curses.color_pair(1) | curses.A_BOLD) - stdscr.addstr(y, 4, hk) - stdscr.attroff(curses.color_pair(1) | curses.A_BOLD) - if disabled: - stdscr.attron(curses.A_DIM) - stdscr.addstr(y, 5, rest) - if disabled: - msg = " (requires newer installed dots)" - stdscr.addstr(y, 5 + len(rest), msg, curses.A_DIM) - stdscr.attroff(curses.A_DIM) - if i == idx: - stdscr.attroff(curses.A_REVERSE) - y += 2 - - info = "Enter=Select Up/Down=Move Mouse=Click h/?=Help q=Quit" - stdscr.addstr(h - 2, 2, info[: max(0, w - 4)]) - - if show_help: - box_w = min(w - 6, 76) - box_h = min(12, h - 6) - bx = max(2, (w - box_w) // 2) - by = max(2, (h - box_h) // 2) - for yy in range(by, by + box_h): - stdscr.addstr(yy, bx, " " * max(0, box_w), curses.color_pair(3)) - stdscr.attron(curses.A_BOLD) - stdscr.addstr(by, bx + 2, "Help") - stdscr.attroff(curses.A_BOLD) - for i, line in enumerate(HELP_TEXT.splitlines()[: max(0, box_h - 3)]): - stdscr.addstr(by + 2 + i, bx + 2, line[: max(0, box_w - 4)]) - stdscr.addstr(by + box_h - 2, bx + 2, "Press q or Esc to close help") - - stdscr.refresh() - - def loop(stdscr) -> str: - curses.curs_set(0) - curses.mousemask(1) - curses.start_color() - try: - curses.use_default_colors() - except Exception: - pass - try: - curses.init_pair(1, curses.COLOR_CYAN, -1) - except Exception: - curses.init_pair(1, curses.COLOR_CYAN, 0) - try: - curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) - except Exception: - curses.init_pair(3, curses.COLOR_WHITE, 0) - idx = 0 - showing_help = False - - while True: - draw_menu(stdscr, idx, showing_help) - ch = stdscr.getch() - if showing_help: - if ch in (ord('q'), ord('Q'), 27): - showing_help = False - continue - - if ch in (curses.KEY_UP, ord('k')): - idx = (idx - 1) % len(labels) - elif ch in (curses.KEY_DOWN, ord('j')): - idx = (idx + 1) % len(labels) - elif ch in (ord('h'), ord('?')): - showing_help = True - elif ch in (ord('q'), 27): - return "Quit" - elif ch == curses.KEY_MOUSE: - try: - _, mx, my, _, _ = curses.getmouse() - base_y = 4 - if my >= base_y: - clicked = (my - base_y) // 2 - if 0 <= clicked < len(labels): - name = labels[clicked] - if name == "Help": - showing_help = True - elif name == "Express" and not express_supported: - pass - else: - return name - except Exception: - pass - elif ch in (curses.KEY_ENTER, 10, 13): - name = labels[idx] - if name == "Help": - showing_help = True - elif name == "Express" and not express_supported: - pass - else: - return name - else: - try: - key = chr(ch).lower() if 0 <= ch < 256 else "" - except Exception: - key = "" - mapping = {"i": "Install", "u": "Upgrade", "e": "Express", "d": "Update", "q": "Quit", "h": "Help"} - if key in mapping: - name = mapping[key] - if name == "Help": - showing_help = True - elif name == "Express" and not express_supported: - pass - else: - return name - - choice = curses.wrapper(loop) - print(choice) - return 0 - - -def run_basic(express_supported: bool) -> int: - # Minimal stdin-only fallback - options = [n for (n, _d) in CHOICES] - while True: - print("Select:") - for i, name in enumerate(options, 1): - if name == "Express" and not express_supported: - print(f" {i}) {name} (disabled)") - else: - print(f" {i}) {name}") - try: - sel = input("> ").strip() - except EOFError: - print("Quit") - return 0 - if sel.isdigit(): - idx = int(sel) - 1 - if 0 <= idx < len(options): - choice = options[idx] - if choice == "Express" and not express_supported: - continue - if choice == "Help": - print(HELP_TEXT) - continue - print(choice) - return 0 - -if __name__ == "__main__": - sys.exit(main()) -- cgit v1.2.3 From 3363d48f00d92bbefe1a65c5331a5671ef88ae6a Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 16 Jan 2026 22:22:14 -0500 Subject: Disabled RainbowBorders by default use quick settings to enable The new mode select menu for RainbowBorders makes the prompt at install redundant. Especially when upgrading On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: CHANGELOG.md renamed: config/hypr/UserScripts/RainbowBorders.sh -> config/hypr/UserScripts/RainbowBorders.bak.sh modified: config/hypr/configs/Startup_Apps.conf modified: copy.sh modified: scripts/lib_prompts.sh --- CHANGELOG.md | 2 + config/hypr/UserScripts/RainbowBorders.bak.sh | 89 +++++++++++++++++++++++++++ config/hypr/UserScripts/RainbowBorders.sh | 89 --------------------------- config/hypr/configs/Startup_Apps.conf | 4 +- copy.sh | 1 - scripts/lib_prompts.sh | 21 ------- 6 files changed, 93 insertions(+), 113 deletions(-) create mode 100755 config/hypr/UserScripts/RainbowBorders.bak.sh delete mode 100755 config/hypr/UserScripts/RainbowBorders.sh (limited to 'scripts') diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a9ecb61..8ae7c154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - There are now mulitple modes for the Rainbow Borders feature - `Disabled`, `Wallust Color`, `Rainbow`, `Gradient flow` - Thank you for the submission +- Disabled `RainbowBorders.sh` by default +- Use the quick setings menu `SUPERSHIFT + E` to enable, select mode - 2026-01-15 - Created waybar configs for ML4W Glass style diff --git a/config/hypr/UserScripts/RainbowBorders.bak.sh b/config/hypr/UserScripts/RainbowBorders.bak.sh new file mode 100755 index 00000000..67269b8a --- /dev/null +++ b/config/hypr/UserScripts/RainbowBorders.bak.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ ## +# Smooth border cycling effect using Wallust palette or full rainbow + +# Possible values: "wallust_random", "rainbow", "gradient_flow" +EFFECT_TYPE="gradient_flow" + +WALLUST_COLORS_SOURCE="$HOME/.config/hypr/wallust/wallust-hyprland.conf" + +WALLUST_COLORS=() + +# ---------- LOAD WALLUST COLORS ---------- +if [[ "$EFFECT_TYPE" == "wallust_random" || "$EFFECT_TYPE" == "gradient_flow" ]]; then + # Accept either hex (0xffRRGGBB) or rgb(r,g,b) and normalize to 0xffRRGGBB + mapfile -t WALLUST_COLORS < <( + grep -E '^\$color[0-9]+' "$WALLUST_COLORS_SOURCE" | awk ' + function hex2(s){ return (length(s)==6 ? "0xff"s : ""); } + function rgb2(r,g,b){ return sprintf("0xff%02x%02x%02x", r, g, b); } + { + if (match($0, /0x([0-9a-fA-F]{8})/, m)) { print "0x" m[1]; next } + if (match($0, /#([0-9a-fA-F]{6})/, m)) { print hex2(m[1]); next } + if (match($0, /rgb\(([0-9]+),[ ]*([0-9]+),[ ]*([0-9]+)\)/, m)) { + print rgb2(m[1], m[2], m[3]); next + } + }' + ) + + if (( ${#WALLUST_COLORS[@]} == 0 )); then + # If wallust colors can't be loaded, fall back to random_hex + EFFECT_TYPE="rainbow" + fi +fi + +# ---------- RANDOM WALLUST COLORS ---------- +function wallust_random() { + echo "${WALLUST_COLORS[RANDOM % ${#WALLUST_COLORS[@]}]}" +} + +# ---------- RAINBOW COLORS ---------- +function random_hex() { + echo "0xff$(openssl rand -hex 3)" +} + +# ---------- FLOW MODE ---------- +BASE_COLOR="${WALLUST_COLORS[10]}" +GRAD1_COLOR="${WALLUST_COLORS[14]}" +GRAD2_COLOR="${WALLUST_COLORS[13]}" +GLOW_COLOR="${WALLUST_COLORS[15]}" + +MAX_POS=10 +GLOW_POS=0 + +function gradient_flow_color() { + local pos=$1 + local d=$(( pos - GLOW_POS )) + + # wrap distance (-9..9) + if (( d > MAX_POS/2 )); then d=$((d - MAX_POS)); fi + if (( d < -MAX_POS/2 )); then d=$((d + MAX_POS)); fi + + case "${d#-}" in + 0) echo "$GLOW_COLOR" ;; + 1) echo "$GRAD1_COLOR" ;; + 2) echo "$GRAD2_COLOR" ;; + *) echo "$BASE_COLOR" ;; + esac + + if (( pos == MAX_POS - 1 )); then + GLOW_POS=$(( (GLOW_POS + 1) % MAX_POS )) + fi +} + +# ---------- Main function ---------- + +function get_color() { + if [[ "$EFFECT_TYPE" == "wallust_random" && ${#WALLUST_COLORS[@]} -gt 0 ]]; then + wallust_random + elif [[ "$EFFECT_TYPE" == "gradient_flow" && ${#WALLUST_COLORS[@]} -ge 16 ]]; then + gradient_flow_color "$1" + else + random_hex + fi +} + +# border effect for ACTIVE window +hyprctl keyword general:col.active_border $(get_color 0) $(get_color 1) $(get_color 2) $(get_color 3) $(get_color 4) $(get_color 5) $(get_color 6) $(get_color 7) $(get_color 8) $(get_color 9) 270deg + +# border effect for INACTIVE windows +#hyprctl keyword general:col.inactive_border $(get_color 0) $(get_color 1) $(get_color 2) $(get_color 3) $(get_color 4) $(get_color 5) $(get_color 6) $(get_color 7) $(get_color 8) $(get_color 9) 270deg \ No newline at end of file diff --git a/config/hypr/UserScripts/RainbowBorders.sh b/config/hypr/UserScripts/RainbowBorders.sh deleted file mode 100755 index 67269b8a..00000000 --- a/config/hypr/UserScripts/RainbowBorders.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env bash -# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ ## -# Smooth border cycling effect using Wallust palette or full rainbow - -# Possible values: "wallust_random", "rainbow", "gradient_flow" -EFFECT_TYPE="gradient_flow" - -WALLUST_COLORS_SOURCE="$HOME/.config/hypr/wallust/wallust-hyprland.conf" - -WALLUST_COLORS=() - -# ---------- LOAD WALLUST COLORS ---------- -if [[ "$EFFECT_TYPE" == "wallust_random" || "$EFFECT_TYPE" == "gradient_flow" ]]; then - # Accept either hex (0xffRRGGBB) or rgb(r,g,b) and normalize to 0xffRRGGBB - mapfile -t WALLUST_COLORS < <( - grep -E '^\$color[0-9]+' "$WALLUST_COLORS_SOURCE" | awk ' - function hex2(s){ return (length(s)==6 ? "0xff"s : ""); } - function rgb2(r,g,b){ return sprintf("0xff%02x%02x%02x", r, g, b); } - { - if (match($0, /0x([0-9a-fA-F]{8})/, m)) { print "0x" m[1]; next } - if (match($0, /#([0-9a-fA-F]{6})/, m)) { print hex2(m[1]); next } - if (match($0, /rgb\(([0-9]+),[ ]*([0-9]+),[ ]*([0-9]+)\)/, m)) { - print rgb2(m[1], m[2], m[3]); next - } - }' - ) - - if (( ${#WALLUST_COLORS[@]} == 0 )); then - # If wallust colors can't be loaded, fall back to random_hex - EFFECT_TYPE="rainbow" - fi -fi - -# ---------- RANDOM WALLUST COLORS ---------- -function wallust_random() { - echo "${WALLUST_COLORS[RANDOM % ${#WALLUST_COLORS[@]}]}" -} - -# ---------- RAINBOW COLORS ---------- -function random_hex() { - echo "0xff$(openssl rand -hex 3)" -} - -# ---------- FLOW MODE ---------- -BASE_COLOR="${WALLUST_COLORS[10]}" -GRAD1_COLOR="${WALLUST_COLORS[14]}" -GRAD2_COLOR="${WALLUST_COLORS[13]}" -GLOW_COLOR="${WALLUST_COLORS[15]}" - -MAX_POS=10 -GLOW_POS=0 - -function gradient_flow_color() { - local pos=$1 - local d=$(( pos - GLOW_POS )) - - # wrap distance (-9..9) - if (( d > MAX_POS/2 )); then d=$((d - MAX_POS)); fi - if (( d < -MAX_POS/2 )); then d=$((d + MAX_POS)); fi - - case "${d#-}" in - 0) echo "$GLOW_COLOR" ;; - 1) echo "$GRAD1_COLOR" ;; - 2) echo "$GRAD2_COLOR" ;; - *) echo "$BASE_COLOR" ;; - esac - - if (( pos == MAX_POS - 1 )); then - GLOW_POS=$(( (GLOW_POS + 1) % MAX_POS )) - fi -} - -# ---------- Main function ---------- - -function get_color() { - if [[ "$EFFECT_TYPE" == "wallust_random" && ${#WALLUST_COLORS[@]} -gt 0 ]]; then - wallust_random - elif [[ "$EFFECT_TYPE" == "gradient_flow" && ${#WALLUST_COLORS[@]} -ge 16 ]]; then - gradient_flow_color "$1" - else - random_hex - fi -} - -# border effect for ACTIVE window -hyprctl keyword general:col.active_border $(get_color 0) $(get_color 1) $(get_color 2) $(get_color 3) $(get_color 4) $(get_color 5) $(get_color 6) $(get_color 7) $(get_color 8) $(get_color 9) 270deg - -# border effect for INACTIVE windows -#hyprctl keyword general:col.inactive_border $(get_color 0) $(get_color 1) $(get_color 2) $(get_color 3) $(get_color 4) $(get_color 5) $(get_color 6) $(get_color 7) $(get_color 8) $(get_color 9) 270deg \ No newline at end of file diff --git a/config/hypr/configs/Startup_Apps.conf b/config/hypr/configs/Startup_Apps.conf index 2bf902cd..0cc5da11 100644 --- a/config/hypr/configs/Startup_Apps.conf +++ b/config/hypr/configs/Startup_Apps.conf @@ -33,8 +33,8 @@ exec-once = $scriptsDir/Hyprsunset.sh init exec-once = wl-paste --type text --watch cliphist store exec-once = wl-paste --type image --watch cliphist store -# Rainbow borders -exec-once = $UserScripts/RainbowBorders.sh +# Rainbow borders (disabled by default; use quick settings menu) +#exec-once = $UserScripts/RainbowBorders.sh # Here are list of features available but disabled by default diff --git a/copy.sh b/copy.sh index 31c66a0b..b061f4ac 100755 --- a/copy.sh +++ b/copy.sh @@ -355,7 +355,6 @@ fi printf "\n%.0s" {1..1} prompt_clock_12h "$LOG" printf "\n%.0s" {1..1} -prompt_rainbow_borders "$LOG" >/dev/null printf "\n%.0s" {1..1} prompt_express_upgrade "$EXPRESS_SUPPORTED" "$LOG" diff --git a/scripts/lib_prompts.sh b/scripts/lib_prompts.sh index a63afde3..bf6fafd7 100644 --- a/scripts/lib_prompts.sh +++ b/scripts/lib_prompts.sh @@ -209,27 +209,6 @@ apply_sddm_12h_format_sequoia() { fi } -# Rainbow borders toggle; returns "disabled" or "kept". -prompt_rainbow_borders() { - local log="$1" - echo "${NOTE} ${SKY_BLUE}By default, Rainbow Borders animation is enabled" - echo "${WARN} However, this uses a bit more CPU and Memory resources." - if ! read -r -p "${CAT} Do you want to disable Rainbow Borders animation? (y/N): " border_choice &1 | tee -a "$log" - echo "kept" - return - fi - if [[ "$border_choice" =~ ^[Yy]$ ]]; then - mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh - sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/configs/Startup_Apps.conf - sed -i '/^[[:space:]]*animation = borderangle, 1, 180, liner, loop/s/^/#/' config/hypr/configs/UserAnimations.conf - echo "${OK} Rainbow borders are now disabled." 2>&1 | tee -a "$log" - echo "disabled" - else - echo "${NOTE} No changes made. Rainbow borders remain enabled." 2>&1 | tee -a "$log" - echo "kept" - fi -} # Express upgrade confirmation; may set EXPRESS_MODE=1. prompt_express_upgrade() { -- cgit v1.2.3