diff --git a/AGENTS.md b/AGENTS.md
index 031b53b..456c46e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -15,7 +15,7 @@ Only entries that would be missed without explicit help are included.
| Task | Command | Why it matters |
|------|---------|----------------|
-| **Install required programs** | `bash term/setup.sh`
`bash _install_skripte/install_basic_pcks.sh`
`bash _install_skripte/install_hypr_pcks.sh`
`bash _install_skripte/install_kreation_pcks.sh` | These scripts install Neovim, hyprland, VST runtime, and other utilities. Edit `term/packages.txt` to add/remove terminal packages. |
+| **Install required programs** | `bash term/setup.sh`
`bash _install_skripte/install_basic_pcks.sh`
`bash hypr/setup.sh`
`bash _install_skripte/install_kreation_pcks.sh` | These scripts install Neovim, hyprland, VST runtime, and other utilities. Edit `term/packages.txt` to add/remove terminal packages. |
| **Link configuration directories** | `ln -s ~/.dotfiles/hypr/.config/hypr ~/.config/hypr`
`ln -s ~/.dotfiles/term/.config/nvim ~/.config/nvim` | The repository expects the configs to live in `~/.config`. |
| **Add VST plugin** | Copy `kreation/.vst3/MT-PowerDrumKit.vst3` into your DAW’s plugins folder (usually `~/.vst`). | The repo contains a pre‑built VST for use in audio software. |
@@ -26,7 +26,7 @@ Only entries that would be missed without explicit help are included.
| Item | Detail |
|------|--------|
-| **Wayland compositor** | Requires `hyprland` (and dependencies like `wlroots`). The script `install_hypr_pcks.sh` installs it. |
+| **Wayland compositor** | Requires `hyprland` (and dependencies like `wlroots`). The script `hypr/setup.sh` installs it from `hypr/packages.txt`. |
| **MIME defaults** | Run `bash hypr/.config/hypr/scripts/ensure-env.sh` after installing to set environment variables (`$XDG_DATA_HOME`, etc.). |
| **Dolphin file associations** | `bash hypr/.config/hypr/scripts/fix_dolphin_file_associations.sh` must be executed once to register the compositor with KDE. |
| **Portal host override** | `bash hypr/.config/hypr/scripts/portal-host-override.sh` fixes Wayland portal issues on some distros. |
diff --git a/Makefile b/Makefile
index 55d0fdc..5aa648e 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ basic:
bash basic/setup.sh
term: basic
- bash term/setup.sh
+ bash term/scripts/setup.sh
stow term
utils: basic
@@ -17,11 +17,8 @@ utils: basic
bash _install_skripte/nextcloud.sh
hypr: basic
- bash _install_skripte/install_hypr_pcks.sh
+ bash hypr/scripts/setup.sh
stow hypr
- bash hypr/.config/hypr/scripts/ensure-env.sh
- bash hypr/.config/hypr/scripts/portal-host-override.sh
- bash hypr/.config/hypr/scripts/fix_dolphin_file_associations.sh
kreation: basic
bash _install_skripte/install_kreation_pcks.sh
diff --git a/_install_skripte/install_hypr_pcks.sh b/_install_skripte/install_hypr_pcks.sh
deleted file mode 100755
index 2220c4a..0000000
--- a/_install_skripte/install_hypr_pcks.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-sudo pacman -S --needed \
- hyprland \
- hyprlauncher \
- xdg-desktop-portal-hyprland \
- hyprpolkitagent \
- pantheon-shortcut-overlay \
- waybar \
- hyprpaper \
- wpaperd \
- wev \
- hyprlock \
- hypridle \
- nwg-drawer \
- wl-clipboard \
- swaync \
- hyprshot \
- rofi
-
-yay -S --needed \
- hyprshutdown \
- hyprtile
-
-# Install hyprltm (network manager)
-curl -s https://raw.githubusercontent.com/hyprltm/hyprltm-net/main/setup.sh | bash
-echo 'fish_add_path -m $HOME/.local/bin' >> ~/.config/fish/config.fish
diff --git a/hypr/scripts/packages.txt b/hypr/scripts/packages.txt
new file mode 100644
index 0000000..c2893a1
--- /dev/null
+++ b/hypr/scripts/packages.txt
@@ -0,0 +1,34 @@
+# ---------------------------------------------------------------------------
+# Hyprland compositor package list for hypr/setup.sh
+#
+# Wayland compositor, its ecosystem tools (lockscreen, idle, wallpaper,
+# notification center, screenshot, launcher) and supporting utilities.
+# `hyprltm` (network manager) is installed via a post-install hook in
+# setup.sh since it is not available as a standard pacman/aur package.
+#
+# - Lines starting with '#' and blank lines are ignored.
+# - Use "@pacman", "@aur" or "@npm" markers to switch section.
+# - The default section is @pacman.
+# ---------------------------------------------------------------------------
+
+@pacman
+hyprland
+hyprlauncher
+xdg-desktop-portal-hyprland
+hyprpolkitagent
+pantheon-shortcut-overlay
+waybar
+hyprpaper
+wpaperd
+wev
+hyprlock
+hypridle
+nwg-drawer
+wl-clipboard
+swaync
+hyprshot
+rofi
+
+@aur
+hyprshutdown
+hyprtile
diff --git a/hypr/scripts/setup.sh b/hypr/scripts/setup.sh
new file mode 100644
index 0000000..95f4408
--- /dev/null
+++ b/hypr/scripts/setup.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PACKAGES_FILE="$SCRIPT_DIR/packages.txt"
+
+# ---------------------------------------------------------------------------
+# Read packages.txt, split into pacman / aur / npm sections.
+# ---------------------------------------------------------------------------
+read_packages() {
+ local section="pacman"
+ local current
+ current=""
+ while IFS= read -r line || [[ -n "$line" ]]; do
+ current="${line%%#*}"
+ current="${current##*( )}"
+ current="${current%%*( )}"
+ [[ -z "$current" ]] && continue
+ case "$current" in
+ @pacman) section="pacman" ;;
+ @aur) section="aur" ;;
+ @npm) section="npm" ;;
+ *)
+ case "$section" in
+ pacman) pacman_pkgs+=("$current") ;;
+ aur) aur_pkgs+=("$current") ;;
+ npm) npm_pkgs+=("$current") ;;
+ esac
+ ;;
+ esac
+ done < "$PACKAGES_FILE"
+}
+
+declare -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
+
+# ---------------------------------------------------------------------------
+# Install sections.
+# ---------------------------------------------------------------------------
+install_pacman() {
+ if ((${#pacman_pkgs[@]})); then
+ echo "==> Installiere Pacman-Pakete: ${pacman_pkgs[*]}"
+ yay -S --needed "${pacman_pkgs[@]}"
+ fi
+}
+
+install_aur() {
+ if ((${#aur_pkgs[@]})); then
+ echo "==> Installiere AUR-Pakete: ${aur_pkgs[*]}"
+ yay -S --needed "${aur_pkgs[@]}"
+ fi
+}
+
+install_npm() {
+ if ((${#npm_pkgs[@]})); then
+ echo "==> Installiere globale npm-Pakete: ${npm_pkgs[*]}"
+ npm install -g "${npm_pkgs[@]}"
+ fi
+}
+
+# ---------------------------------------------------------------------------
+# Post-install: hyprltm (network manager) via upstream script.
+# ---------------------------------------------------------------------------
+install_hyprltm() {
+ if command -v hyprltm >/dev/null 2>&1; then
+ echo "hyprltm bereits installiert; fahre fort."
+ return
+ fi
+ echo "Installiere hyprltm (Network Manager) ..."
+ curl -s https://raw.githubusercontent.com/hyprltm/hyprltm-net/main/setup.sh | bash
+}
+
+# ---------------------------------------------------------------------------
+# Post-install: ensure fish PATH includes ~/.local/bin (for hyprltm).
+# ---------------------------------------------------------------------------
+add_fish_local_bin_path() {
+ local fish_config="$HOME/.config/fish/config.fish"
+ if [[ -f "$fish_config" ]] && grep -q '\$HOME/.local/bin' "$fish_config"; then
+ echo "fish ~/.local/bin PATH bereits gesetzt; fahre fort."
+ return
+ fi
+ echo "Fuege ~/.local/bin zum fish-PATH hinzu ..."
+ echo 'fish_add_path -m $HOME/.local/bin' >> "$fish_config"
+}
+
+# ---------------------------------------------------------------------------
+# Post-install: run Hyprland environment & desktop integration scripts.
+# ---------------------------------------------------------------------------
+run_hypr_scripts() {
+ local scripts_dir="$SCRIPT_DIR/../.config/hypr/scripts"
+
+ echo "==> Fuehre ensure-env.sh aus ..."
+ bash "$scripts_dir/ensure-env.sh"
+
+ echo "==> Fuehre portal-host-override.sh aus ..."
+ bash "$scripts_dir/portal-host-override.sh"
+
+ echo "==> Fuehre fix_dolphin_file_associations.sh aus ..."
+ bash "$scripts_dir/fix_dolphin_file_associations.sh"
+}
+
+# ---------------------------------------------------------------------------
+# Main
+# ---------------------------------------------------------------------------
+main() {
+ echo "==> Lese Paketliste: $PACKAGES_FILE"
+ read_packages
+
+ install_pacman
+ install_aur
+ install_npm
+
+ install_hyprltm
+ add_fish_local_bin_path
+ run_hypr_scripts
+
+ echo "Fertig. Hyprland und das Compositor-Okosystem sind eingerichtet."
+}
+
+main
diff --git a/term/packages.txt b/term/scripts/packages.txt
similarity index 100%
rename from term/packages.txt
rename to term/scripts/packages.txt
diff --git a/term/setup.sh b/term/scripts/setup.sh
similarity index 100%
rename from term/setup.sh
rename to term/scripts/setup.sh
diff --git a/test/entrypoint-test.sh b/test/entrypoint-test.sh
index a5db66f..be0739b 100755
--- a/test/entrypoint-test.sh
+++ b/test/entrypoint-test.sh
@@ -152,12 +152,20 @@ NOOP
export PATH="$HOME/bin:$PATH"
# 2c. setup.sh package parsing sanity (mirrors read_packages) for each
- # package dir: basic/term/utils.
- for d in basic term utils; do
- if ( cd "$REPO" && bash -n "$d/setup.sh" ); then
- say_ok "$d/setup.sh syntax OK"
+ # package dir: basic/term/utils/hypr. term/ and hypr/ keep their scripts
+ # inside scripts/ so stowing the top-level dir only creates .config/ links.
+ for d in basic term utils hypr; do
+ if [[ "$d" == "term" || "$d" == "hypr" ]]; then
+ SETUP_PATH="$d/scripts/setup.sh"
+ PKG_PATH="$d/scripts/packages.txt"
else
- say_fail "$d/setup.sh syntax error"
+ SETUP_PATH="$d/setup.sh"
+ PKG_PATH="$d/packages.txt"
+ fi
+ if ( cd "$REPO" && bash -n "$SETUP_PATH" ); then
+ say_ok "$SETUP_PATH syntax OK"
+ else
+ say_fail "$SETUP_PATH syntax error"
fi
pacman_count=$(awk '
/^@pacman/{s="pacman"; next}
@@ -167,9 +175,9 @@ NOOP
/^[[:space:]]*$/{next}
s=="pacman"{pc++} s=="aur"{ac++} s=="npm"{nc++}
END{printf "%d %d %d", pc,ac,nc}
- ' "$REPO/$d/packages.txt")
+ ' "$REPO/$PKG_PATH")
read -r PC AC NC <<< "$pacman_count"
- say_ok "$d/packages.txt -> ${PC} pacman, ${AC} aur, ${NC} npm entries"
+ say_ok "$PKG_PATH -> ${PC} pacman, ${AC} aur, ${NC} npm entries"
done
# 2c2. Every @pacman entry in every packages.txt must resolve in the
@@ -179,7 +187,12 @@ NOOP
# AUR-only name (e.g. `rd`) fails here before any install happens.
header "package resolvability (@pacman entries)"
resolv_fail=0
- for d in basic term utils; do
+ for d in basic term utils hypr; do
+ if [[ "$d" == "term" || "$d" == "hypr" ]]; then
+ PKG_PATH="$d/scripts/packages.txt"
+ else
+ PKG_PATH="$d/packages.txt"
+ fi
while IFS= read -r pkg; do
[[ -z "$pkg" ]] && continue
if pacman -S --print-format '%n' "$pkg" >/dev/null 2>&1; then
@@ -195,7 +208,7 @@ NOOP
/^@npm/{s="skip"; next}
/^[[:space:]]*#/{next} /^[[:space:]]*$/{next}
s=="pacman"{ sub(/^[^\/]*\//,""); print }
- ' "$REPO/$d/packages.txt")
+ ' "$REPO/$PKG_PATH")
done
# 2d. If network allowed and not skipped, actually install the pacman
@@ -205,20 +218,20 @@ NOOP
header "make term (pacman + npm packages, AUR skipped)"
# Patch packages.txt: keep @pacman and @npm (@npm runs via sudo npm
# in the container), drop @aur so we don't hit AUR builds.
- cp "$REPO/term/packages.txt" "$HOME/packages.txt.full"
+ cp "$REPO/term/scripts/packages.txt" "$HOME/packages.txt.full"
awk '
/^@aur$/{s="skip"}; /^@npm$/{s="npm"}; /^@pacman$/{s="pacman"}
{ if (s!="skip" && NF>0 && $1 !~ /^#/) print }
- ' "$REPO/term/packages.txt" > "$HOME/packages.txt.term-smoke"
+ ' "$REPO/term/scripts/packages.txt" > "$HOME/packages.txt.term-smoke"
# pacman-only list for verify_packages.sh (npm packages are not in
# the pacman DB).
awk '
/^@aur$/{s="skip"}; /^@npm$/{s="skip"}; /^@pacman$/{s="pacman"}
{ if (s!="skip" && NF>0 && $1 !~ /^#/) print }
- ' "$REPO/term/packages.txt" > "$HOME/packages.txt.term-only"
+ ' "$REPO/term/scripts/packages.txt" > "$HOME/packages.txt.term-only"
# set a scratch HOME for setup.sh so it doesn't touch the real one.
mkdir -p "$HOME/term"
- cp "$REPO/term/setup.sh" "$HOME/term/setup.sh"
+ cp "$REPO/term/scripts/setup.sh" "$HOME/term/setup.sh"
cp "$HOME/packages.txt.term-smoke" "$HOME/term/packages.txt"
# chsh is stubbed via $HOME/bin so even `chsh` works without a pty.
setup_ok=0
diff --git a/test/lint.sh b/test/lint.sh
index f285ce1..c191838 100755
--- a/test/lint.sh
+++ b/test/lint.sh
@@ -80,24 +80,33 @@ fi
# 4. packages.txt parsing sanity (mirrors each setup.sh read_packages).
# ---------------------------------------------------------------------------
echo "== Checking packages.txt markers =="
-for pkgdir in term basic utils; do
- if ! [[ -f "$pkgdir/packages.txt" ]]; then
- say_fail "$pkgdir/packages.txt missing"
+for pkgdir in term basic utils hypr; do
+ # term/ and hypr/ keep packages.txt + setup.sh inside scripts/ so stowing
+ # the top-level dir only creates .config/ symlinks.
+ if [[ "$pkgdir" == "term" || "$pkgdir" == "hypr" ]]; then
+ PKG_FILE="$pkgdir/scripts/packages.txt"
+ SETUP_FILE="$pkgdir/scripts/setup.sh"
+ else
+ PKG_FILE="$pkgdir/packages.txt"
+ SETUP_FILE="$pkgdir/setup.sh"
+ fi
+ if ! [[ -f "$PKG_FILE" ]]; then
+ say_fail "$PKG_FILE missing"
continue
fi
- if grep -q '^@pacman' "$pkgdir/packages.txt"; then
- say_pass "$pkgdir/packages.txt declares @pacman section"
+ if grep -q '^@pacman' "$PKG_FILE"; then
+ say_pass "$PKG_FILE declares @pacman section"
else
- say_fail "$pkgdir/packages.txt missing @pacman marker"
+ say_fail "$PKG_FILE missing @pacman marker"
fi
# every @aur/@npm marker must be matched by a real consumer in setup.sh
for marker in '@aur' '@npm'; do
- if grep -q "^$marker" "$pkgdir/packages.txt"; then
- grep -q "$marker" "$pkgdir/setup.sh" \
- && say_pass "$pkgdir/packages.txt $marker handled by $pkgdir/setup.sh" \
- || say_fail "$pkgdir/packages.txt uses $marker but $pkgdir/setup.sh does not handle it"
+ if grep -q "^$marker" "$PKG_FILE"; then
+ grep -q "$marker" "$SETUP_FILE" \
+ && say_pass "$PKG_FILE $marker handled by $SETUP_FILE" \
+ || say_fail "$PKG_FILE uses $marker but $SETUP_FILE does not handle it"
else
- say_pass "$pkgdir/packages.txt has no $marker section"
+ say_pass "$PKG_FILE has no $marker section"
fi
done
done
diff --git a/test/verify_packages.sh b/test/verify_packages.sh
index 9d4a606..d3fdadf 100755
--- a/test/verify_packages.sh
+++ b/test/verify_packages.sh
@@ -54,6 +54,18 @@ declare -A BINS=(
[fzf]="fzf --version"
[chromium]="chromium --version"
[locate]="locate --version"
+ # Hyprland compositor & ecosystem
+ [hyprland]="hyprctl version"
+ [waybar]="waybar --version"
+ [hyprlock]="hyprlock --version"
+ [hypridle]="hypridle --version"
+ [hyprpaper]="hyprpaper -v"
+ [rofi]="rofi -v"
+ [swaync]="swaync --version"
+ [nwg-drawer]="nwg-drawer --version"
+ [wl-clipboard]="wl-copy --version"
+ [hyprshot]="hyprshot --version"
+ [wpaperd]="wpaperd --version"
)
# python-pip may expose `pip` instead of `pip3` on some setups; treat them