From f041272302d38252013960b79fbbb9803799e725 Mon Sep 17 00:00:00 2001 From: clsty Date: Fri, 31 Oct 2025 22:38:00 +0800 Subject: [PATCH 01/16] Detect cmds in checkdeps --- sdata/subcmd-checkdeps/0.run.sh | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sdata/subcmd-checkdeps/0.run.sh b/sdata/subcmd-checkdeps/0.run.sh index ae512c574..2670dcac6 100644 --- a/sdata/subcmd-checkdeps/0.run.sh +++ b/sdata/subcmd-checkdeps/0.run.sh @@ -9,15 +9,11 @@ pkglistfile=$(mktemp) pkglistfile_orig=${LIST_FILE_PATH} pkglistfile_orig_s=${REPO_ROOT}/cache/dependencies_stripped.conf -#if ! "$(command -v curl)";then -# echo "Please install curl first.";exit 1 -#fi -#if ! "$(command -v gzip)";then -# echo "Please install gzip first.";exit 1 -#fi -#if ! "$(command -v pacman)";then -# echo "pacman not found, aborting...";exit 1 -#fi +for cmd in curl gzip pacman;do + if ! command -v $cmd;then + echo "Please install $cmd first.";exit 1 + fi +done remove_bashcomments_emptylines $pkglistfile_orig $pkglistfile_orig_s cat $pkglistfile_orig_s | sed "s_\ _\n_g" > $pkglistfile From 02c71e9310af4758d311e40d9cea576d6c829bb3 Mon Sep 17 00:00:00 2001 From: clsty Date: Fri, 31 Oct 2025 22:40:43 +0800 Subject: [PATCH 02/16] Fix submodule update detect logic --- sdata/lib/functions.sh | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/sdata/lib/functions.sh b/sdata/lib/functions.sh index b236b8324..b5b5a650d 100644 --- a/sdata/lib/functions.sh +++ b/sdata/lib/functions.sh @@ -293,23 +293,7 @@ function check_disk_space() { } function auto_get_git_submodule(){ - local git_submodules_list=() - - while IFS= read -r path; do - [ -z "$path" ] && continue - git_submodules_list+=("$path") - done < <(git submodule status --recursive 2>/dev/null | awk '{print $2}') - - local missing=0 - - for p in "${git_submodules_list[@]}"; do - if [ ! -d "$p" ] || [ -z "$(ls -A "$p" 2>/dev/null)" ]; then - missing=1 - break - fi - done - - if [ "$missing" -eq 1 ]; then + if git submodule status --recursive | grep -E '^[+-U]';then x git submodule update --init --recursive fi } From 73be5c5f0abc26cd6856dc144ec6daa06882feb7 Mon Sep 17 00:00:00 2001 From: clsty Date: Fri, 31 Oct 2025 22:42:16 +0800 Subject: [PATCH 03/16] Improve message for backup configs --- sdata/subcmd-install/3.files.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdata/subcmd-install/3.files.sh b/sdata/subcmd-install/3.files.sh index e5e803295..ad81c07de 100644 --- a/sdata/subcmd-install/3.files.sh +++ b/sdata/subcmd-install/3.files.sh @@ -22,7 +22,7 @@ function auto_backup_configs(){ false) if [[ ! -d "$BACKUP_DIR" ]]; then local backup=true;fi;; *) printf "${STY_RED}" - printf "Would you like to backup clashing dirs/files to \"$BACKUP_DIR\"?" + printf "Would you like to backup clashing dirs/files to \"$BACKUP_DIR\"?\n" printf "${STY_RST}" while true;do echo " y = Yes, backup" @@ -33,7 +33,7 @@ function auto_backup_configs(){ local backup=true;break ;; [nNsS]) echo -e "${STY_BLUE}Alright, skipping...${STY_RST}" local backup=false;break ;; - *) echo -e "${STY_RED}Please enter [y/n].${STY_RST}";; + *) echo -e "${STY_RED}Please enter [y/n/s].${STY_RST}";; esac done ;; From 43aae4ee56ac5a3e59275630a9b69ad4c3904860 Mon Sep 17 00:00:00 2001 From: clsty Date: Fri, 31 Oct 2025 23:07:35 +0800 Subject: [PATCH 04/16] Minor update about git_submodule() --- sdata/lib/functions.sh | 3 ++- sdata/subcmd-install/3.files.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sdata/lib/functions.sh b/sdata/lib/functions.sh index b5b5a650d..a2455c2a2 100644 --- a/sdata/lib/functions.sh +++ b/sdata/lib/functions.sh @@ -292,8 +292,9 @@ function check_disk_space() { return 0 } -function auto_get_git_submodule(){ +function auto_update_git_submodule(){ if git submodule status --recursive | grep -E '^[+-U]';then + # Note: `git pull --recurse-submodules` cannot substitute `git submodule update --init --recursive` cuz it does not init a submodule when needed. x git submodule update --init --recursive fi } diff --git a/sdata/subcmd-install/3.files.sh b/sdata/subcmd-install/3.files.sh index ad81c07de..209414038 100644 --- a/sdata/subcmd-install/3.files.sh +++ b/sdata/subcmd-install/3.files.sh @@ -46,8 +46,8 @@ function auto_backup_configs(){ } ##################################################################################### -showfun auto_get_git_submodule -v auto_get_git_submodule +showfun auto_update_git_submodule +v auto_update_git_submodule # Backup if [[ ! "${SKIP_BACKUP}" == true ]]; then auto_backup_configs; fi From df23d79e0485d78ae4da500b8d52c441cc5fd58d Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 00:47:00 +0800 Subject: [PATCH 05/16] Fix outdate detect --- sdata/subcmd-install/1.deps-selector.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sdata/subcmd-install/1.deps-selector.sh b/sdata/subcmd-install/1.deps-selector.sh index 71f8cf066..27661925e 100644 --- a/sdata/subcmd-install/1.deps-selector.sh +++ b/sdata/subcmd-install/1.deps-selector.sh @@ -4,7 +4,7 @@ printf "${STY_CYAN}[$0]: 1. Install dependencies\n${STY_RST}" function outdate_detect(){ # Shallow clone prevent latest_commit_timestamp() from working. - x git_auto_unshallow + x git_auto_unshallow 2>&1>/dev/null local source_path="$1" local target_path="$2" @@ -119,12 +119,17 @@ elif [[ -f "./sdata/dist-${OS_DISTRO_ID}/install-deps.sh" ]]; then if [[ "${tmp_update_status}" =~ ^(OUTDATED|EMPTY_TARGET|EMPTY_SOURCE|FORCE_OUTDATED|WIP)$ ]]; then printf "${STY_RED}${STY_BOLD}===URGENT===${STY_RST}\n" printf "${STY_RED}" - printf "The community provided ./sdata/dist-${TARGET_ID}/ is not updated (update status: ${tmp_update_status}),\n" - printf "which means it does not fully reflect the latest changes of ./sdata/dist-arch/ .\n" - printf "You are highly recommended to abort this script, until someone (maybe you?) has updated the ./sdata/dist-${TARGET_ID}/ to fully reflect the latest changes in ./sdata/dist-arch/ .\n" - printf "PR is welcomed. Please see discussion#2140 for details.\n" + printf "The community provided ./sdata/dist-${TARGET_ID}/ is outdated (status: ${tmp_update_status}),\n" + printf "which means it probably does not reflect all latest changes of ./sdata/dist-arch/ .\n" + printf "\n" + printf "According to the actual changes, it may still works, but it can also work unexpectedly.\n" + printf "It's highly recommended to check the following links before continue:${STY_RST}\n" printf "${STY_UNDERLINE}https://github.com/end-4/dots-hyprland/discussions/2140${STY_RST}\n" - printf "${STY_RED}${STY_INVERT}If you are proceeding anyway, illogical-impulse will very likely not work as expected.${STY_RST}\n" + printf "${STY_UNDERLINE}https://github.com/end-4/dots-hyprland/commits/main/sdata/dist-arch${STY_RST}\n" + printf "${STY_UNDERLINE}https://github.com/end-4/dots-hyprland/commits/main/sdata/dist-${TARGET_ID}${STY_RST}\n" + printf "\n" + printf "${STY_PURPLE}${STY_INVERT}PR on ./sdata/dist-${TARGET_ID}/ to properly reflect the latest changes of ./sdata/dist-arch is welcomed.${STY_RST}\n" + printf "\n" if [ "$ask" = "false" ]; then echo "Urgent problem encountered, aborting...";exit 1 fi @@ -163,7 +168,7 @@ else printf "./sdata/dist-${OS_DISTRO_ID}/install-deps.sh not found.\n" printf "./sdata/dist-${TARGET_ID}/install-deps.sh will be used.\n" printf "1. It may disrupt your system and will likely fail without your manual intervention.\n" - printf "2. It's WIP and only contains small number of dependencies far from enough.\n" + printf "2. It is WIP and only contains small number of dependencies far from enough.\n" printf "Proceed only at your own risk.\n" printf "${STY_RST}" pause From 82ce9b866f60048c73e85316c3a7dc1ee50f8e3c Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 01:09:42 +0800 Subject: [PATCH 06/16] Update showhelp --- setup | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup b/setup index 5b15e286b..61467801a 100755 --- a/setup +++ b/setup @@ -11,7 +11,8 @@ set -e ##################################################################################### showhelp_global(){ -printf "${STY_CYAN}NOTE: +printf " +${STY_CYAN}NOTE: The old \"./install.sh\" is now \"./setup install\" The old \"./update.sh\" is now \"./setup exp-update\" The old \"./uninstall.sh\" is now \"./setup exp-uninstall\"${STY_RST} @@ -36,6 +37,8 @@ Subcommands: For each , use -h for details: $0 -h + +${STY_BOLD}${STY_CYAN}Access ${STY_UNDERLINE}https://ii.clsty.link${STY_RST} ${STY_BOLD}${STY_CYAN}for documentation about illogical-impulse.${STY_RST} " } case $1 in From f302da127508c742abcb887099323b0ffa57503b Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 31 Oct 2025 18:17:58 +0100 Subject: [PATCH 07/16] live light/dark switching for gtk4 --- dots/.config/matugen/config.toml | 4 +- .../{gtk/gtk-colors.css => gtk-3.0/gtk.css} | 0 .../.config/matugen/templates/gtk-4.0/gtk.css | 44 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) rename dots/.config/matugen/templates/{gtk/gtk-colors.css => gtk-3.0/gtk.css} (100%) create mode 100644 dots/.config/matugen/templates/gtk-4.0/gtk.css diff --git a/dots/.config/matugen/config.toml b/dots/.config/matugen/config.toml index d2b2a9a1c..1f47d1565 100644 --- a/dots/.config/matugen/config.toml +++ b/dots/.config/matugen/config.toml @@ -18,11 +18,11 @@ input_path = '~/.config/matugen/templates/fuzzel/fuzzel_theme.ini' output_path = '~/.config/fuzzel/fuzzel_theme.ini' [templates.gtk3] -input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' +input_path = '~/.config/matugen/templates/gtk-3.0/gtk.css' output_path = '~/.config/gtk-3.0/gtk.css' [templates.gtk4] -input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' +input_path = '~/.config/matugen/templates/gtk-4.0/gtk.css' output_path = '~/.config/gtk-4.0/gtk.css' [templates.kde_colors] diff --git a/dots/.config/matugen/templates/gtk/gtk-colors.css b/dots/.config/matugen/templates/gtk-3.0/gtk.css similarity index 100% rename from dots/.config/matugen/templates/gtk/gtk-colors.css rename to dots/.config/matugen/templates/gtk-3.0/gtk.css diff --git a/dots/.config/matugen/templates/gtk-4.0/gtk.css b/dots/.config/matugen/templates/gtk-4.0/gtk.css new file mode 100644 index 000000000..80b1d6975 --- /dev/null +++ b/dots/.config/matugen/templates/gtk-4.0/gtk.css @@ -0,0 +1,44 @@ +/* +* GTK Colors +* Generated with Matugen +*/ + +@media (prefers-color-scheme: light) { + @define-color accent_color {{colors.primary.light.hex}}; + @define-color accent_fg_color {{colors.on_primary.light.hex}}; + @define-color accent_bg_color {{colors.primary.light.hex}}; + @define-color window_bg_color {{colors.background.light.hex}}; + @define-color window_fg_color {{colors.on_background.light.hex}}; + @define-color headerbar_bg_color {{colors.surface_dim.light.hex}}; + @define-color headerbar_fg_color {{colors.on_surface.light.hex}}; + @define-color popover_bg_color {{colors.surface_dim.light.hex}}; + @define-color popover_fg_color {{colors.on_surface.light.hex}}; + @define-color view_bg_color {{colors.surface.light.hex}}; + @define-color view_fg_color {{colors.on_surface.light.hex}}; + @define-color card_bg_color {{colors.surface.light.hex}}; + @define-color card_fg_color {{colors.on_surface.light.hex}}; + @define-color sidebar_bg_color @window_bg_color; + @define-color sidebar_fg_color @window_fg_color; + @define-color sidebar_border_color @window_bg_color; + @define-color sidebar_backdrop_color @window_bg_color; +} + +@media (prefers-color-scheme: dark) { + @define-color accent_color {{colors.primary.dark.hex}}; + @define-color accent_fg_color {{colors.on_primary.dark.hex}}; + @define-color accent_bg_color {{colors.primary.dark.hex}}; + @define-color window_bg_color {{colors.background.dark.hex}}; + @define-color window_fg_color {{colors.on_background.dark.hex}}; + @define-color headerbar_bg_color {{colors.surface_dim.dark.hex}}; + @define-color headerbar_fg_color {{colors.on_surface.dark.hex}}; + @define-color popover_bg_color {{colors.surface_dim.dark.hex}}; + @define-color popover_fg_color {{colors.on_surface.dark.hex}}; + @define-color view_bg_color {{colors.surface.dark.hex}}; + @define-color view_fg_color {{colors.on_surface.dark.hex}}; + @define-color card_bg_color {{colors.surface.dark.hex}}; + @define-color card_fg_color {{colors.on_surface.dark.hex}}; + @define-color sidebar_bg_color @window_bg_color; + @define-color sidebar_fg_color @window_fg_color; + @define-color sidebar_border_color @window_bg_color; + @define-color sidebar_backdrop_color @window_bg_color; +} From 2c21eccac35143d460c0dba0d5e807abc2c27c8a Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 01:22:52 +0800 Subject: [PATCH 08/16] Update showhelp --- setup | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup b/setup index 61467801a..9309491e2 100755 --- a/setup +++ b/setup @@ -11,8 +11,7 @@ set -e ##################################################################################### showhelp_global(){ -printf " -${STY_CYAN}NOTE: +printf "${STY_CYAN}NOTE: The old \"./install.sh\" is now \"./setup install\" The old \"./update.sh\" is now \"./setup exp-update\" The old \"./uninstall.sh\" is now \"./setup exp-uninstall\"${STY_RST} @@ -24,6 +23,7 @@ Syntax: Subcommands: install (Re)Install/Update illogical-impulse. + Note: To update to the latest, manually run \"git pull\" first. install-deps Run the install step \"1. Install dependencies\" install-setups Run the install step \"2. Setup for permissions/services etc\" install-files Run the install step \"3. Copying config files\" From 835c11341639a4037a4545991a3cbc2880efaee6 Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 08:09:51 +0800 Subject: [PATCH 09/16] Move README.md into .github --- README.md => .github/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => .github/README.md (100%) diff --git a/README.md b/.github/README.md similarity index 100% rename from README.md rename to .github/README.md From b421691734c6e1f713c154b83de58d4b3a83cd04 Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 09:22:03 +0800 Subject: [PATCH 10/16] Update comment --- sdata/subcmd-install/3.files-exp.sh | 8 +++++++- sdata/subcmd-install/options.sh | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index 2606e3809..c483cdd98 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -1,7 +1,13 @@ # This script is meant to be sourced. # It's not for directly running. -# TODO: https://github.com/end-4/dots-hyprland/issues/2137 +# See https://github.com/end-4/dots-hyprland/issues/2137 +# TODO: Implement versioning, i.e. when user-defined yaml config file has version number mismatch with the default one, produce error. If only minor version number is not the same, the error can be ommitted via --exp-file-no-strict . +# TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. +# TODO: Implement symlink (readable or non-readable) as sync mode +# TODO: Implement --exp-file-reset-symlink to try to remove all symlink in .config and .local, which point to the local repo +# TODO: Update help and doc about `--exp-files` and the yaml config, including the possible values of mode. +# TODO: Support exclude pattern for each target to skip some files inside it. # Configuration file CONFIG_FILE="sdata/subcmd-install/3.files.yaml" diff --git a/sdata/subcmd-install/options.sh b/sdata/subcmd-install/options.sh index d60705354..5116ab9d5 100644 --- a/sdata/subcmd-install/options.sh +++ b/sdata/subcmd-install/options.sh @@ -27,14 +27,20 @@ Options for install: Possible values of : $(ls -A ${REPO_ROOT}/dots-extra/fontsets) ${STY_CYAN} New features (experimental): - --exp-files Use yaml-based config for the third step copying files. - This feature is ${STY_YELLOW}still on early stage${STY_CYAN}, feedback and contribution welcomed, - see https://github.com/end-4/dots-hyprland/issues/2137 for details. - --via-nix Use Nix and Home-manager to install dependencies. - This feature is ${STY_RED}working in progress${STY_CYAN}. Contribution is welcomed, - see https://github.com/end-4/dots-hyprland/issues/1061 for details. + --exp-files Use yaml-based config for the third step copying files. + This feature is ${STY_YELLOW}still on early stage${STY_CYAN}, + feedback and contribution welcomed, + see https://github.com/end-4/dots-hyprland/issues/2137 for details. + --via-nix Use Nix and Home-manager to install dependencies. + This feature is ${STY_RED}working in progress${STY_CYAN}. Contribution is welcomed, + see https://github.com/end-4/dots-hyprland/issues/1061 for details. ${STY_RST}" } +# TODO: implement options below for --exp-files +# --exp-files-path Use instead of the default yaml config +# --exp-files-no-strict Ignore error when minor version number is not the same +# --exp-files-regen Force copy the default config to ${EXP_FILE_PATH} +# (auto do this when not existed) cleancache(){ rm -rf "${REPO_ROOT}/cache" From e3549e639ed23c1dc56f737d8fd7418a08a98280 Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 09:38:47 +0800 Subject: [PATCH 11/16] Update comment --- sdata/dist-nix/home-manager/home.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdata/dist-nix/home-manager/home.nix b/sdata/dist-nix/home-manager/home.nix index be4541011..39d84584e 100644 --- a/sdata/dist-nix/home-manager/home.nix +++ b/sdata/dist-nix/home-manager/home.nix @@ -52,7 +52,9 @@ ##### Not work, to be solved ##### # swaylock pamtester + + # TODO: migrate all packages from dist-arch. Note that for each package, must know why it's needed and how it's used specifically, cuz things may be need tweak to properly use the package installed by Nix, especially those have hardcoded path /usr/* . ### illogical-impulse-audio libcava #cava lxqt.pavucontrol-qt #pavucontrol-qt From 09ad926642356cc6d776d1d112c7e02374590786 Mon Sep 17 00:00:00 2001 From: "Celestial.y" Date: Sat, 1 Nov 2025 09:46:27 +0800 Subject: [PATCH 12/16] Update comment --- sdata/subcmd-install/3.files-exp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index c483cdd98..3cdab2e27 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -4,7 +4,7 @@ # See https://github.com/end-4/dots-hyprland/issues/2137 # TODO: Implement versioning, i.e. when user-defined yaml config file has version number mismatch with the default one, produce error. If only minor version number is not the same, the error can be ommitted via --exp-file-no-strict . # TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. -# TODO: Implement symlink (readable or non-readable) as sync mode +# TODO: Implement symlink (both read-write and read-only) as sync mode # TODO: Implement --exp-file-reset-symlink to try to remove all symlink in .config and .local, which point to the local repo # TODO: Update help and doc about `--exp-files` and the yaml config, including the possible values of mode. # TODO: Support exclude pattern for each target to skip some files inside it. From 17984c812fddc3733791c224a15f667f3137e05f Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 09:52:34 +0800 Subject: [PATCH 13/16] Update files-exp; Rename 3.files.yaml to 3.files-exp.yaml --- sdata/subcmd-install/3.files-exp.sh | 294 +++++++++--------- .../{3.files.yaml => 3.files-exp.yaml} | 0 sdata/subcmd-install/options.sh | 5 - 3 files changed, 152 insertions(+), 147 deletions(-) rename sdata/subcmd-install/{3.files.yaml => 3.files-exp.yaml} (100%) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index c483cdd98..dd227fd4a 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -2,139 +2,149 @@ # It's not for directly running. # See https://github.com/end-4/dots-hyprland/issues/2137 +# +# Stage 1 todos: +# TODO: add --exp-files-path Use instead of the default yaml config +# TODO: add --exp-files-regen Force copy the default config to ${EXP_FILE_PATH} (auto do this when not existed) # TODO: Implement versioning, i.e. when user-defined yaml config file has version number mismatch with the default one, produce error. If only minor version number is not the same, the error can be ommitted via --exp-file-no-strict . -# TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. +# TODO: add --exp-files-no-strict Ignore error when minor version number is not the same +# +# Stage 2 todos: # TODO: Implement symlink (readable or non-readable) as sync mode -# TODO: Implement --exp-file-reset-symlink to try to remove all symlink in .config and .local, which point to the local repo +# TODO: add --exp-file-reset-symlink Try to remove all symlink in .config and .local, which point to the local repo # TODO: Update help and doc about `--exp-files` and the yaml config, including the possible values of mode. +# +# Stage 3 todos: +# TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. # TODO: Support exclude pattern for each target to skip some files inside it. + # Configuration file -CONFIG_FILE="sdata/subcmd-install/3.files.yaml" +CONFIG_FILE="sdata/subcmd-install/3.files-exp.yaml" # ============================================================================= wizard_update_preferences() { - echo -e "${STY_CYAN}=== Dotfiles Customization ===${STY_RESET}" - + echo -e "${STY_CYAN}=== Dotfiles Customization ===${STY_RESET}" + # Get current preferences current_shell=$(yq '.user_preferences.shell // "fish"' "$CONFIG_FILE") current_terminal=$(yq '.user_preferences.terminal // "kitty"' "$CONFIG_FILE") current_keybindings=$(yq '.user_preferences.keybindings // "default"' "$CONFIG_FILE") - + echo "Current preferences:" echo " Shell: $current_shell" echo " Terminal: $current_terminal" echo " Keybindings: $current_keybindings" echo - + # Shell selection echo "Which shell do you prefer?" echo "1) fish (default)" echo "2) zsh" read -p "Enter choice [1-2]: " shell_choice - + case "$shell_choice" in - 1|"") shell="fish" ;; - 2) shell="zsh" ;; - *) echo "Invalid choice, using fish"; shell="fish" ;; + 1|"") shell="fish" ;; + 2) shell="zsh" ;; + *) echo "Invalid choice, using fish"; shell="fish" ;; esac - + # Terminal selection echo echo "Which terminal do you prefer?" echo "1) kitty (default)" echo "2) foot" read -p "Enter choice [1-2]: " terminal_choice - + case "$terminal_choice" in - 1|"") terminal="kitty" ;; - 2) terminal="foot" ;; - *) echo "Invalid choice, using kitty"; terminal="kitty" ;; + 1|"") terminal="kitty" ;; + 2) terminal="foot" ;; + *) echo "Invalid choice, using kitty"; terminal="kitty" ;; esac - + # Keybindings selection echo echo "Which keybinding style do you prefer?" echo "1) default (arrow keys)" echo "2) vim (H/J/K/L)" read -p "Enter choice [1-2]: " keybind_choice - + case "$keybind_choice" in - 1|"") keybindings="default" ;; - 2) keybindings="vim" ;; - *) echo "Invalid choice, using default"; keybindings="default" ;; + 1|"") keybindings="default" ;; + 2) keybindings="vim" ;; + *) echo "Invalid choice, using default"; keybindings="default" ;; esac - + # Update YAML in-place yq -i ".user_preferences.shell = \"$shell\"" "$CONFIG_FILE" yq -i ".user_preferences.terminal = \"$terminal\"" "$CONFIG_FILE" yq -i ".user_preferences.keybindings = \"$keybindings\"" "$CONFIG_FILE" - + echo echo "Preferences updated!" -} + } # Get user preference get_pref() { - yq -r ".user_preferences.$1" "$CONFIG_FILE" + yq -r ".user_preferences.$1" "$CONFIG_FILE" } # Check if pattern should be processed based on user preferences should_process_pattern() { - local pattern="$1" - local condition=$(echo "$pattern" | yq '.condition // "true"') + local pattern="$1" + local condition=$(echo "$pattern" | yq '.condition // "true"') # If no condition or condition is "true", always process if [[ "$condition" == "true" ]]; then return 0 fi - + # Extract the preference type and value from condition local type=$(echo "$condition" | yq '.type') local value=$(echo "$condition" | yq '.value') - + [[ "$(get_pref "$type")" == "$value" ]] - -} + + } # Compare hashes of files/directories, return true if they are the same, false otherwise files_are_same() { - local path1="$1" - local path2="$2" - + local path1="$1" + local path2="$2" + # Check if paths exist if [[ ! -e "$path1" || ! -e "$path2" ]]; then - return 1 + return 1 fi - + # For directories, use find + md5sum to compare recursively # For files, use md5sum directly if [[ -d "$path1" && -d "$path2" ]]; then - # Compare directory contents using find and md5sum - local hash1=$(find "$path1" -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') - local hash2=$(find "$path2" -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') - [[ "$hash1" == "$hash2" ]] + # Compare directory contents using find and md5sum + local hash1=$(find "$path1" -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') + local hash2=$(find "$path2" -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') + [[ "$hash1" == "$hash2" ]] elif [[ -f "$path1" && -f "$path2" ]]; then - # Compare file hashes - local hash1=$(md5sum "$path1" | awk '{print $1}') - local hash2=$(md5sum "$path2" | awk '{print $1}') - [[ "$hash1" == "$hash2" ]] + # Compare file hashes + local hash1=$(md5sum "$path1" | awk '{print $1}') + local hash2=$(md5sum "$path2" | awk '{print $1}') + [[ "$hash1" == "$hash2" ]] else - # One is a file, one is a directory - different types - return 1 + # One is a file, one is a directory - different types + return 1 fi -} + } # Find next backup number get_next_backup_number() { - local base_path="$1" - local counter=1 + local base_path="$1" + local counter=1 - while [[ -e "${base_path}.old.${counter}" ]]; do - ((counter++)) - done + while [[ -e "${base_path}.old.${counter}" ]]; do + ((counter++)) + done - echo $counter + echo $counter } # ============================================================================= @@ -152,118 +162,118 @@ readarray patterns < <(yq -o=j -I=0 '.patterns[]' "$CONFIG_FILE") # Process each pattern for pattern in "${patterns[@]}"; do - from=$(echo "$pattern" | yq '.from' - | envsubst) - to=$(echo "$pattern" | yq '.to' - | envsubst) - mode=$(echo "$pattern" | yq '.mode' - | envsubst) - condition=$(echo "$pattern" | yq '.condition // "true"') - + from=$(echo "$pattern" | yq '.from' - | envsubst) + to=$(echo "$pattern" | yq '.to' - | envsubst) + mode=$(echo "$pattern" | yq '.mode' - | envsubst) + condition=$(echo "$pattern" | yq '.condition // "true"') + # Handle fontconfig fontset override # If FONTSET_DIR_NAME is set and this is the fontconfig pattern, use the fontset instead if [[ "$from" == "dots/.config/fontconfig" ]] && [[ -n "${FONTSET_DIR_NAME:-}" ]]; then - from="dots-extra/fontsets/${FONTSET_DIR_NAME}" - echo "Using fontset \"${FONTSET_DIR_NAME}\" for fontconfig" + from="dots-extra/fontsets/${FONTSET_DIR_NAME}" + echo "Using fontset \"${FONTSET_DIR_NAME}\" for fontconfig" fi - + # Check if pattern should be processed if ! should_process_pattern "$pattern"; then - # Format condition message nicely - if [[ "$condition" != "true" ]]; then - cond_type=$(echo "$condition" | yq -r '.type // ""') - cond_value=$(echo "$condition" | yq -r '.value // ""') - if [[ -n "$cond_type" && -n "$cond_value" ]]; then - echo "Skipping $from -> $to (condition not met: $cond_type == '$cond_value')" - else - echo "Skipping $from -> $to (condition not met)" - fi + # Format condition message nicely + if [[ "$condition" != "true" ]]; then + cond_type=$(echo "$condition" | yq -r '.type // ""') + cond_value=$(echo "$condition" | yq -r '.value // ""') + if [[ -n "$cond_type" && -n "$cond_value" ]]; then + echo "Skipping $from -> $to (condition not met: $cond_type == '$cond_value')" else - echo "Skipping $from -> $to (condition not met)" + echo "Skipping $from -> $to (condition not met)" fi - continue + else + echo "Skipping $from -> $to (condition not met)" + fi + continue fi - + echo "Processing: $from -> $to (mode: $mode)" - + # Build exclude arguments for rsync excludes=() if echo "$pattern" | yq -e '.excludes' >/dev/null 2>&1; then - while IFS= read -r exclude; do - excludes+=(--exclude "$exclude") - done < <(echo "$pattern" | yq -r '.excludes[]') + while IFS= read -r exclude; do + excludes+=(--exclude "$exclude") + done < <(echo "$pattern" | yq -r '.excludes[]') fi - + # Check if source exists if [[ ! -e "$from" ]]; then - echo "Warning: Source does not exist: $from (skipping)" - continue + echo "Warning: Source does not exist: $from (skipping)" + continue fi - + # Ensure destination directory exists for files if [[ -f "$from" ]]; then - v mkdir -p "$(dirname "$to")" + v mkdir -p "$(dirname "$to")" fi - + # Execute based on mode case $mode in - "sync") - if [[ -d "$from" ]]; then - warning_rsync_delete - v rsync -av --delete "${excludes[@]}" "$from/" "$to/" - else - warning_rsync_normal - # For files, don't use trailing slash and don't use --delete - v rsync -av "${excludes[@]}" "$from" "$to" - fi - ;; - "soft") - warning_rsync_normal - if [[ -d "$from" ]]; then - v rsync -av "${excludes[@]}" "$from/" "$to/" - else - # For files, don't use trailing slash - v rsync -av "${excludes[@]}" "$from" "$to" - fi - ;; - "hard") + "sync") + if [[ -d "$from" ]]; then + warning_rsync_delete + v rsync -av --delete "${excludes[@]}" "$from/" "$to/" + else + warning_rsync_normal + # For files, don't use trailing slash and don't use --delete + v rsync -av "${excludes[@]}" "$from" "$to" + fi + ;; + "soft") + warning_rsync_normal + if [[ -d "$from" ]]; then + v rsync -av "${excludes[@]}" "$from/" "$to/" + else + # For files, don't use trailing slash + v rsync -av "${excludes[@]}" "$from" "$to" + fi + ;; + "hard") + v cp -r "$from" "$to" + ;; + "hard-backup") + if [[ -e "$to" ]]; then + if files_are_same "$from" "$to"; then + echo "Files are identical, skipping backup" + else + backup_number=$(get_next_backup_number "$to") + v mv "$to" "$to.old.$backup_number" v cp -r "$from" "$to" - ;; - "hard-backup") - if [[ -e "$to" ]]; then - if files_are_same "$from" "$to"; then - echo "Files are identical, skipping backup" - else - backup_number=$(get_next_backup_number "$to") - v mv "$to" "$to.old.$backup_number" - v cp -r "$from" "$to" - fi - else - v cp -r "$from" "$to" - fi - ;; - "soft-backup") - if [[ -e "$to" ]]; then - if files_are_same "$from" "$to"; then - echo "Files are identical, skipping backup" - else - v cp -r "$from" "$to.new" - fi - else - v cp -r "$from" "$to" - fi - ;; - "skip") - echo "Skipping $from" - ;; - "skip-if-exists") - if [[ -e "$to" ]]; then - echo "Skipping $from (destination exists)" - else - v cp -r "$from" "$to" - fi - ;; - *) - echo "Unknown mode: $mode" - ;; + fi + else + v cp -r "$from" "$to" + fi + ;; + "soft-backup") + if [[ -e "$to" ]]; then + if files_are_same "$from" "$to"; then + echo "Files are identical, skipping backup" + else + v cp -r "$from" "$to.new" + fi + else + v cp -r "$from" "$to" + fi + ;; + "skip") + echo "Skipping $from" + ;; + "skip-if-exists") + if [[ -e "$to" ]]; then + echo "Skipping $from (destination exists)" + else + v cp -r "$from" "$to" + fi + ;; + *) + echo "Unknown mode: $mode" + ;; esac -done + done ##################################################################################### diff --git a/sdata/subcmd-install/3.files.yaml b/sdata/subcmd-install/3.files-exp.yaml similarity index 100% rename from sdata/subcmd-install/3.files.yaml rename to sdata/subcmd-install/3.files-exp.yaml diff --git a/sdata/subcmd-install/options.sh b/sdata/subcmd-install/options.sh index 5116ab9d5..c5e860215 100644 --- a/sdata/subcmd-install/options.sh +++ b/sdata/subcmd-install/options.sh @@ -36,11 +36,6 @@ New features (experimental): see https://github.com/end-4/dots-hyprland/issues/1061 for details. ${STY_RST}" } -# TODO: implement options below for --exp-files -# --exp-files-path Use instead of the default yaml config -# --exp-files-no-strict Ignore error when minor version number is not the same -# --exp-files-regen Force copy the default config to ${EXP_FILE_PATH} -# (auto do this when not existed) cleancache(){ rm -rf "${REPO_ROOT}/cache" From efae444942db1284411d857277d0b931778deb35 Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 10:16:45 +0800 Subject: [PATCH 14/16] Update files-exp --- sdata/subcmd-install/3.files-exp.sh | 4 ++-- sdata/subcmd-install/3.files-exp.yaml | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index b3833251c..0bccb092e 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -4,6 +4,7 @@ # See https://github.com/end-4/dots-hyprland/issues/2137 # # Stage 1 todos: +# TODO: Properly handle hyprland config, ~/.config/hypr/hyprland.conf should be overwritten only when firstrun # TODO: add --exp-files-path Use instead of the default yaml config # TODO: add --exp-files-regen Force copy the default config to ${EXP_FILE_PATH} (auto do this when not existed) # TODO: Implement versioning, i.e. when user-defined yaml config file has version number mismatch with the default one, produce error. If only minor version number is not the same, the error can be ommitted via --exp-file-no-strict . @@ -16,8 +17,7 @@ # # Stage 3 todos: # TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. -# TODO: Support exclude pattern for each target to skip some files inside it. - +# TODO: Implement variants like keybindings, terminals, etc under user_preferences. # Configuration file CONFIG_FILE="sdata/subcmd-install/3.files-exp.yaml" diff --git a/sdata/subcmd-install/3.files-exp.yaml b/sdata/subcmd-install/3.files-exp.yaml index 59ed69ebc..5282e0594 100644 --- a/sdata/subcmd-install/3.files-exp.yaml +++ b/sdata/subcmd-install/3.files-exp.yaml @@ -1,3 +1,11 @@ +# The possible values of `mode`: (by default `sync`) +# - `sync`: Make the destination completely the same as the source. +# - `soft`: Skip existing files when copying +# - `hard`: Overwrite existing files when copying +# - `soft-backup`: If target file exists, copy source file to `*.new`. Do not create `*.new` but skip coyping when source and target HASH values are exactly the same. +# - `hard-backup`: If target file exists, create backup by renaming it to `*.old.` where `` is a number increment from 1 to prevent backup gets overwritten when running twice. (Keep in mind that this script must be idempotent.) Also must compare the actual file content by using MD5 HASH value to prevent generating lots of `*.old.`s when runnng multiple times. Do not create backup but skip coyping when source and target HASH values are exactly the same. +# - `skip`: Skip this step +# - `skip-if-exists`: Skip this step if target exists version: "1.0" user_preferences: shell: "fish" # fish | zsh From 9c89099cf1351d2cd74d06c8f7100598e7a6d7aa Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 10:18:52 +0800 Subject: [PATCH 15/16] Update comment in files-exp --- sdata/subcmd-install/3.files-exp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index 0bccb092e..a25f76834 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -16,7 +16,7 @@ # TODO: Update help and doc about `--exp-files` and the yaml config, including the possible values of mode. # # Stage 3 todos: -# TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. +# TODO: Implement user-define yaml with merging (override) ability for user who only wants little customization and is satisfied with most of the defaults. User can use `./install-files.yaml` as custom config. When `./install-files.yaml` exists and have correct major version number, merge it together with `sdata/step/3.install-files.yaml` to generate a `cache/install-files.final.yaml` to determine how to copy files. About how to merge two yaml files, I know some software such as rime input method and docker supports a override yaml config, which we may reference from. See also https://github.com/mikefarah/yq/discussions/1437 # TODO: Implement variants like keybindings, terminals, etc under user_preferences. # Configuration file From 1bea1e8c914593b6c838521755f2f90c0e58901b Mon Sep 17 00:00:00 2001 From: clsty Date: Sat, 1 Nov 2025 10:35:33 +0800 Subject: [PATCH 16/16] Update comment --- sdata/subcmd-install/3.files-exp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdata/subcmd-install/3.files-exp.sh b/sdata/subcmd-install/3.files-exp.sh index a25f76834..8f0bcd8f9 100644 --- a/sdata/subcmd-install/3.files-exp.sh +++ b/sdata/subcmd-install/3.files-exp.sh @@ -11,7 +11,7 @@ # TODO: add --exp-files-no-strict Ignore error when minor version number is not the same # # Stage 2 todos: -# TODO: Implement symlink (both read-write and read-only) as sync mode +# TODO: Implement bool key symlink (both read-write and read-only), when the value of `symlink` is true, then instead using `rsync` or `cp`, use `ln`. # TODO: add --exp-file-reset-symlink Try to remove all symlink in .config and .local, which point to the local repo # TODO: Update help and doc about `--exp-files` and the yaml config, including the possible values of mode. #