Compare commits

..
Author SHA1 Message Date
mathias2784 e499e63a49 screensaver text 2026-09-23 23:41:59 +02:00
mathias2784 df5abce062 merge main incl conflict resolution 2026-09-23 23:36:48 +02:00
mathias2784 aed6d46846 tte screensaver 2026-09-23 23:31:12 +02:00
mathias2784 30619b00ce hyprsaver 2026-09-23 23:05:54 +02:00
mathias2784 545485f3c5 Merge branch 'main' into hypr-caelestia 2026-09-23 21:52:27 +02:00
mathias2784 a8947283a5 .gitignore 2026-09-23 21:51:50 +02:00
mathias2784 496920cbdd refactor 2026-09-23 21:49:06 +02:00
mathias2784 519432d630 hypr: caelestia 2026-09-23 21:21:20 +02:00
mathias2784 15d77eeaca hypr: enrich noctalia config 2026-09-23 19:51:24 +02:00
mathias2784 23d0d1ecd3 hypr: shell commands in dedicated model 2026-09-23 19:32:37 +02:00
mathias2784 1d7ed473f6 hypr: refactor config to a more modular design 2026-09-23 19:04:52 +02:00
mathias2784 c055c5d592 tmux: turn off auto-restore at start 2026-09-23 07:07:54 +02:00
mathias2784 b7e396a1f0 a little less info in fastfetch 2026-09-23 07:05:42 +02:00
mathias2784 4be3a67dfe hypr: some sliding animations 2026-09-22 23:26:35 +02:00
mathias2784 a5eab1dda0 hypr setup: hello hyprmod & noctalia; goodbye hyprltm 2026-09-22 23:24:08 +02:00
mathias2784 4d9b3f99ac silence linter warnings in lua files 2026-09-22 23:00:29 +02:00
mathias2784 143f1ad86a use Noctalia instead of various components 2026-09-22 22:56:33 +02:00
mathias2784 466c79f1df use $HOME instead of /home/mathias 2026-09-22 22:00:25 +02:00
mathias2784 0bf7af3b03 re-introduce fastfetch 2026-09-21 22:56:30 +02:00
mathias2784 90a9390f37 consistent styling 2026-09-21 22:39:09 +02:00
mathias2784 c54c7a2b9d fix some test failures 2026-09-21 22:12:57 +02:00
mathias2784 0ca73bf029 tmux: fix styling 2026-09-21 21:42:09 +02:00
mathias2784 edeee7debd Neovim keybind for closing current bufferline tab 2026-09-21 21:33:00 +02:00
mathias2784 8f89aefe86 waypaper improvement 2026-09-21 21:26:59 +02:00
mathias2784 4d197d304e waypaper: minor fixes 2026-09-21 09:25:52 +02:00
mathias2784 c5c4ec6527 waypaper 2026-09-20 22:27:12 +02:00
91 changed files with 2231 additions and 2188 deletions
+6 -1
View File
@@ -2,9 +2,14 @@ hypr/.config/hypr/env
hypr/.config/hypr/env.conf
hypr/.config/hypr/env.sh
hypr/.config/hypr/monitor_setup.lua
hypr/.config/wpaperd/wallpapers/linked
# Noctalia template output (shell-owned, regenerated on palette change)
hypr/.config/hypr/noctalia.lua
hypr/.config/kitty/themes/noctalia.conf
# Caelestia runtime output (shell-owned, regenerated on scheme change)
hypr/.config/hypr/scheme/
*~lock.*#
lazy-lock.json
fish_variables
term/.config/opencode/cli.json
term/.config/opencode/service.json
hypr/.config/hypr/scheme/current.lua
+2 -1
View File
@@ -1,5 +1,6 @@
{
"diagnostics.globals": [
"vim"
"vim",
"hl"
]
}
+2 -2
View File
@@ -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` <br>`bash _install_skripte/install_basic_pcks.sh` <br>`bash hypr/setup.sh` <br>`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 setup/term/setup.sh` <br>`bash setup/basic/setup.sh` <br>`bash setup/hypr/setup.sh` <br>`bash setup/kreation/setup.sh` | These scripts install Neovim, hyprland, VST runtime, and other utilities. Edit `setup/term/packages.txt` to add/remove terminal packages. |
| **Link configuration directories** | `ln -s ~/.dotfiles/hypr/.config/hypr ~/.config/hypr` <br>`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 `hypr/setup.sh` installs it from `hypr/packages.txt`. |
| **Wayland compositor** | Requires `hyprland` (and dependencies like `wlroots`). The script `setup/hypr/setup.sh` installs it from `setup/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. |
+8 -7
View File
@@ -6,26 +6,27 @@
# Zweige abhaengen. Die uebrigen Ziele haengen nur von basic ab und sind
# untereinander unabhaengig.
basic:
bash basic/setup.sh
bash setup/basic/setup.sh
stow basic
term: basic
bash term/scripts/setup.sh
bash setup/term/setup.sh
stow term
utils: basic
bash utils/setup.sh
bash _install_skripte/nextcloud.sh
bash setup/utils/setup.sh
bash setup/nextcloud.sh
hypr: basic
bash hypr/scripts/setup.sh
bash setup/hypr/setup.sh
stow hypr
kreation: basic
bash _install_skripte/install_kreation_pcks.sh
bash setup/kreation/setup.sh
stow kreation
buntes-monster: hypr kreation
_install_skripte/buntes-monster-links.sh
bash setup/buntes-monster-links.sh
# ---------------------------------------------------------------------------
# Testing (see README.md "Testing" and test/ for details)
+10 -9
View File
@@ -6,11 +6,12 @@ Personal configuration files for an Arch Linux workstation (Hyprland + Neovim +
| Directory | Contents |
|-----------|----------|
| `basic/` | Base system packages + the **central theme** (`basic/.config/themes` → `~/.config/themes`: Catppuccin Mocha palette, `current` symlink, `switch-theme.sh`/`sync-theme.sh`). All other packages reference it instead of copying colors. |
| `term/` | Fish + kitty + starship + nvim + tmux + yazi + fastfetch + opencode terminal environment |
| `hypr/` | Hyprland compositor config, kitty theme, wpaperd wallpapers |
| `hypr/` | Hyprland compositor config + Noctalia shell config (Catppuccin Mocha) |
| `kreation/`| VST plugin (`MT-PowerDrumKit.vst3`) |
| `local_ai/`| Local AI / MCP tooling config |
| `_install_skripte/` | Miscellaneous install helper scripts |
| `setup/` | Install/setup scripts + package lists (one subdir per target, shared helpers in `setup/lib/`; not stowed) |
| `test/` | Docker test harness (lint + smoke tests) |
Each top-level directory is a **stow package**. `stow` symlinks the files from the repository into your home directory (e.g. `term/.config/...` → `~/.config/...`).
@@ -42,8 +43,8 @@ Run `make <target>` from the repository root. Each target first runs the relevan
| Target | What it does |
|--------|--------------|
| `make term` | Runs `term/setup.sh` (installs terminal packages, sets fish as default shell, clones tmuxifier), then `stow term`. Pulls in `basic`. |
| `make basic` | Runs `basic/setup.sh`: enables multilib, updates the system, installs `yay` if missing, installs the `basic/packages.txt` packages, and sets up Docker (enables/starts the service, adds your user to the `docker` group, verifies the service) |
| `make term` | Runs `setup/term/setup.sh` (installs terminal packages, sets fish as default shell, clones tmuxifier), then `stow term`. Pulls in `basic`. |
| `make basic` | Runs `setup/basic/setup.sh`: enables multilib, updates the system, installs `yay` if missing, installs the `setup/basic/packages.txt` packages, and sets up Docker (enables/starts the service, adds your user to the `docker` group, verifies the service) |
| `make hypr` | `make basic`, installs Hyprland packages, stows `hypr`, runs the Hyprland setup scripts (`ensure-env.sh`, `portal-host-override.sh`, `fix_dolphin_file_associations.sh`) |
| `make kreation` | `make basic`, installs VST runtime, stows `kreation` |
| `make buntes-monster` | Everything (`basic` + `hypr` + `kreation`), then wires up symlinks |
@@ -53,7 +54,7 @@ Run `make <target>` from the repository root. Each target first runs the relevan
The terminal package list lives in a single editable file:
```
term/packages.txt
setup/term/packages.txt
```
Add/remove packages on separate lines. Lines starting with `#` are ignored, and you can switch between package sources with section markers:
@@ -64,12 +65,12 @@ Add/remove packages on separate lines. Lines starting with `#` are ignored, and
@npm # install via npm -g
```
The default section is `@pacman`. The AUR helper `yay` is bootstrapped automatically by `basic/setup.sh`.
The default section is `@pacman`. The AUR helper `yay` is bootstrapped automatically by `setup/basic/setup.sh`.
## What the install scripts do
- **`basic/setup.sh`** – enables multilib, updates the system (`pacman -Syu`), ensures `yay` is installed, reads `basic/packages.txt` and installs all packages with `--needed` (skips already-installed ones), and sets up Docker (`sudo systemctl enable --now docker`, adds the current user to the `docker` group, checks the service). Idempotent and safe to re-run.
- **`term/setup.sh`** – reads `term/packages.txt` and installs all packages (pacman/AUR via `yay --needed`, npm via `sudo npm install -g`), sets `fish` as the default shell (`chsh`), clones `tmuxifier`, adds the `git` yazi plugin (skips if already present), and runs `sudo updatedb`. Idempotent and safe to re-run.
- **`setup/basic/setup.sh`** – enables multilib, updates the system (`pacman -Syu`), ensures `yay` is installed, reads `setup/basic/packages.txt` and installs all packages with `--needed` (skips already-installed ones), and sets up Docker (`sudo systemctl enable --now docker`, adds the current user to the `docker` group, checks the service). Idempotent and safe to re-run.
- **`setup/term/setup.sh`** – reads `setup/term/packages.txt` and installs all packages (pacman/AUR via `yay --needed`, npm via `sudo npm install -g`), sets `fish` as the default shell (`chsh`), clones `tmuxifier`, adds the `git` yazi plugin (skips if already present), and runs `sudo updatedb`. Idempotent and safe to re-run.
## Stow: resolving conflicts with existing paths
@@ -137,7 +138,7 @@ There are **two tiers**:
| Target | What it does | Docker required? |
|--------|--------------|------------------|
| `make test-lint` | Fast, offline integrity checks: `bash -n` syntax pass over every script, `shellcheck` (if installed), `packages.txt` marker validation, and Makefile ↔ script/stow-package name consistency. Catches typos like `_install_skripte_install_basic_pcks.sh` (missing `/`). | No |
| `make test-lint` | Fast, offline integrity checks: `bash -n` syntax pass over every script, `shellcheck` (if installed), `packages.txt` marker validation, and Makefile ↔ script/stow-package name consistency. Catches typos like `setup/basic/setuo.sh` (missing `/`). | No |
| `make test-stow` | `stow --simulate` for every stow-able package; fails if a package the Makefile stows doesn't exist (e.g. `stow nvim` — nvim lives under `term/`). | No |
| `make test-shellcheck` | Runs shellcheck over all tracked scripts (shellcheck must be installed). | No |
| `make test-lint-docker` | Builds the `/dev` stage (`archlinux:latest` + shellcheck) and runs `test/lint.sh` inside it. | Yes |
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
sudo pacman -S --needed \
reaper \
guitarix \
kdenlive \
yabridge \
yabridgectl \
obs-studio \
surge-xt \
lsp-plugins \
calf \
dragonfly-reverb
yay -S --needed \
numaplayer
+1
View File
@@ -0,0 +1 @@
themes/catppuccin-mocha
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# Scaffold a new theme directory (basic/.config/themes/scripts/new-theme.sh).
#
# Usage: new-theme.sh <theme-id> e.g. new-theme.sh rose-pine-moon
#
# Copies themes/catppuccin-mocha as a template. Afterwards:
# 1. Replace every palette value in the new directory.
# 2. Add one row to themes/registry.conf.
# 3. Run scripts/switch-theme.sh <theme-id> to try it.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
THEMES_DIR="$REPO_ROOT/basic/.config/themes/themes"
[[ $# -eq 1 ]] || { echo "usage: $(basename "$0") <theme-id>" >&2; exit 1; }
theme_id="$1"
if [[ ! "$theme_id" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
echo "error: invalid theme-id '$theme_id'" >&2
exit 1
fi
[[ -e "$THEMES_DIR/$theme_id" ]] && { echo "error: $theme_id already exists" >&2; exit 1; }
cp -r "$THEMES_DIR/catppuccin-mocha" "$THEMES_DIR/$theme_id"
echo "scaffolded $THEMES_DIR/$theme_id"
echo "next: replace the palette values, add a registry.conf row, run switch-theme.sh $theme_id"
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
# Central theme switcher (basic/.config/themes/scripts/switch-theme.sh).
#
# Usage: switch-theme.sh <theme-id> e.g. switch-theme.sh catppuccin-mocha
#
# Retargets the tracked `current` symlink to themes/<theme-id> and reloads
# every consumer that can be reloaded. Because `current` lives in the repo,
# the switch is a reviewable git change; re-stowing is not required since
# all consumers resolve through ~/.config/themes/current at runtime.
#
# A future non-Catppuccin theme only needs its own themes/<theme-id>/
# directory plus a row in themes/registry.conf — this script stays untouched.
set -euo pipefail
usage() {
echo "usage: $(basename "$0") <theme-id>" >&2
echo "available:" >&2
ls -1 "$(repo_root)/basic/.config/themes/themes" 2>/dev/null | grep -v '^registry.conf$' | sed 's/^/ /' >&2 || true
}
repo_root() {
local src="$0"
if command -v readlink >/dev/null 2>&1; then
src="$(readlink -f "$0")"
fi
cd "$(dirname "$src")/../../../.." && pwd
}
main() {
[[ $# -eq 1 ]] || { usage; exit 1; }
local theme_id="$1"
if [[ ! "$theme_id" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
echo "error: invalid theme-id '$theme_id'" >&2
exit 1
fi
local root
root="$(repo_root)"
local dest="$root/basic/.config/themes/themes/$theme_id"
local link="$root/basic/.config/themes/current"
[[ -d "$dest" ]] || { echo "error: unknown theme '$theme_id' (no $dest)" >&2; usage; exit 1; }
ln -sfn "themes/$theme_id" "$link"
echo "theme switched: current -> themes/$theme_id"
# Best-effort live reloads; every step is guarded so the switch
# succeeds even on machines without a running compositor.
if command -v hyprctl >/dev/null 2>&1; then
hyprctl reload >/dev/null 2>&1 || true
fi
if command -v tmux >/dev/null 2>&1 && [[ -n "${TMUX:-}" ]]; then
tmux source-file "$HOME/.config/tmux/tmux.conf" >/dev/null 2>&1 || true
fi
echo "note: restart Neovim (or :colorscheme \$THEME_NVIM_COLORSCHEME) and open a new shell to pick up theme.env.sh."
}
main "$@"
+83
View File
@@ -0,0 +1,83 @@
#!/bin/bash
# Central theme drift guard (basic/.config/themes/scripts/sync-theme.sh).
#
# Fails if hardcoded theme hex values appear anywhere in the repo outside:
# - basic/.config/themes (the single source of truth)
# - term/.config/tmux/plugins/ (vendored upstream, stow-ignored)
# - term/.config/yazi/theme.toml (declared mirror: yazi has no include)
# - term/.config/starship.toml (declared mirror: starship has no include)
# - hypr/.config/hypr/noctalia.lua + hypr/.config/kitty/themes/noctalia.conf
# (Noctalia template output: shell-owned, gitignored, regenerated from
# the active palette on every theme change)
# - test/ + docs (may quote values in prose)
#
# Run with: bash basic/.config/themes/scripts/sync-theme.sh
# test/lint.sh invokes it as part of `make test-lint`.
set -uo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
cd "$REPO_ROOT" || exit 1
# Sentinel hex values of the active palette (case-insensitive).
SENTINELS='74c7ec|1e1e2e|cdd6f4|45475a|b4befe|f38ba8|a6e3a1|f9e2af|181825|11111b|89b4fa|f5e0dc'
matches="$(grep -rniE --include='*.conf' --include='*.css' --include='*.rasi' \
--include='*.lua' --include='*.toml' --include='*.fish' --include='*.sh' \
--exclude-dir='.git' --exclude-dir='plugins' --exclude-dir='test' \
-E "$SENTINELS" . 2>/dev/null | grep -vE '^./basic/.config/themes' \
| grep -vE 'term/.config/(yazi/theme.toml|starship.toml)' \
| grep -vE 'hypr/.config/(hypr/noctalia.lua|kitty/themes/noctalia.conf)' || true)"
if [[ -n "$matches" ]]; then
echo "FAIL: hardcoded theme colors outside basic/.config/themes (and declared mirrors):"
printf '%s\n' "$matches" | sed 's/^/ /'
echo "Move the values into basic/.config/themes and reference them instead."
exit 1
fi
echo "ok: no hardcoded theme colors outside the central theme"
# ---------------------------------------------------------------------------
# Role/palette consistency: every role in theme.css must equal its palette
# twin (roles are literal hex because some parsers drop @-references).
# ---------------------------------------------------------------------------
python3 - <<'EOF'
import re, sys
css_path = "basic/.config/themes/themes/catppuccin-mocha/theme.css"
defines = dict(re.findall(r"@define-color\s+([a-z0-9_]+)\s+(#[0-9a-fA-F]+)", open(css_path).read()))
# role -> palette twin (bg_translucent intentionally excluded: crust + alpha).
pairs = {
"bg": "base", "bg_dim": "mantle", "bg_deep": "crust",
"fg": "text", "fg_dim": "subtext0", "fg_muted": "overlay1",
"surface": "surface0", "border": "surface1",
"accent": "sapphire", "accent2": "lavender",
"ok": "green", "warn": "yellow", "urgent": "red",
}
missing = [k for k in list(pairs) + list(pairs.values()) if k not in defines]
if missing:
print(f"FAIL: theme.css missing defines: {sorted(missing)}")
sys.exit(1)
bad = [r for r, p in pairs.items() if defines[r].lower() != defines[p].lower()]
if bad:
print(f"FAIL: roles out of sync with palette in {css_path}: {bad}")
sys.exit(1)
trans = defines.get("bg_translucent_raw", "")
m = re.fullmatch(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9.]+)\s*\)", trans)
if not m:
# defines[] regex only captures #hex; re-read raw value (may be rgba()).
raw = re.search(r"@define-color\s+bg_translucent\s+([^;]+);", open(css_path).read())
trans = raw.group(1).strip() if raw else ""
m = re.fullmatch(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9.]+)\s*\)", trans)
crust_rgb = tuple(int(defines["crust"][i:i+2], 16) for i in (1, 3, 5))
if not m or tuple(map(int, m.groups()[:3])) != crust_rgb or not (0 < float(m.group(4)) < 1):
print(f"FAIL: bg_translucent must be rgba(crust, alpha<1) in {css_path}")
sys.exit(1)
print("ok: theme.css roles match palette")
EOF
@@ -1,3 +1,8 @@
# Central theme: catppuccin-mocha (Catppuccin Mocha), hyprland $vars.
# Part of basic/.config/themes. Managed file: refresh via
# setup/fetch-ports.sh
# (upstream: catppuccin/hyprland generated mocha.conf).
# Hyprland consumers load it via: source = ~/.config/themes/current/hypr.conf
$rosewater = rgb(f5e0dc)
$rosewaterAlpha = f5e0dc
@@ -0,0 +1,88 @@
# Central theme: catppuccin-mocha (Catppuccin Mocha), kitty colors.
# Part of basic/.config/themes. Managed file: refresh via
# setup/fetch-ports.sh
# (upstream: catppuccin/kitty themes/mocha.conf).
# vim:ft=kitty
## name: Catppuccin Kitty Mocha
## author: Catppuccin Org
## license: MIT
## upstream: https://github.com/catppuccin/kitty/blob/main/themes/mocha.conf
## blurb: Soothing pastel theme for the high-spirited!
# The basic colors
foreground #cdd6f4
background #1e1e2e
selection_foreground #1e1e2e
selection_background #f5e0dc
# Cursor colors
cursor #f5e0dc
cursor_text_color #1e1e2e
# Scrollbar colors
scrollbar_handle_color #9399b2
scrollbar_track_color #45475a
# URL color when hovering with mouse
url_color #f5e0dc
# Kitty window border colors
active_border_color #b4befe
inactive_border_color #6c7086
bell_border_color #f9e2af
# OS Window titlebar colors
wayland_titlebar_color system
macos_titlebar_color system
# Tab bar colors
active_tab_foreground #11111b
active_tab_background #cba6f7
inactive_tab_foreground #cdd6f4
inactive_tab_background #181825
tab_bar_background #11111b
# Colors for marks (marked text in the terminal)
mark1_foreground #1e1e2e
mark1_background #b4befe
mark2_foreground #1e1e2e
mark2_background #cba6f7
mark3_foreground #1e1e2e
mark3_background #74c7ec
# The 16 terminal colors
# black
color0 #45475a
color8 #585b70
# red
color1 #f38ba8
color9 #f38ba8
# green
color2 #a6e3a1
color10 #a6e3a1
# yellow
color3 #f9e2af
color11 #f9e2af
# blue
color4 #89b4fa
color12 #89b4fa
# magenta
color5 #f5c2e7
color13 #f5c2e7
# cyan
color6 #94e2d5
color14 #94e2d5
# white
color7 #bac2de
color15 #a6adc8
@@ -0,0 +1,54 @@
/* Central theme: catppuccin-mocha (Catppuccin Mocha).
* Part of basic/.config/themes. Managed file: edit the palette here.
* (theme.css was originally ported from catppuccin/waybar themes/mocha.css;
* the waybar port is gone, so this file is hand-maintained now.)
* Consumers must use this file via
* ~/.config/themes/current/theme.css, never a private copy.
* Role aliases (stable interface, theme-agnostic) follow the palette. */
@define-color rosewater #f5e0dc;
@define-color flamingo #f2cdcd;
@define-color pink #f5c2e7;
@define-color mauve #cba6f7;
@define-color red #f38ba8;
@define-color maroon #eba0ac;
@define-color peach #fab387;
@define-color yellow #f9e2af;
@define-color green #a6e3a1;
@define-color teal #94e2d5;
@define-color sky #89dceb;
@define-color sapphire #74c7ec;
@define-color blue #89b4fa;
@define-color lavender #b4befe;
@define-color text #cdd6f4;
@define-color subtext1 #bac2de;
@define-color subtext0 #a6adc8;
@define-color overlay2 #9399b2;
@define-color overlay1 #7f849c;
@define-color overlay0 #6c7086;
@define-color surface2 #585b70;
@define-color surface1 #45475a;
@define-color surface0 #313244;
@define-color base #1e1e2e;
@define-color mantle #181825;
@define-color crust #11111b;
/* ---- Stable role interface (theme-agnostic; consumers use THESE) ----
* NOTE: values are literal hex, NOT @references to the palette above.
* Some Gtk.CssProvider-based parsers silently drop
* @define-color lines that reference another @color, which made every
* background transparent. Keep each role in sync with its palette twin
* (mapping below); scripts/sync-theme.sh verifies this mechanically. */
@define-color bg #1e1e2e; /* = @base */
@define-color bg_dim #181825; /* = @mantle */
@define-color bg_deep #11111b; /* = @crust */
@define-color bg_translucent rgba(17, 17, 27, 0.85); /* crust at 85% (translucent window bg) */
@define-color fg #cdd6f4; /* = @text */
@define-color fg_dim #a6adc8; /* = @subtext0 */
@define-color fg_muted #7f849c; /* = @overlay1 */
@define-color surface #313244; /* = @surface0 */
@define-color border #45475a; /* = @surface1 */
@define-color accent #74c7ec; /* = @sapphire */
@define-color accent2 #b4befe; /* = @lavender */
@define-color ok #a6e3a1; /* = @green */
@define-color warn #f9e2af; /* = @yellow */
@define-color urgent #f38ba8; /* = @red */
@@ -0,0 +1,42 @@
# Central theme interface: catppuccin-mocha (Catppuccin Mocha).
# Part of basic/.config/themes. Managed file: edit the palette here.
# Sourced by POSIX shells (~/.bashrc) and by Hyprland-launched apps.
# Generic THEME_* vars are the stable, theme-agnostic interface; the
# CATPPUCCIN_* / palette vars below exist because lazy.nvim, TPM and
# starship need the literal upstream names. A future non-Catppuccin theme
# only adds a new directory exporting the same THEME_* names.
export THEME_NAME="catppuccin"
export THEME_FLAVOR="mocha"
export THEME_ID="catppuccin-mocha"
# Generic roles (stable interface).
export THEME_BG="#1e1e2e"
export THEME_BG_DIM="#181825"
export THEME_FG="#cdd6f4"
export THEME_FG_DIM="#a6adc8"
export THEME_SURFACE="#313244"
export THEME_BORDER="#45475a"
export THEME_ACCENT="#74c7ec"
export THEME_ACCENT2="#b4befe"
export THEME_OK="#a6e3a1"
export THEME_WARN="#f9e2af"
export THEME_URGENT="#f38ba8"
# Plugin / colorscheme mapping (see ../registry.conf).
export THEME_NVIM_COLORSCHEME="catppuccin"
export THEME_TMUX_PLUGIN="catppuccin/tmux"
export THEME_GTK="Adwaita:dark"
# Upstream literal names (compat for lazy.nvim / TPM / starship).
export CATPPUCCIN_FLAVOR="mocha"
export CATPPUCCIN_BASE="#1e1e2e"
export CATPPUCCIN_MANTLE="#181825"
export CATPPUCCIN_CRUST="#11111b"
export CATPPUCCIN_TEXT="#cdd6f4"
export CATPPUCCIN_SAPPHIRE="#74c7ec"
export CATPPUCCIN_LAVENDER="#b4befe"
export CATPPUCCIN_SURFACE1="#45475a"
export CATPPUCCIN_RED="#f38ba8"
export CATPPUCCIN_GREEN="#a6e3a1"
export CATPPUCCIN_YELLOW="#f9e2af"
@@ -0,0 +1,25 @@
# Central theme interface: catppuccin-mocha (Catppuccin Mocha).
# Fish companion of theme.env.sh. Sourced from fish/config.fish.
# Managed file: edit the palette here, not in consumers.
set -gx THEME_NAME "catppuccin"
set -gx THEME_FLAVOR "mocha"
set -gx THEME_ID "catppuccin-mocha"
set -gx THEME_BG "#1e1e2e"
set -gx THEME_BG_DIM "#181825"
set -gx THEME_FG "#cdd6f4"
set -gx THEME_FG_DIM "#a6adc8"
set -gx THEME_SURFACE "#313244"
set -gx THEME_BORDER "#45475a"
set -gx THEME_ACCENT "#74c7ec"
set -gx THEME_ACCENT2 "#b4befe"
set -gx THEME_OK "#a6e3a1"
set -gx THEME_WARN "#f9e2af"
set -gx THEME_URGENT "#f38ba8"
set -gx THEME_NVIM_COLORSCHEME "catppuccin"
set -gx THEME_TMUX_PLUGIN "catppuccin/tmux"
set -gx THEME_GTK "Adwaita:dark"
set -gx CATPPUCCIN_FLAVOR "mocha"
@@ -0,0 +1,87 @@
-- Central theme interface: catppuccin-mocha (Catppuccin Mocha).
-- Part of basic/.config/themes. Managed file: edit the palette here.
-- Consumers (hyprland.lua) load this via
-- dofile(os.getenv("HOME") .. "/.config/themes/current/theme.lua")
-- and must use the generic roles (bg/fg/accent/...) so a future
-- non-Catppuccin theme only adds a new directory. Full palette is
-- passed through for components that need specific colors.
-- Hyprland color syntax: "rgb(hex)" / "rgba(hexaa)".
local T = {
name = "catppuccin",
flavor = "mocha",
hex = {
rosewater = "f5e0dc",
flamingo = "f2cdcd",
pink = "f5c2e7",
mauve = "cba6f7",
red = "f38ba8",
maroon = "eba0ac",
peach = "fab387",
yellow = "f9e2af",
green = "a6e3a1",
teal = "94e2d5",
sky = "89dceb",
sapphire = "74c7ec",
blue = "89b4fa",
lavender = "b4befe",
text = "cdd6f4",
subtext1 = "bac2de",
subtext0 = "a6adc8",
overlay2 = "9399b2",
overlay1 = "7f849c",
overlay0 = "6c7086",
surface2 = "585b70",
surface1 = "45475a",
surface0 = "313244",
base = "1e1e2e",
mantle = "181825",
crust = "11111b",
},
-- Generic roles (stable interface, theme-agnostic).
bg = "rgba(1e1e2eee)",
bg_dim = "rgb(181825)",
fg = "rgb(cdd6f4)",
fg_dim = "rgb(a6adc8)",
surface = "rgb(313244)",
border_active = "rgba(74c7ecee)",
border_inactive = "rgba(45475aee)",
shadow = "rgba(74c7ecee)",
accent = "rgb(74c7ec)",
accent2 = "rgb(b4befe)",
ok = "rgb(a6e3a1)",
warn = "rgb(f9e2af)",
urgent = "rgb(f38ba8)",
-- Full palette passthrough (hyprland syntax).
rosewater = "rgb(f5e0dc)",
flamingo = "rgb(f2cdcd)",
pink = "rgb(f5c2e7)",
mauve = "rgb(cba6f7)",
red = "rgb(f38ba8)",
maroon = "rgb(eba0ac)",
peach = "rgb(fab387)",
yellow = "rgb(f9e2af)",
green = "rgb(a6e3a1)",
teal = "rgb(94e2d5)",
sky = "rgb(89dceb)",
sapphire = "rgb(74c7ec)",
blue = "rgb(89b4fa)",
lavender = "rgb(b4befe)",
text = "rgb(cdd6f4)",
subtext1 = "rgb(bac2de)",
subtext0 = "rgb(a6adc8)",
overlay2 = "rgb(9399b2)",
overlay1 = "rgb(7f849c)",
overlay0 = "rgb(6c7086)",
surface2 = "rgb(585b70)",
surface1 = "rgb(45475a)",
surface0 = "rgb(313244)",
base = "rgb(1e1e2e)",
mantle = "rgb(181825)",
crust = "rgb(11111b)",
}
return T
+10
View File
@@ -0,0 +1,10 @@
# Central theme registry (basic/.config/themes/themes/registry.conf).
#
# One row per installed theme. Columns (pipe-separated):
# theme-id | nvim colorscheme | tmux plugin | gtk theme | notes
#
# Consumers must branch on THEME_ID / THEME_NVIM_COLORSCHEME /
# THEME_TMUX_PLUGIN only — never on hardcoded theme names elsewhere.
# Adding a future non-Catppuccin theme means: scaffold the directory with
# scripts/new-theme.sh, fill in its palette, add one row here.
catppuccin-mocha|catppuccin|catppuccin/tmux|Adwaita:dark|default; Catppuccin Mocha everywhere
-150
View File
@@ -1,150 +0,0 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SCRIPT_DIR/packages.txt"
# ---------------------------------------------------------------------------
# Enable multilib in /etc/pacman.conf (with a safety backup)
# ---------------------------------------------------------------------------
enable_multilib() {
sudo sed -i.bak '/^#\[multilib\]/,+1 s/^#//' /etc/pacman.conf
}
# ---------------------------------------------------------------------------
# Ensure yay (AUR helper) is installed.
# ---------------------------------------------------------------------------
install_yay() {
if pacman -Q yay &>/dev/null; then
echo "yay bereits installiert; fahre fort."
return
fi
if pacman -Si yay &>/dev/null; then
echo "Installiere yay mit pacman ..."
sudo pacman -S --needed yay
return
fi
echo "installiere yay via git ..."
sudo pacman -S --needed base-devel git
local tmp
tmp="$(mktemp -d)"
git clone https://aur.archlinux.org/yay.git "$tmp/yay"
(
cd "$tmp/yay"
makepkg -si
)
rm -rf "$tmp"
}
# ---------------------------------------------------------------------------
# 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
}
# ---------------------------------------------------------------------------
# Docker: Dienst aktivieren/starten, Benutzer in die docker-Gruppe aufnehmen
# und den Dienst verifizieren. (docker selbst wird ueber basic/packages.txt
# als Pacman-Paket installiert.)
# ---------------------------------------------------------------------------
setup_docker() {
if ! command -v docker >/dev/null 2>&1; then
echo "Warnung: docker nicht installiert; ueberspringe Docker-Setup."
return
fi
echo "==> Aktiviere und starte Docker-Dienst ..."
sudo systemctl enable --now docker
# Bei Aufruf via `sudo <script>` ist SUDO_USER der eigentliche Benutzer.
local target_user="${SUDO_USER:-$USER}"
echo "==> Stelle sicher, dass $target_user in der docker-Gruppe ist ..."
if [[ "$target_user" == "root" ]] || id -nG "$target_user" 2>/dev/null | grep -qw docker; then
echo "Benutzer $target_user ist bereits in der docker-Gruppe."
else
sudo usermod -aG docker "$target_user"
echo "Benutzer $target_user zur docker-Gruppe hinzugefuegt; wirksam nach dem naechsten Login."
fi
echo "==> Pruefe Docker-Dienst ..."
if systemctl is-active --quiet docker; then
echo "Docker-Dienst laeuft (Socket: /var/run/docker.sock)."
else
echo "Warnung: Docker-Dienst laeuft nicht; pruefe mit: systemctl status docker"
fi
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
echo "==> Aktiviere multilib ..."
enable_multilib
echo "==> System aktualisieren ..."
sudo pacman -Syu
echo "==> Sicherstelle yay ..."
install_yay
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages
install_pacman
install_aur
install_npm
echo "==> Richte Docker ein ..."
setup_docker
echo "Fertig. Die Basis-Systemumgebung ist eingerichtet."
}
main
@@ -0,0 +1,2 @@
{
}
+23
View File
@@ -0,0 +1,23 @@
{
"appearance": {
"transparency": {
"enabled": true
}
},
"general": {
"apps": {
"explorer": ["dolphin"],
"terminal": ["kitty"]
}
},
"launcher": {
"showOnHover": true,
"useFuzzy": {
"apps": true
},
"vimKeybinds": true
},
"paths": {
"wallpaperDir": "~/nextcloud/Photos/Wallpapers"
}
}
Executable → Regular
+21 -23
View File
@@ -1,34 +1,32 @@
# hypridle.conf — idle stages: screensaver (300s, backend in modules/screensaver.lua) -> Noctalia lock (10min) -> DPMS off.
# Managed by dotfiles (stow hypr).
#
# NOTE: this Hyprland (hyprmod Lua runtime, 0.56.x) evaluates `hyprctl dispatch`
# args as Lua — classic `dispatch dpms off` syntax fails. Dispatchers must be
# hl.dsp.* expressions (e.g. hl.dsp.dpms(false)).
general {
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances.
before_sleep_cmd = loginctl lock-session # lock before suspend.
after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display.
lock_cmd = pidof -q noctalia || noctalia msg session lock
before_sleep_cmd = loginctl lock-session
after_sleep_cmd = hyprctl dispatch 'hl.dsp.dpms(true)'
}
# Screensaver via backend wrappers (switch backend in modules/screensaver.lua).
listener {
timeout = 300 # 5.0min.
on-timeout = brightnessctl -s set 10 # set monitor backlight to minimum, avoid 0 on OLED monitor.
on-resume = brightnessctl -r # monitor backlight restore.
timeout = 300
on-timeout = ~/.config/hypr/scripts/screensaver-start.sh
on-resume = ~/.config/hypr/scripts/screensaver-stop.sh
}
# turn off keyboard backlight, comment out this section if you dont have a keyboard backlight.
# 10min: lock via Noctalia (SUPER+L runs the same command).
listener {
timeout = 300 # 5.0min.
on-timeout = brightnessctl -sd rgb:kbd_backlight set 0 # turn off keyboard backlight.
on-resume = brightnessctl -rd rgb:kbd_backlight # turn on keyboard backlight.
timeout = 600
on-timeout = loginctl lock-session
}
# 10m30s: power off displays.
listener {
timeout = 900 # 15min
on-timeout = loginctl lock-session # lock screen when timeout has passed
}
listener {
timeout = 1800 # 30min
on-timeout = hyprctl dispatch dpms off # screen off when timeout has passed
on-resume = hyprctl dispatch dpms on && brightnessctl -r # screen on when activity is detected after timeout has fired.
}
listener {
timeout = 2700 # 45min
on-timeout = systemctl suspend # suspend pc
timeout = 630
on-timeout = hyprctl dispatch 'hl.dsp.dpms(false)'
on-resume = hyprctl dispatch 'hl.dsp.dpms(true)'
}
-12
View File
@@ -1,12 +0,0 @@
-- Generated by HyprMod
-- Settings
hl.config({
general = {
border_size = 5,
col = {
active_border = "0xcbe0e89b",
inactive_border = "0xff0e0543",
},
},
})
+25 -607
View File
@@ -1,11 +1,3 @@
local var_color_active_border = "rgba(74c7ecee)"
local var_color_inactive_border = "rgba(45475aee)"
local var_color_decoration_shadow = "rgba(74c7ecee)"
local var_mainMod = "SUPER"
local var_terminal = "kitty"
local var_fileManager = "dolphin"
local var_menu = "wofi --show drun"
local var_screenshot_folder = "~/Bilder/Screenshots/"
require("env")
hl.exec_cmd("bash ~/.config/hypr/env.sh")
@@ -14,13 +6,22 @@ hl.exec_cmd("bash ~/.config/hypr/env.sh")
-- ## MONITORS ###
-- ###############
require("monitor_setup")
-- load default monitor config
require("modules.monitor_setup_default")
-- Only use monitor_setup if the file exists
local config_home = os.getenv("XDG_CONFIG_HOME") or os.getenv("HOME") .. "/.config"
local f = io.open(config_home .. "/hypr/monitor_setup.lua", "r")
if f then
f:close()
require("monitor_setup")
end
-- unscale XWayland
hl.config({
xwayland = {
force_zero_scaling = true,
},
xwayland = {
force_zero_scaling = true,
},
})
-- ##################
@@ -28,606 +29,23 @@ hl.config({
-- ##################
hl.on("hyprland.start", function()
hl.exec_cmd("waybar &")
hl.exec_cmd("caelestia shell -d")
end)
hl.on("hyprland.start", function()
hl.exec_cmd("wpaperd &")
hl.exec_cmd("swaync &")
hl.exec_cmd("hypridle &")
hl.exec_cmd("nextcloud &")
hl.exec_cmd("sh ~/.config/hypr/scripts/portal-host-override.sh")
hl.exec_cmd("sh ~/.config/hypr/scripts/ensure-mime-defaults.sh")
hl.exec_cmd("hypridle &")
end)
-- ############################
-- ## ENVIRONMENT VARIABLES ###
-- ############################
-- See https://wiki.hypr.land/Configuring/Environment-variables/
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_TYPE", "wayland")
hl.env("XDG_MENU_PREFIX", "plasma-")
hl.env("GTK_USE_PORTAL", "1")
hl.env("GTK_THEME", "Adwaita:dark")
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
hl.env("QT_QPA_PLATFORMTHEME", "kde")
-- ##################
-- ## PERMISSIONS ###
-- ##################
-- ####################
-- ## COLOR SCHEMES ###
-- ####################
require("themes.mocha")
-- ####################
-- ## LOOK AND FEEL ###
-- ####################
-- Refer to https://wiki.hypr.land/Configuring/Variables/
-- https://wiki.hypr.land/Configuring/Variables/#general
hl.config({
general = {
gaps_in = 3,
gaps_out = 4,
border_size = 3,
},
})
-- https://wiki.hypr.land/Configuring/Variables/#variable-types for info about colors
hl.config({
general = {
col = {
active_border = var_color_active_border,
inactive_border = var_color_inactive_border,
},
},
})
-- Set to true enable resizing windows by clicking and dragging on borders and gaps
hl.config({
general = {
resize_on_border = true,
},
})
-- Please see https://wiki.hypr.land/Configuring/Tearing/ before you turn this on
hl.config({
general = {
allow_tearing = false,
layout = "dwindle",
},
})
-- https://wiki.hypr.land/Configuring/Variables/#decoration
hl.config({
decoration = {
rounding = 5,
rounding_power = 2,
},
})
-- Change transparency of focused and unfocused windows
hl.config({
decoration = {
active_opacity = 1.0,
inactive_opacity = 1.0,
shadow = {
enabled = true,
range = 10,
render_power = 3,
color = var_color_decoration_shadow,
},
},
})
-- https://wiki.hypr.land/Configuring/Variables/#blur
hl.config({
decoration = {
blur = {
enabled = true,
size = 10,
passes = 2,
vibrancy = 0.1696,
},
},
})
-- https://wiki.hypr.land/Configuring/Variables/#animations
hl.config({
animations = {
enabled = true,
},
})
-- Default curves, see https://wiki.hypr.land/Configuring/Animations/#curves
-- NAME, X0, Y0, X1, Y1
hl.curve("easeOutQuint", { type = "bezier", points = { {0.23, 1}, {0.32, 1} } })
hl.curve("easeInOutCubic", { type = "bezier", points = { {0.65, 0.05}, {0.36, 1} } })
hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } })
hl.curve("almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1} } })
hl.curve("quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1} } })
-- Default animations, see https://wiki.hypr.land/Configuring/Animations/
-- NAME, ONOFF, SPEED, CURVE, [STYLE]
hl.animation({
leaf = "global",
enabled = true,
speed = 10,
bezier = "default",
})
hl.animation({
leaf = "border",
enabled = true,
speed = 5.39,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "windows",
enabled = true,
speed = 4.79,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "windowsIn",
enabled = true,
speed = 4.1,
bezier = "easeOutQuint",
style = "popin 87%",
})
hl.animation({
leaf = "windowsOut",
enabled = true,
speed = 1.49,
bezier = "linear",
style = "popin 87%",
})
hl.animation({
leaf = "fadeIn",
enabled = true,
speed = 1.73,
bezier = "almostLinear",
})
hl.animation({
leaf = "fadeOut",
enabled = true,
speed = 1.46,
bezier = "almostLinear",
})
hl.animation({
leaf = "fade",
enabled = true,
speed = 3.03,
bezier = "quick",
})
hl.animation({
leaf = "layers",
enabled = true,
speed = 3.81,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "layersIn",
enabled = true,
speed = 4,
bezier = "easeOutQuint",
style = "fade",
})
hl.animation({
leaf = "layersOut",
enabled = true,
speed = 1.5,
bezier = "linear",
style = "fade",
})
hl.animation({
leaf = "fadeLayersIn",
enabled = true,
speed = 1.79,
bezier = "almostLinear",
})
hl.animation({
leaf = "fadeLayersOut",
enabled = true,
speed = 1.39,
bezier = "almostLinear",
})
hl.animation({
leaf = "workspaces",
enabled = true,
speed = 1.94,
bezier = "almostLinear",
style = "fade",
})
hl.animation({
leaf = "workspacesIn",
enabled = true,
speed = 1.21,
bezier = "almostLinear",
style = "fade",
})
hl.animation({
leaf = "workspacesOut",
enabled = true,
speed = 1.94,
bezier = "almostLinear",
style = "fade",
})
hl.animation({
leaf = "zoomFactor",
enabled = true,
speed = 7,
bezier = "quick",
})
-- Ref https://wiki.hypr.land/Configuring/Workspace-Rules/
-- "Smart gaps" / "No gaps when only"
-- uncomment all if you wish to use that.
hl.workspace_rule({
workspace = "w[tv1]",
gaps_out = 0,
gaps_in = 0,
})
hl.workspace_rule({
workspace = "f[1]",
gaps_out = 0,
gaps_in = 0,
})
hl.window_rule({
name = "no-gaps-wtv1",
match = {
float = false,
workspace = "w[tv1]",
},
border_size = 0,
rounding = 0,
})
hl.window_rule({
name = "no-gaps-f1",
match = {
float = false,
workspace = "f[1]",
},
border_size = 0,
rounding = 0,
})
-- See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more
hl.config({
dwindle = {
preserve_split = true,
},
})
-- See https://wiki.hypr.land/Configuring/Master-Layout/ for more
hl.config({
master = {
new_status = "master",
},
})
-- https://wiki.hypr.land/Configuring/Variables/#misc
hl.config({
misc = {
force_default_wallpaper = -1,
disable_hyprland_logo = false,
},
})
-- ############
-- ## INPUT ###
-- ############
-- https://wiki.hypr.land/Configuring/Variables/#input
hl.config({
input = {
kb_layout = "de",
kb_variant = "",
kb_model = "",
kb_options = "grp:alt_shift_toggle",
kb_rules = "",
follow_mouse = 1,
numlock_by_default = true,
sensitivity = 0,
touchpad = {
natural_scroll = true,
},
},
})
-- See https://wiki.hypr.land/Configuring/Gestures
hl.gesture({
fingers = 3,
direction = "horizontal",
action = "workspace",
})
-- Example per-device config
-- See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more
hl.device({
name = "epic-mouse-v1",
sensitivity = -0.5,
})
-- ##################
-- ## KEYBINDINGS ###
-- ##################
-- See https://wiki.hypr.land/Configuring/Keywords/
-- Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more
hl.bind(var_mainMod .. " + RETURN", hl.dsp.exec_cmd(var_terminal), { description = "Open terminal (kitty)" })
hl.bind(var_mainMod .. " + Q", hl.dsp.window.close(), { description = "Close focused window" })
hl.bind(var_mainMod .. " + ESCAPE", hl.dsp.exec_cmd("hyprshutdown"), { description = "Shutdown Hyprland" })
hl.bind(var_mainMod .. " + SHIFT + ESCAPE", hl.dsp.exec_cmd("command -v hyprshutdown >/dev/null 2>&1 && hyprshutdown || hyprctl dispatch exit"), { description = "Exit Hyprland" })
hl.bind(var_mainMod .. " + CTRL + ESCAPE", hl.dsp.exec_cmd("hyprshutdown -t 'Shutting down...' --post-cmd 'shutdown -P 0'"), { description = "Power off the system" })
hl.bind(var_mainMod .. " + ALT + ESCAPE", hl.dsp.exec_cmd("hyprshutdown -t 'Restarting...' --post-cmd 'reboot'"), { description = "Reboot the system" })
hl.bind(var_mainMod .. " + E", hl.dsp.exec_cmd(var_fileManager), { description = "Open file manager (dolphin)" })
hl.bind(var_mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }), { description = "Toggle floating window" })
hl.bind(var_mainMod .. " + SPACE", hl.dsp.exec_cmd(var_menu), { description = "Open app launcher (wofi)" })
hl.bind(var_mainMod .. " + SHIFT + SPACE", hl.dsp.exec_cmd("nwg-drawer"), { description = "Open app drawer (nwg-drawer)" })
hl.bind(var_mainMod .. " + P", hl.dsp.window.pseudo(), { description = "Toggle pseudo-tiling" })
hl.bind(var_mainMod .. " + SHIFT + J", hl.dsp.layout("togglesplit"), { description = "Toggle split layout" })
hl.bind(var_mainMod .. " + I", hl.dsp.exec_cmd("firefox &"), { description = "Open Firefox" })
hl.bind(var_mainMod .. " + n", hl.dsp.exec_cmd("~/.local/bin/hyprltm-net"), { description = "Network manager (hyprltm)" })
-- Move focus with mainMod or Vim-style
hl.bind(var_mainMod .. " + CTRL + h", hl.dsp.focus({ direction = "left" }), { description = "Focus window left" })
hl.bind(var_mainMod .. " + CTRL + l", hl.dsp.focus({ direction = "right" }), { description = "Focus window right" })
hl.bind(var_mainMod .. " + CTRL + k", hl.dsp.focus({ direction = "up" }), { description = "Focus window up" })
hl.bind(var_mainMod .. " + CTRL + j", hl.dsp.focus({ direction = "down" }), { description = "Focus window down" })
-- Move windows with mainMod or Vim-style
hl.bind(var_mainMod .. " + SHIFT + h", hl.dsp.window.move({ direction = "left" }), { description = "Move window left" })
hl.bind(var_mainMod .. " + SHIFT + l", hl.dsp.window.move({ direction = "right" }), { description = "Move window right" })
hl.bind(var_mainMod .. " + SHIFT + k", hl.dsp.window.move({ direction = "up" }), { description = "Move window up" })
hl.bind(var_mainMod .. " + SHIFT + j", hl.dsp.window.move({ direction = "down" }), { description = "Move window down" })
-- Resize focused window with mainMod + Arrows
hl.bind(var_mainMod .. " + left", hl.dsp.window.resize({ x = -10, y = 0, relative = true }), { description = "Resize window left" })
hl.bind(var_mainMod .. " + right", hl.dsp.window.resize({ x = 10, y = 0, relative = true }), { description = "Resize window right" })
hl.bind(var_mainMod .. " + up", hl.dsp.window.resize({ x = 0, y = -10, relative = true }), { description = "Resize window up" })
hl.bind(var_mainMod .. " + down", hl.dsp.window.resize({ x = 0, y = 10, relative = true }), { description = "Resize window down" })
-- Switch workspaces with mainMod + [0-9]
hl.bind(var_mainMod .. " + 1", hl.dsp.focus({ workspace = 1 }), { description = "Switch to workspace 1" })
hl.bind(var_mainMod .. " + 2", hl.dsp.focus({ workspace = 2 }), { description = "Switch to workspace 2" })
hl.bind(var_mainMod .. " + 3", hl.dsp.focus({ workspace = 3 }), { description = "Switch to workspace 3" })
hl.bind(var_mainMod .. " + 4", hl.dsp.focus({ workspace = 4 }), { description = "Switch to workspace 4" })
hl.bind(var_mainMod .. " + 5", hl.dsp.focus({ workspace = 5 }), { description = "Switch to workspace 5" })
hl.bind(var_mainMod .. " + 6", hl.dsp.focus({ workspace = 6 }), { description = "Switch to workspace 6" })
hl.bind(var_mainMod .. " + 7", hl.dsp.focus({ workspace = 7 }), { description = "Switch to workspace 7" })
hl.bind(var_mainMod .. " + 8", hl.dsp.focus({ workspace = 8 }), { description = "Switch to workspace 8" })
hl.bind(var_mainMod .. " + 9", hl.dsp.focus({ workspace = 9 }), { description = "Switch to workspace 9" })
hl.bind(var_mainMod .. " + 0", hl.dsp.focus({ workspace = 10 }), { description = "Switch to workspace 10" })
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"), {
repeating = true,
description = "Volume up",
})
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), {
locked = true,
description = "Volume down",
})
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
hl.bind(var_mainMod .. " + SHIFT + 1", hl.dsp.window.move({ workspace = 1 }), { description = "Move window to workspace 1" })
hl.bind(var_mainMod .. " + SHIFT + 2", hl.dsp.window.move({ workspace = 2 }), { description = "Move window to workspace 2" })
hl.bind(var_mainMod .. " + SHIFT + 3", hl.dsp.window.move({ workspace = 3 }), { description = "Move window to workspace 3" })
hl.bind(var_mainMod .. " + SHIFT + 4", hl.dsp.window.move({ workspace = 4 }), { description = "Move window to workspace 4" })
hl.bind(var_mainMod .. " + SHIFT + 5", hl.dsp.window.move({ workspace = 5 }), { description = "Move window to workspace 5" })
hl.bind(var_mainMod .. " + SHIFT + 6", hl.dsp.window.move({ workspace = 6 }), { description = "Move window to workspace 6" })
hl.bind(var_mainMod .. " + SHIFT + 7", hl.dsp.window.move({ workspace = 7 }), { description = "Move window to workspace 7" })
hl.bind(var_mainMod .. " + SHIFT + 8", hl.dsp.window.move({ workspace = 8 }), { description = "Move window to workspace 8" })
hl.bind(var_mainMod .. " + SHIFT + 9", hl.dsp.window.move({ workspace = 9 }), { description = "Move window to workspace 9" })
hl.bind(var_mainMod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = 10 }), { description = "Move window to workspace 10" })
-- # Example special workspace (scratchpad)
-- bind = $mainMod, S, togglespecialworkspace, magic
-- bind = $mainMod SHIFT, S, movetoworkspace, special:magic
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(var_mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }), { description = "Next workspace (scroll down)" })
hl.bind(var_mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }), { description = "Previous workspace (scroll up)" })
-- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(var_mainMod .. " + mouse:272", hl.dsp.window.drag(), {
mouse = true,
description = "Move window with mouse",
})
hl.bind(var_mainMod .. " + mouse:273", hl.dsp.window.resize(), {
mouse = true,
description = "Resize window with mouse",
})
-- Laptop multimedia keys for volume and LCD brightness
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), {
repeating = true,
locked = true,
description = "Volume up (repeat)",
})
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), {
repeating = true,
locked = true,
description = "Volume down (repeat)",
})
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), {
repeating = true,
locked = true,
description = "Mute audio",
})
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), {
repeating = true,
locked = true,
description = "Mute microphone",
})
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), {
repeating = true,
locked = true,
description = "Brightness up",
})
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), {
repeating = true,
locked = true,
description = "Brightness down",
})
-- Requires playerctl
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), {
locked = true,
description = "Next track",
})
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), {
locked = true,
description = "Play/Pause",
})
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), {
locked = true,
description = "Play/Pause",
})
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), {
locked = true,
description = "Previous track",
})
-- Screenshots
hl.bind("PRINT", hl.dsp.exec_cmd("hyprshot -m region --output-folder " .. var_screenshot_folder), {
locked = true,
description = "Screenshot region",
})
hl.bind("CTRL + PRINT", hl.dsp.exec_cmd("hyprshot -m window --output-folder " .. var_screenshot_folder), {
locked = true,
description = "Screenshot window",
})
hl.bind("SHIFT + PRINT", hl.dsp.exec_cmd("hyprshot -m active --output-folder " .. var_screenshot_folder), {
locked = true,
description = "Screenshot active monitor",
})
-- Screenlock
hl.bind("CTRL + ALT + L", hl.dsp.exec_cmd("hyprlock"), {locked = true, description = "Lock screen"})
hl.bind(var_mainMod .. " + L", hl.dsp.exec_cmd("hyprlock"), {locked = true, description = "Lock screen"})
-- Keybind overview popup
hl.bind(var_mainMod .. " + K", hl.dsp.exec_cmd("sh ~/.config/hypr/scripts/show-keybinds.sh"), { description = "Show keybind overview" })
-- #############################
-- ## WINDOWS AND WORKSPACES ###
-- #############################
-- See https://wiki.hypr.land/Configuring/Window-Rules/ for more
-- See https://wiki.hypr.land/Configuring/Workspace-Rules/ for workspace rules
-- Example windowrules that are useful
-- Ignore maximize requests from all apps. You'll probably like this.
hl.window_rule({
name = "suppress-maximize-events",
match = {
class = ".*",
},
suppress_event = "maximize",
})
-- Fix some dragging issues with XWayland
hl.window_rule({
name = "fix-xwayland-drags",
match = {
class = "^$",
title = "^$",
xwayland = true,
float = true,
fullscreen = false,
pin = false,
},
no_focus = true,
})
-- Hyprland-run windowrule
hl.config({
decoration = {
blur = {
size = 8,
passes = 2,
},
},
})
hl.window_rule({
name = "move-hyprland-run",
match = {
class = "hyprland-run",
},
move = "20 monitor_h-120",
float = true,
})
hl.window_rule({
name = "opacity-kitty-dolphin",
match = {
class = ".*(kitty|dolphin).*",
},
opacity = "0.90 0.80",
})
hl.layer_rule({
match = {
namespace = "waybar",
},
blur = true,
})
hl.layer_rule({
match = {
namespace = "waybar",
},
blur_popups = true,
})
hl.window_rule({
name = "no-rounding-fullscreen",
match = {
fullscreen = 1,
},
rounding = 0,
border_size = 0,
})
-- windowrule {
-- name = no-rounding-steam-games
-- match:class = ^steam_app_.*$
-- rounding = 0
-- border_size = 0
-- }
-- windowrule {
-- name = no-rounding-gamescope
-- match:class = ^gamescope$
-- rounding = 0
-- border_size = 0
-- }
hl.on("hyprland.start", function()
hl.exec_cmd("sh ~/.config/hypr/scripts/portal-host-override.sh")
hl.exec_cmd("sh ~/.config/hypr/scripts/ensure-mime-defaults.sh")
end)
require("modules.environment_variables")
require("modules.look_and_feel")
require("modules.input")
require("modules.keybinds")
require("modules.windows_and_workspaces")
-- HyprMod managed settings
require("hyprland-gui")
-106
View File
@@ -1,106 +0,0 @@
# sample hyprlock.conf
# for more configuration options, refer https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock
#
# rendered text in all widgets supports pango markup (e.g. <b> or <i> tags)
# ref. https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/#general-remarks
#
# shortcuts to clear password buffer: ESC, Ctrl+U, Ctrl+Backspace
#
# you can get started by copying this config to ~/.config/hypr/hyprlock.conf
#
$font = Monospace
general {
hide_cursor = false
}
# uncomment to enable fingerprint authentication
# auth {
# fingerprint {
# enabled = true
# ready_message = Scan fingerprint to unlock
# present_message = Scanning...
# retry_delay = 250 # in milliseconds
# }
# }
animations {
enabled = true
bezier = linear, 1, 1, 0, 0
animation = fadeIn, 1, 5, linear
animation = fadeOut, 1, 5, linear
animation = inputFieldDots, 1, 2, linear
}
background {
monitor =
path = screenshot
blur_passes = 3
}
input-field {
monitor =
size = 20%, 5%
outline_thickness = 3
inner_color = rgba(0, 0, 0, 0.0) # no fill
outer_color = rgba(33ccffee) rgba(00ff99ee) 45deg
check_color = rgba(00ff99ee) rgba(ff6633ee) 120deg
fail_color = rgba(ff6633ee) rgba(ff0066ee) 40deg
font_color = rgb(143, 143, 143)
fade_on_empty = false
rounding = 15
font_family = $font
placeholder_text = Input password...
fail_text = $PAMFAIL
# uncomment to use a letter instead of a dot to indicate the typed password
# dots_text_format = *
# dots_size = 0.4
dots_spacing = 0.3
# uncomment to use an input indicator that does not show the password length (similar to swaylock's input indicator)
# hide_input = true
position = 0, -20
halign = center
valign = center
}
# TIME
label {
monitor =
text = $TIME # ref. https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/#variable-substitution
font_size = 90
font_family = $font
position = -30, 0
halign = right
valign = top
}
# DATE
label {
monitor =
text = cmd[update:60000] date +"%A, %d %B %Y" # update every 60 seconds
font_size = 25
font_family = $font
position = -30, -150
halign = right
valign = top
}
label {
monitor =
text = $LAYOUT[en,ru]
font_size = 24
onclick = hyprctl switchxkblayout all next
position = 250, -20
halign = center
valign = center
}
+40
View File
@@ -0,0 +1,40 @@
# hyprsaver.toml — chill playlist: calm shaders + cool palettes, cycling.
# Location: ~/.config/hypr/hyprsaver.toml (stowed from dotfiles).
# Names verified against `hyprsaver --list-shaders` / `--list-palettes`.
# Everything else uses hyprsaver's built-in defaults (see
# /usr/share/hyprsaver/examples/config.toml for the full reference).
[general]
fps = 30
shader = "cycle"
palette = "cycle"
shader_cycle_interval = 300
palette_cycle_interval = 60
cycle_order = "random"
synced = true
shader_playlist = "chill"
palette_playlist = "chill"
[playlists.chill]
shaders = [
"plasma",
"marble",
"snowfall",
"aurora",
"clouds",
"planet",
"starfield",
"fireflies",
]
palettes = [
"vaporwave",
"frost",
"ocean",
"aurora",
]
[behavior]
fade_in_ms = 800
fade_out_ms = 400
dismiss_on = ["key", "mouse_move", "mouse_click", "touch"]
exclusive_keyboard = true
@@ -0,0 +1,12 @@
-- See https://wiki.hypr.land/Configuring/Environment-variables/
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_TYPE", "wayland")
hl.env("XDG_MENU_PREFIX", "plasma-")
hl.env("GTK_USE_PORTAL", "1")
hl.env("GTK_THEME", os.getenv("THEME_GTK") or "Adwaita:dark")
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
hl.env("QT_QPA_PLATFORMTHEME", "kde")
+33
View File
@@ -0,0 +1,33 @@
-- https://wiki.hypr.land/Configuring/Variables/#input
hl.config({
input = {
kb_layout = "de",
kb_variant = "",
kb_model = "",
kb_options = "grp:alt_shift_toggle",
kb_rules = "",
follow_mouse = 1,
numlock_by_default = true,
sensitivity = 0,
touchpad = {
natural_scroll = true,
},
},
})
-- See https://wiki.hypr.land/Configuring/Gestures
hl.gesture({
fingers = 3,
direction = "horizontal",
action = "workspace",
})
-- Example per-device config
-- See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more
hl.device({
name = "epic-mouse-v1",
sensitivity = -0.5,
})
+237
View File
@@ -0,0 +1,237 @@
local var = require("modules.variables")
local command = require("modules.shell_commands")
-- See https://wiki.hypr.land/Configuring/Keywords/
-- Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more
hl.bind(var.mainMod .. " + RETURN", hl.dsp.exec_cmd(var.terminal), { description = "Open terminal (kitty)" })
hl.bind(var.mainMod .. " + Q", hl.dsp.window.close(), { description = "Close focused window" })
hl.bind(
var.mainMod .. " + ESCAPE",
hl.dsp.exec_cmd(command.session),
{ description = "Session menu (logout/reboot/shutdown)" }
)
hl.bind(var.mainMod .. " + SHIFT + ESCAPE", hl.dsp.exec_cmd(command.logout), { description = "Exit Hyprland" })
hl.bind(var.mainMod .. " + CTRL + ESCAPE", hl.dsp.exec_cmd(command.shutdown), { description = "Power off the system" })
hl.bind(var.mainMod .. " + ALT + ESCAPE", hl.dsp.exec_cmd(command.reboot), { description = "Reboot the system" })
hl.bind(var.mainMod .. " + E", hl.dsp.exec_cmd(var.fileManager), { description = "Open file manager (dolphin)" })
hl.bind(var.mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }), { description = "Toggle floating window" })
hl.bind(var.mainMod .. " + SPACE", hl.dsp.exec_cmd(command.menu), { description = "Open app launcher" })
hl.bind(var.mainMod .. " + P", hl.dsp.window.pseudo(), { description = "Toggle pseudo-tiling" })
hl.bind(var.mainMod .. " + SHIFT + J", hl.dsp.layout("togglesplit"), { description = "Toggle split layout" })
hl.bind(var.mainMod .. " + I", hl.dsp.exec_cmd("firefox &"), { description = "Open Firefox" })
hl.bind(var.mainMod .. " + n", hl.dsp.exec_cmd("nm-connection-editor"), { description = "Network manager" })
hl.bind(var.mainMod .. " + comma", hl.dsp.exec_cmd(command.settings), { description = "settings menu" })
hl.bind(var.mainMod .. " + S", hl.dsp.exec_cmd(command.control_center), { description = "Control center" })
-- Move focus with mainMod or Vim-style
hl.bind(var.mainMod .. " + CTRL + h", hl.dsp.focus({ direction = "left" }), { description = "Focus window left" })
hl.bind(var.mainMod .. " + CTRL + l", hl.dsp.focus({ direction = "right" }), { description = "Focus window right" })
hl.bind(var.mainMod .. " + CTRL + k", hl.dsp.focus({ direction = "up" }), { description = "Focus window up" })
hl.bind(var.mainMod .. " + CTRL + j", hl.dsp.focus({ direction = "down" }), { description = "Focus window down" })
-- Move windows with mainMod or Vim-style
hl.bind(var.mainMod .. " + SHIFT + h", hl.dsp.window.move({ direction = "left" }), { description = "Move window left" })
hl.bind(
var.mainMod .. " + SHIFT + l",
hl.dsp.window.move({ direction = "right" }),
{ description = "Move window right" }
)
hl.bind(var.mainMod .. " + SHIFT + k", hl.dsp.window.move({ direction = "up" }), { description = "Move window up" })
hl.bind(var.mainMod .. " + SHIFT + j", hl.dsp.window.move({ direction = "down" }), { description = "Move window down" })
-- Resize focused window with mainMod + Arrows
hl.bind(
var.mainMod .. " + left",
hl.dsp.window.resize({ x = -10, y = 0, relative = true }),
{ description = "Resize window left" }
)
hl.bind(
var.mainMod .. " + right",
hl.dsp.window.resize({ x = 10, y = 0, relative = true }),
{ description = "Resize window right" }
)
hl.bind(
var.mainMod .. " + up",
hl.dsp.window.resize({ x = 0, y = -10, relative = true }),
{ description = "Resize window up" }
)
hl.bind(
var.mainMod .. " + down",
hl.dsp.window.resize({ x = 0, y = 10, relative = true }),
{ description = "Resize window down" }
)
-- Switch workspaces with mainMod + [0-9]
hl.bind(var.mainMod .. " + 1", hl.dsp.focus({ workspace = 1 }), { description = "Switch to workspace 1" })
hl.bind(var.mainMod .. " + 2", hl.dsp.focus({ workspace = 2 }), { description = "Switch to workspace 2" })
hl.bind(var.mainMod .. " + 3", hl.dsp.focus({ workspace = 3 }), { description = "Switch to workspace 3" })
hl.bind(var.mainMod .. " + 4", hl.dsp.focus({ workspace = 4 }), { description = "Switch to workspace 4" })
hl.bind(var.mainMod .. " + 5", hl.dsp.focus({ workspace = 5 }), { description = "Switch to workspace 5" })
hl.bind(var.mainMod .. " + 6", hl.dsp.focus({ workspace = 6 }), { description = "Switch to workspace 6" })
hl.bind(var.mainMod .. " + 7", hl.dsp.focus({ workspace = 7 }), { description = "Switch to workspace 7" })
hl.bind(var.mainMod .. " + 8", hl.dsp.focus({ workspace = 8 }), { description = "Switch to workspace 8" })
hl.bind(var.mainMod .. " + 9", hl.dsp.focus({ workspace = 9 }), { description = "Switch to workspace 9" })
hl.bind(var.mainMod .. " + 0", hl.dsp.focus({ workspace = 10 }), { description = "Switch to workspace 10" })
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"), {
repeating = true,
description = "Volume up",
})
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), {
locked = true,
description = "Volume down",
})
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
hl.bind(
var.mainMod .. " + SHIFT + 1",
hl.dsp.window.move({ workspace = 1 }),
{ description = "Move window to workspace 1" }
)
hl.bind(
var.mainMod .. " + SHIFT + 2",
hl.dsp.window.move({ workspace = 2 }),
{ description = "Move window to workspace 2" }
)
hl.bind(
var.mainMod .. " + SHIFT + 3",
hl.dsp.window.move({ workspace = 3 }),
{ description = "Move window to workspace 3" }
)
hl.bind(
var.mainMod .. " + SHIFT + 4",
hl.dsp.window.move({ workspace = 4 }),
{ description = "Move window to workspace 4" }
)
hl.bind(
var.mainMod .. " + SHIFT + 5",
hl.dsp.window.move({ workspace = 5 }),
{ description = "Move window to workspace 5" }
)
hl.bind(
var.mainMod .. " + SHIFT + 6",
hl.dsp.window.move({ workspace = 6 }),
{ description = "Move window to workspace 6" }
)
hl.bind(
var.mainMod .. " + SHIFT + 7",
hl.dsp.window.move({ workspace = 7 }),
{ description = "Move window to workspace 7" }
)
hl.bind(
var.mainMod .. " + SHIFT + 8",
hl.dsp.window.move({ workspace = 8 }),
{ description = "Move window to workspace 8" }
)
hl.bind(
var.mainMod .. " + SHIFT + 9",
hl.dsp.window.move({ workspace = 9 }),
{ description = "Move window to workspace 9" }
)
hl.bind(
var.mainMod .. " + SHIFT + 0",
hl.dsp.window.move({ workspace = 10 }),
{ description = "Move window to workspace 10" }
)
-- # Example special workspace (scratchpad)
-- bind = $mainMod, S, togglespecialworkspace, magic
-- bind = $mainMod SHIFT, S, movetoworkspace, special:magic
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(
var.mainMod .. " + mouse_down",
hl.dsp.focus({ workspace = "e+1" }),
{ description = "Next workspace (scroll down)" }
)
hl.bind(
var.mainMod .. " + mouse_up",
hl.dsp.focus({ workspace = "e-1" }),
{ description = "Previous workspace (scroll up)" }
)
-- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(var.mainMod .. " + mouse:272", hl.dsp.window.drag(), {
mouse = true,
description = "Move window with mouse",
})
hl.bind(var.mainMod .. " + mouse:273", hl.dsp.window.resize(), {
mouse = true,
description = "Resize window with mouse",
})
-- Laptop multimedia keys for volume and LCD brightness
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), {
repeating = true,
locked = true,
description = "Volume up (repeat)",
})
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), {
repeating = true,
locked = true,
description = "Volume down (repeat)",
})
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), {
repeating = true,
locked = true,
description = "Mute audio",
})
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), {
repeating = true,
locked = true,
description = "Mute microphone",
})
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), {
repeating = true,
locked = true,
description = "Brightness up",
})
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), {
repeating = true,
locked = true,
description = "Brightness down",
})
-- Requires playerctl
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), {
locked = true,
description = "Next track",
})
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), {
locked = true,
description = "Play/Pause",
})
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), {
locked = true,
description = "Play/Pause",
})
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), {
locked = true,
description = "Previous track",
})
-- Screenshots
hl.bind("PRINT", hl.dsp.exec_cmd("hyprshot -m region --output-folder " .. var.screenshot_folder), {
locked = true,
description = "Screenshot region",
})
hl.bind("CTRL + PRINT", hl.dsp.exec_cmd("hyprshot -m window --output-folder " .. var.screenshot_folder), {
locked = true,
description = "Screenshot window",
})
hl.bind("SHIFT + PRINT", hl.dsp.exec_cmd("hyprshot -m active --output-folder " .. var.screenshot_folder), {
locked = true,
description = "Screenshot active monitor",
})
hl.bind(var.mainMod .. " + L", hl.dsp.exec_cmd(command.lock), { locked = true, description = "Lock screen" })
hl.bind(var.mainMod .. " + SHIFT + L", hl.dsp.exec_cmd(command.screensaver), { description = "Start screensaver (any key quits)" })
hl.bind(var.mainMod .. " + K", hl.dsp.exec_cmd(command.keybinds_show), { description = "Show keybind overview" })
hl.bind(var.mainMod .. " + W", hl.dsp.exec_cmd(command.wallpaper_select), { description = "Wallpaper select" })
-- Caelestia extras
hl.bind(var.mainMod .. " + SHIFT + V", hl.dsp.exec_cmd(command.clipboard), { description = "Clipboard history" })
hl.bind(var.mainMod .. " + period", hl.dsp.exec_cmd(command.emoji), { description = "Emoji picker" })
hl.bind(var.mainMod .. " + SHIFT + K", hl.dsp.exec_cmd(command.show_all), { description = "Toggle utilities" })
hl.bind("CTRL + ALT + C", hl.dsp.exec_cmd(command.clear_notifications), { description = "Clear notifications" })
+257
View File
@@ -0,0 +1,257 @@
local var = require("modules.variables")
-- Refer to https://wiki.hypr.land/Configuring/Variables/
-- https://wiki.hypr.land/Configuring/Variables/#general
hl.config({
general = {
gaps_in = 3,
gaps_out = 4,
border_size = 3,
},
})
-- https://wiki.hypr.land/Configuring/Variables/#variable-types for info about colors
hl.config({
general = {
col = {
active_border = var.color_active_border,
inactive_border = var.color_inactive_border,
},
},
})
-- Set to true enable resizing windows by clicking and dragging on borders and gaps
hl.config({
general = {
resize_on_border = true,
},
})
-- Please see https://wiki.hypr.land/Configuring/Tearing/ before you turn this on
hl.config({
general = {
allow_tearing = false,
layout = "dwindle",
},
})
-- https://wiki.hypr.land/Configuring/Variables/#decoration
hl.config({
decoration = {
rounding = 5,
rounding_power = 2,
},
})
-- Change transparency of focused and unfocused windows
hl.config({
decoration = {
active_opacity = 1.0,
inactive_opacity = 1.0,
shadow = {
enabled = true,
range = 10,
render_power = 3,
color = var.color_decoration_shadow,
},
},
})
-- https://wiki.hypr.land/Configuring/Variables/#blur
hl.config({
decoration = {
blur = {
enabled = true,
size = 10,
passes = 2,
vibrancy = 0.1696,
},
},
})
-- https://wiki.hypr.land/Configuring/Variables/#animations
hl.config({
animations = {
enabled = true,
},
})
-- Default curves, see https://wiki.hypr.land/Configuring/Animations/#curves
-- NAME, X0, Y0, X1, Y1
hl.curve("easeOutQuint", { type = "bezier", points = { { 0.23, 1 }, { 0.32, 1 } } })
hl.curve("easeInOutCubic", { type = "bezier", points = { { 0.65, 0.05 }, { 0.36, 1 } } })
hl.curve("linear", { type = "bezier", points = { { 0, 0 }, { 1, 1 } } })
hl.curve("almostLinear", { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1 } } })
hl.curve("quick", { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1 } } })
-- Default animations, see https://wiki.hypr.land/Configuring/Animations/
-- NAME, ONOFF, SPEED, CURVE, [STYLE]
hl.animation({
leaf = "global",
enabled = true,
speed = 10,
bezier = "default",
})
hl.animation({
leaf = "border",
enabled = true,
speed = 5.39,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "windows",
enabled = true,
speed = 4.79,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "windowsIn",
enabled = true,
speed = 4.1,
bezier = "easeOutQuint",
style = "popin 87%",
})
hl.animation({
leaf = "windowsOut",
enabled = true,
speed = 1.49,
bezier = "linear",
style = "popin 87%",
})
hl.animation({
leaf = "fadeIn",
enabled = true,
speed = 1.73,
bezier = "almostLinear",
})
hl.animation({
leaf = "fadeOut",
enabled = true,
speed = 1.46,
bezier = "almostLinear",
})
hl.animation({
leaf = "fade",
enabled = true,
speed = 3.03,
bezier = "quick",
})
hl.animation({
leaf = "layers",
enabled = true,
speed = 3.81,
bezier = "easeOutQuint",
})
hl.animation({
leaf = "layersIn",
enabled = true,
speed = 4,
bezier = "easeOutQuint",
style = "fade",
})
hl.animation({
leaf = "layersOut",
enabled = true,
speed = 1.5,
bezier = "linear",
style = "fade",
})
hl.animation({
leaf = "fadeLayersIn",
enabled = true,
speed = 1.79,
bezier = "almostLinear",
})
hl.animation({
leaf = "fadeLayersOut",
enabled = true,
speed = 1.39,
bezier = "almostLinear",
})
hl.animation({
leaf = "workspaces",
enabled = true,
speed = 1.94,
bezier = "almostLinear",
style = "slide",
})
hl.animation({
leaf = "workspacesIn",
enabled = true,
speed = 1.21,
bezier = "almostLinear",
style = "slide",
})
hl.animation({
leaf = "workspacesOut",
enabled = true,
speed = 1.94,
bezier = "almostLinear",
style = "slide",
})
hl.animation({
leaf = "zoomFactor",
enabled = true,
speed = 7,
bezier = "quick",
})
-- Ref https://wiki.hypr.land/Configuring/Workspace-Rules/
-- "Smart gaps" / "No gaps when only"
-- uncomment all if you wish to use that.
hl.workspace_rule({
workspace = "w[tv1]",
gaps_out = 0,
gaps_in = 0,
})
hl.workspace_rule({
workspace = "f[1]",
gaps_out = 0,
gaps_in = 0,
})
hl.window_rule({
name = "no-gaps-wtv1",
match = {
float = false,
workspace = "w[tv1]",
},
border_size = 0,
rounding = 0,
})
hl.window_rule({
name = "no-gaps-f1",
match = {
float = false,
workspace = "f[1]",
},
border_size = 0,
rounding = 0,
})
-- See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more
hl.config({
dwindle = {
preserve_split = true,
},
})
-- See https://wiki.hypr.land/Configuring/Master-Layout/ for more
hl.config({
master = {
new_status = "master",
},
})
-- https://wiki.hypr.land/Configuring/Variables/#misc
hl.config({
misc = {
force_default_wallpaper = -1,
disable_hyprland_logo = false,
},
})
@@ -1 +0,0 @@
monitor=,preferred,auto,1.0
@@ -1 +0,0 @@
monitor=,preferred,auto,1.0
@@ -1,9 +0,0 @@
-- monitor=,preferred,auto,1.0
hl.monitor({
output = "",
disabled = false,
mode = "preferred",
position = "auto",
scale = 1.0,
})
@@ -1,18 +0,0 @@
# monitorv2 {
# output = DP-2
# mode = highres highrr
# position = 0x0
# scale = 1.2
# bitdepth = 10
# cm = hdr
# supports_wide_color = 1
# supports_hdr = 1
# sdr_min_luminance = 0.005
# sdr_max_luminance = 200
# min_luminance = 0.002
# max_luminance = 200
# max_avg_luminance = 150
# }
monitor = DP-2, preferred, auto-left, 1.5
monitor = DP-3, preferred, auto-right, 1.0
@@ -1,14 +0,0 @@
hl.monitor({
output = "DP-2",
disabled = false,
mode = "preferred",
position = "auto-left",
scale = 1.5,
})
hl.monitor({
output = "DP-3",
disabled = false,
mode = "preferred",
position = "auto-right",
scale = 1.0,
})
@@ -0,0 +1,36 @@
-- Default
hl.monitor({
output = "",
disabled = false,
mode = "preferred",
position = "auto",
scale = 1.0,
})
-- -- Buntes Monster
-- hl.monitor({
-- output = "DP-2",
-- disabled = false,
-- mode = "preferred",
-- position = "auto-left",
-- scale = 1.5,
-- })
-- hl.monitor({
-- output = "DP-3",
-- disabled = false,
-- mode = "preferred",
-- position = "auto-right",
-- scale = 1.0,
-- })
-- -- Archtop
-- hl.monitor({
-- output = "",
-- disabled = false,
-- mode = "preferred",
-- position = "auto",
-- scale = 1.0,
-- })
+13
View File
@@ -0,0 +1,13 @@
-- Screensaver commands for idle (hypridle on-timeout/on-resume) and manual
-- (SUPER+SHIFT+L) use. scripts/screensaver-start.sh and
-- scripts/screensaver-stop.sh exec the .start / .stop command below.
--
-- Active backend: tte (fullscreen kitty + terminal-text-effects).
return {
start = "~/.config/hypr/scripts/launch-screensaver.sh",
stop = "~/.config/hypr/scripts/screensaver-stop.sh",
-- Alternative backend: hyprsaver (GPU fractal shaders, wlr-layer-shell).
-- Swap the commented pair in to switch (no other file changes needed).
-- start = "hyprsaver",
-- stop = "hyprsaver --quit",
}
@@ -0,0 +1,24 @@
-- Caelestia shell commands. This branch is caelestia-only;
-- revert to Noctalia by switching branches.
-- Caelestia drawers (see ScreenState.qml): bar, osd, session, launcher,
-- dashboard, utilities, sidebar. Wallpaper goes through the launcher
-- (type `>wallpaper`) or `caelestia wallpaper`.
return {
session = "caelestia shell drawers toggle session",
logout = "hyprctl dispatch exit",
shutdown = "systemctl poweroff",
reboot = "systemctl reboot",
menu = "caelestia shell drawers toggle launcher",
settings = "caelestia shell drawers toggle dashboard",
control_center = "caelestia shell drawers toggle sidebar",
lock = "caelestia shell lock lock",
wallpaper_select = "caelestia shell drawers toggle launcher && sleep 0.1 && wtype \">wallpaper \"",
clipboard = "caelestia clipboard",
clipboard_delete = "caelestia clipboard -d",
emoji = "caelestia emoji -p",
show_all = "caelestia shell drawers toggle utilities",
clear_notifications = "caelestia shell notifs clear",
keybinds_show = "sh ~/.config/hypr/scripts/show-keybinds.sh",
screensaver = "sh ~/.config/hypr/scripts/screensaver-start.sh force",
}
+20
View File
@@ -0,0 +1,20 @@
local theme = dofile(os.getenv("HOME") .. "/.config/themes/current/theme.lua")
-- local var_color_active_border = theme.border_active
-- local var_color_inactive_border = theme.border_inactive
-- local var_color_decoration_shadow = theme.shadow
-- local var_mainMod = "SUPER"
-- local var_terminal = "kitty"
-- local var_fileManager = "dolphin"
-- local var_menu = "noctalia msg panel-toggle launcher"
-- local var_screenshot_folder = "~/Bilder/Screenshots/"
return {
color_active_border = theme.border_active,
color_inactive_border = theme.border_inactive,
color_decoration_shadow = theme.shadow,
mainMod = "SUPER",
terminal = "kitty",
fileManager = "dolphin",
screenshot_folder = "~/Bilder/Screenshots/",
}
@@ -0,0 +1,138 @@
-- See https://wiki.hypr.land/Configuring/Window-Rules/ for more
-- See https://wiki.hypr.land/Configuring/Workspace-Rules/ for workspace rules
-- Example windowrules that are useful
-- Ignore maximize requests from all apps. You'll probably like this.
hl.window_rule({
name = "suppress-maximize-events",
match = {
class = ".*",
},
suppress_event = "maximize",
})
-- Fix some dragging issues with XWayland
hl.window_rule({
name = "fix-xwayland-drags",
match = {
class = "^$",
title = "^$",
xwayland = true,
float = true,
fullscreen = false,
pin = false,
},
no_focus = true,
})
-- Hyprland-run windowrule
hl.config({
decoration = {
blur = {
size = 8,
passes = 2,
},
},
})
hl.window_rule({
name = "move-hyprland-run",
match = {
class = "hyprland-run",
},
move = "20 monitor_h-120",
float = true,
})
hl.window_rule({
name = "keybinds-float",
match = {
class = "keybinds",
},
float = true,
size = "900 700",
center = true,
dim_around = true,
})
hl.window_rule({
name = "opacity-kitty-dolphin",
match = {
class = ".*(kitty|dolphin).*",
},
opacity = "0.80 0.70",
})
-- Noctalia shell surfaces: blur bars/panels/dock/notifications and let
-- Noctalia run its own animations (no Hyprland layer animation on top).
hl.layer_rule({
name = "noctalia",
match = {
namespace = "^noctalia-(bar-.+|notification|dock|panel|attached-panel|osd|window-switcher)$",
},
no_anim = true,
ignore_alpha = 0.5,
blur = true,
blur_popups = true,
})
hl.layer_rule({
name = "caelestia",
match = {
namespace = "^caelestia-.*$",
},
no_anim = true,
ignore_alpha = 0.5,
blur = true,
blur_popups = true,
})
hl.window_rule({
name = "noctalia-settings",
match = {
class = "dev.noctalia.Noctalia",
},
float = true,
size = "1080 920",
})
hl.window_rule({
name = "no-rounding-fullscreen",
match = {
fullscreen = 1,
},
rounding = 0,
border_size = 0,
})
-- Manual tte screensaver preview (SUPER+SHIFT+L): fullscreen kitty.
hl.window_rule({
name = "screensaver-fullscreen",
match = {
class = "org.screensaver",
},
fullscreen = true,
float = true,
})
-- windowrule {
-- name = no-rounding-steam-games
-- match:class = ^steam_app_.*$
-- rounding = 0
-- border_size = 0
-- }
-- windowrule {
-- name = no-rounding-gamescope
-- match:class = ^gamescope$
-- rounding = 0
-- border_size = 0
-- }
+4
View File
@@ -0,0 +1,4 @@
hyprland
// idle looks good on you
ArchTop is relaxing 🧘
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# launch-screensaver.sh — idle-triggered tte screensaver (hypridle on-timeout).
# Spawns one fullscreen kitty running screensaver-tte.sh per monitor.
# Usage: launch-screensaver.sh [force]
# force ignore the screensaver-off toggle file.
# Toggle off: touch ~/.local/state/hypr/screensaver-off
#
# Lessons baked in: no focus-restore after spawn (it raced the new window and
# caused flash-then-nothing), no pkill -f patterns anywhere (teardown is done
# by screensaver-stop.sh via exact client PIDs).
set -euo pipefail
SCREENSAVER_CLASS="org.screensaver"
TOGGLE_FILE="$HOME/.local/state/hypr/screensaver-off"
command -v tte >/dev/null 2>&1 || exit 1
command -v kitty >/dev/null 2>&1 || exit 1
# Already running (precise client check).
if hyprctl clients -j 2>/dev/null | jq -e '.[] | select(.class=="org.screensaver")' >/dev/null 2>&1; then
exit 0
fi
# Opt-out toggle (unless forced, e.g. manual invocation).
if [[ -f "$TOGGLE_FILE" ]] && [[ "${1:-}" != "force" ]]; then
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# hyprctl prints plain-text errors (not JSON) when HYPRLAND_INSTANCE_SIGNATURE
# is stale (e.g. shell/tmux predates the current compositor). Fail clearly
# instead of dumping a jq parse error.
monitors_json="$(hyprctl monitors -j 2>/dev/null)" || {
echo "launch-screensaver: hyprctl failed - is HYPRLAND_INSTANCE_SIGNATURE stale? (try a fresh terminal)" >&2
exit 1
}
echo "$monitors_json" | jq -e . >/dev/null 2>&1 || {
echo "launch-screensaver: hyprctl did not return JSON - stale HYPRLAND_INSTANCE_SIGNATURE?" >&2
exit 1
}
# NOTE: hyprmod Lua runtime (Hyprland 0.56.x) evaluates `hyprctl dispatch` args
# as Lua — classic `dispatch focusmonitor eDP-1` fails. Dispatchers must be
# hl.dsp.* expressions. Focus each monitor before exec so the saver kitty
# spawns there; deliberately no focus-restore afterwards (spawn race).
for m in $(echo "$monitors_json" | jq -r '.[] | .name'); do
hyprctl dispatch "hl.dsp.focus({monitor=\"$m\"})" >/dev/null 2>&1
hyprctl dispatch "hl.dsp.exec_cmd('kitty --class=\"$SCREENSAVER_CLASS\" --override font_size=18 --override window_padding_width=0 --override background_opacity=1 --override mouse_hide_wait=1.0 -e \"$SCRIPT_DIR/screensaver-tte.sh\"')" >/dev/null 2>&1
done
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# screensaver-start.sh — exec the start command from modules/screensaver.lua.
# Usage: screensaver-start.sh [force] (forwarded to .sh targets, e.g. the tte
# launcher's toggle bypass; dropped for bare commands like `hyprsaver`).
set -euo pipefail
CMD="$(lua -e 'print(dofile(os.getenv("HOME").."/.config/hypr/modules/screensaver.lua").start)' 2>/dev/null)" || {
echo "screensaver-start: cannot read modules/screensaver.lua" >&2
exit 1
}
CMD="${CMD/#\~/$HOME}"
[[ -n "$CMD" ]] || {
echo "screensaver-start: empty start command" >&2
exit 1
}
if [[ "$CMD" == *.sh ]]; then
exec "$CMD" "$@"
else
# Bare command, may carry flags (e.g. "hyprsaver --quit").
# shellcheck disable=SC2086
exec $CMD
fi
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# screensaver-stop.sh — exec the stop command from modules/screensaver.lua.
# When it points back here (tte backend), run the built-in teardown below:
# kill saver windows by Hyprland client PID (class org.screensaver) plus
# stray tte processes (exact comm match). Never `pkill -f <pattern>`: a
# full-cmdline pattern also matches bystander shells merely mentioning it.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ME="$(realpath "$SCRIPT_DIR/screensaver-stop.sh")"
WANT="$(lua -e 'print(dofile(os.getenv("HOME").."/.config/hypr/modules/screensaver.lua").stop)' 2>/dev/null)" || {
echo "screensaver-stop: cannot read modules/screensaver.lua" >&2
exit 1
}
WANT="${WANT/#\~/$HOME}"
# Alternative backend configured (e.g. "hyprsaver --quit"): run it instead.
if [[ "$(realpath -m "$WANT")" != "$ME" ]]; then
# shellcheck disable=SC2086
exec $WANT
fi
# --- tte teardown ---
pids="$(hyprctl clients -j 2>/dev/null | jq -r '.[] | select(.class=="org.screensaver") | .pid' 2>/dev/null)" || pids=""
if [[ -n "${pids:-}" ]]; then
# shellcheck disable=SC2086
kill $pids 2>/dev/null || true
fi
# tte runs under comm "tte" (verified); -x matches the comm only, so this
# cannot hit bystander shells.
pkill -x tte 2>/dev/null || true
exit 0
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# screensaver-tte.sh — runs inside each fullscreen tte kitty.
# Loops random tte effects until any keypress, then exits (kitty closes).
# Child teardown uses the exact PID ($!) — never pkill -f patterns, which
# would also match bystander shells mentioning the class name.
set -euo pipefail
SCREENSAVER_TEXT="$HOME/.config/hypr/screensaver.txt"
trap 'exit 0' SIGINT SIGTERM SIGHUP SIGQUIT
printf '\033]11;rgb:00/00/00\007' # black background
input="$SCREENSAVER_TEXT"
[[ -f "$input" ]] || input="/etc/hostname"
while true; do
tte -i "$input" \
--frame-rate 60 --canvas-width 0 --canvas-height 0 \
--anchor-canvas c --anchor-text c \
--random-effect --exclude-effects dev_worm \
--no-eol --no-restore-cursor &
TPID=$!
# Wait for tte to appear (Python startup) before polling it.
for _ in $(seq 1 10); do
kill -0 "$TPID" 2>/dev/null || break
pgrep -x tte >/dev/null 2>&1 && break
sleep 0.1
done
while kill -0 "$TPID" 2>/dev/null; do
if read -r -n1 -t 1; then
kill "$TPID" 2>/dev/null || true
wait "$TPID" 2>/dev/null || true
exit 0
fi
done
wait "$TPID" 2>/dev/null || true
# Throttle respawn if tte exits instantly (e.g. a sub-second effect).
sleep 0.2
done
+15 -44
View File
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# show-keybinds.sh — floating keybind overview popup.
#
# Reads the live keybind list from `hyprctl binds -j` and shows it in a wofi
# popup (single column, sorted A-Z, fuzzy-searchable, closes on Esc).
# Pressing Enter on a row executes that keybind's action via the compositor's
# Lua state (hl.dispatch on the bind's stored dispatcher).
# Reads the live keybind list from `hyprctl binds -j` and shows it in a
# floating kitty window (single column, sorted A-Z, searchable via less).
# Display-only: wofi/rofi are gone (the Noctalia launcher has no stdin-list
# mode), so picking a row to execute is not wired up.
#
# Note: this config uses the Lua API (hl.bind), so `hyprctl binds -j` reports
# key + modmask + an opaque Lua registry reference instead of a readable
@@ -13,7 +13,7 @@
# you change a bind.
#
# Usage: show-keybinds.sh [--print]
# --print print the formatted list to stdout instead of opening wofi
# --print print the formatted list to stdout instead of opening kitty
# (handy for debugging / testing the formatting pipeline)
set -euo pipefail
@@ -22,9 +22,6 @@ set -euo pipefail
# display order. See https://wiki.hypr.land/Configuring/Binds/
readonly MOD_ORDER=(64 SUPER 8 ALT 4 CTRL 1 SHIFT 2 CAPS 16 MOD2 32 MOD3 128 MOD5)
# chord -> Lua registry ref of the dispatcher to run on selection
declare -A dispatch_for
if ! hyprctl binds -j >/dev/null 2>&1; then
echo "hyprctl binds failed - are you inside a Hyprland session?" >&2
exit 1
@@ -38,8 +35,6 @@ rows=()
# like the (usually empty) submap. \x1f is not whitespace, so every field
# keeps its position.
while IFS=$'\x1f' read -r modmask key description submap arg; do
raw_key="$key"
# Humanize mouse-button binds.
case "$key" in
mouse:272) key="LMB" ;;
@@ -68,18 +63,6 @@ while IFS=$'\x1f' read -r modmask key description submap arg; do
else
rows+=("$(printf '%-26s %s' "$chord" "(no description)")")
fi
# Remember how to run this row. Mouse drag/resize need a real pointer
# gesture, so they stay display-only. First occurrence of a chord wins
# (media keys are often bound twice with different flags).
case "$raw_key" in
mouse:272 | mouse:273) ;;
*)
if [[ -n "$arg" && -z "${dispatch_for[$chord]+x}" ]]; then
dispatch_for[$chord]="$arg"
fi
;;
esac
done < <(hyprctl binds -j | jq -r '.[] | [(.modmask | tostring), .key, .description, .submap, .arg] | join("\u001f")')
if (( ${#rows[@]} == 0 )); then
@@ -96,28 +79,16 @@ if [[ "${1:-}" == "--print" ]]; then
exit 0
fi
if ! command -v wofi >/dev/null 2>&1; then
printf '%s\n' "${rows[@]}"
# Floating display via kitty (class `keybinds` has a float rule in
# hyprland.lua). Rows go through a temp file rather than a stdin pipe so the
# popup does not depend on kitty forwarding stdin to its child; the previous
# run's file is cleaned up on the next invocation. q closes the window.
rm -f /tmp/keybinds.??????.txt 2>/dev/null || true
if command -v kitty >/dev/null 2>&1; then
tmp="$(mktemp /tmp/keybinds.XXXXXX.txt)"
printf '%s\n' "${rows[@]}" > "$tmp"
kitty --class keybinds --title Keybinds less -S "$tmp"
exit 0
fi
sel=""
if ! sel=$(printf '%s\n' "${rows[@]}" | wofi \
--dmenu \
--prompt "Keybinds" \
--location center \
--width 860 \
--lines 22 \
--cache-file /dev/null \
--insensitive \
--no-custom-entry \
--hide-scroll); then
exit 0 # popup dismissed (Esc) - not an error
fi
# Re-derive the chord from the selected row (everything before the first
# double space) and run its stored dispatcher in the compositor's Lua state.
sel_chord="${sel%% *}"
if [[ -n "${dispatch_for[$sel_chord]+x}" ]]; then
hyprctl eval "hl.dispatch(debug.getregistry()[${dispatch_for[$sel_chord]}])" >/dev/null 2>&1 || true
fi
printf '%s\n' "${rows[@]}"
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
out_dir="$HOME/dotfiles/themes/.config/catppuccin/mocha.conf"
url="https://raw.githubusercontent.com/catppuccin/hyprland/main/themes/mocha.conf"
curl -o "$out_dir" "$url"
View File
+3 -1
View File
@@ -3,7 +3,8 @@ map ctrl+shift+c copy_to_clipboard
map ctrl+shift+v paste_from_clipboard
copy_on_select yes
# Coloer theme
# Color theme: central theme (basic/.config/themes). themes/mocha.conf is a
# symlink into the central palette — edit colors there, never here.
include themes/mocha.conf
# Font
@@ -13,3 +14,4 @@ italic_font auto
bold_italic_font auto
font_size 10.0
include themes/noctalia.conf
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
out_dir="$HOME/dotfiles/themes/.config/themes/kitty/catppuccin/mocha.conf"
url="https://raw.githubusercontent.com/catppuccin/kitty/main/themes/mocha.conf"
curl -o "$out_dir" "$url"
-84
View File
@@ -1,84 +0,0 @@
# vim:ft=kitty
## name: Catppuccin Kitty Mocha
## author: Catppuccin Org
## license: MIT
## upstream: https://github.com/catppuccin/kitty/blob/main/themes/mocha.conf
## blurb: Soothing pastel theme for the high-spirited!
# The basic colors
foreground #cdd6f4
background #1e1e2e
selection_foreground #1e1e2e
selection_background #f5e0dc
# Cursor colors
cursor #f5e0dc
cursor_text_color #1e1e2e
# Scrollbar colors
scrollbar_handle_color #9399b2
scrollbar_track_color #45475a
# URL color when hovering with mouse
url_color #f5e0dc
# Kitty window border colors
active_border_color #b4befe
inactive_border_color #6c7086
bell_border_color #f9e2af
# OS Window titlebar colors
wayland_titlebar_color system
macos_titlebar_color system
# Tab bar colors
active_tab_foreground #11111b
active_tab_background #cba6f7
inactive_tab_foreground #cdd6f4
inactive_tab_background #181825
tab_bar_background #11111b
# Colors for marks (marked text in the terminal)
mark1_foreground #1e1e2e
mark1_background #b4befe
mark2_foreground #1e1e2e
mark2_background #cba6f7
mark3_foreground #1e1e2e
mark3_background #74c7ec
# The 16 terminal colors
# black
color0 #45475a
color8 #585b70
# red
color1 #f38ba8
color9 #f38ba8
# green
color2 #a6e3a1
color10 #a6e3a1
# yellow
color3 #f9e2af
color11 #f9e2af
# blue
color4 #89b4fa
color12 #89b4fa
# magenta
color5 #f5c2e7
color13 #f5c2e7
# cyan
color6 #94e2d5
color14 #94e2d5
# white
color7 #bac2de
color15 #a6adc8
+1
View File
@@ -0,0 +1 @@
../../../../basic/.config/themes/themes/catppuccin-mocha/kitty.conf
+66
View File
@@ -0,0 +1,66 @@
# Portable Noctalia config — generated by noctalia-sync-from-gui.sh.
# Validate with: noctalia config validate ~/.config/noctalia/config.toml
[bar.default]
background_opacity = 0.52
capsule = false
center = []
end = []
margin_ends = 0
panel_overlap = 0
position = "bottom"
radius = 0
start = []
thickness = 28
[dock]
background_opacity = 0.68
[lockscreen_widgets]
enabled = false
schema_version = 2
[shell]
font_family = "JetBrainsMono Nerd Font Mono"
[shell.panel]
launcher_placement = "attached"
transparency_mode = "glass"
[theme]
mode = "dark"
builtin = "Catppuccin"
[theme.templates]
enable_builtin_templates = true
builtin_ids = []
[wallpaper]
directory = ""
[idle]
behavior_order = ["backlight-dim", "kbd-off", "lock", "screen-off", "suspend"]
[idle.behavior.backlight-dim]
timeout = 300
action = "command"
command = "brightnessctl -s set 10"
resume_command = "brightnessctl -r"
[idle.behavior.kbd-off]
timeout = 300
action = "command"
command = "brightnessctl -sd rgb:kbd_backlight set 0"
resume_command = "brightnessctl -rd rgb:kbd_backlight"
[idle.behavior.lock]
timeout = 900
action = "lock"
[idle.behavior.screen-off]
timeout = 1800
action = "screen_off"
[idle.behavior.suspend]
timeout = 2700
action = "lock_and_suspend"
-230
View File
@@ -1,230 +0,0 @@
// -*- mode: jsonc -*-
{
"custom/gpu": {
"format": "{text}",
"tooltip": false,
"exec": "~/.config/waybar/scripts/gpu-info.sh",
"exec-interval": 1,
"return-type": "json"
},
// "layer": "top", // Waybar at top layer
"position": "bottom", // Waybar position (top|bottom|left|right)
"height": 30, // Waybar height (to be removed for auto height)
// "width": 800, // Waybar width
"spacing": 4, // Gaps between modules (4px)
// Choose the order of the modules
"modules-left": [
"hyprland/workspaces"
//"hyprland/mode",
//"hyprland/scratchpad",
//"custom/media"
],
"modules-center": [
"hyprland/window"
],
"modules-right": [
"mpd",
"idle_inhibitor",
"pulseaudio",
//"network",
//"power-profiles-daemon",
"cpu",
"memory",
"temperature",
"backlight",
"keyboard-state",
//"hyprland/language",
"battery",
//"battery#bat2",
"custom/gpu",
"clock",
"tray",
"custom/power"
],
// Modules configuration
"hyprland/workspaces": {
"disable-scroll": true,
"all-outputs": true,
"warp-on-scroll": true,
"format": "{name}: {icon}",
"format-icons": {
// "1": "",
// "2": "",
// "3": "",
// "4": "",
// "5": "",
// "urgent": "",
"active": "",
"default": ""
}
},
"keyboard-state": {
"numlock": true,
"capslock": true,
"format": "{name} {icon}",
"format-icons": {
"locked": "",
"unlocked": ""
}
},
"hyprland/mode": {
"format": "<span style=\"italic\">{}</span>"
},
"hyprland/scratchpad": {
"format": "{icon} {count}",
"show-empty": false,
"format-icons": ["", ""],
"tooltip": true,
"tooltip-format": "{app}: {title}"
},
"mpd": {
"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ",
"format-disconnected": "Disconnected ",
"format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ",
"unknown-tag": "N/A",
"interval": 5,
"consume-icons": {
"on": " "
},
"random-icons": {
"off": "<span color=\"#f53c3c\"></span> ",
"on": " "
},
"repeat-icons": {
"on": " "
},
"single-icons": {
"on": "1 "
},
"state-icons": {
"paused": "",
"playing": ""
},
"tooltip-format": "MPD (connected)",
"tooltip-format-disconnected": "MPD (disconnected)"
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "",
"deactivated": ""
}
},
"tray": {
// "icon-size": 21,
"spacing": 10//,
// "icons": {
// "blueman": "bluetooth",
// "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
// }
},
"clock": {
"format": "{:%Y-%m-%d %H:%M}",
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
"on-click": "~/.config/waybar/scripts/copy-date.sh"
//"format-alt": "{:%Y-%m-%d}"
},
"cpu": {
"interval": 1,
"format": "cpu:{usage:02}%@{avg_frequency:4.2f}MHz",
"tooltip": false
},
"memory": {
"interval": 1,
"format": "mem:{:02}%"
},
"temperature": {
// "thermal-zone": 2,
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
"critical-threshold": 80,
// "format-critical": "{temperatureC}°C {icon}",
"format": "{temperatureC}°C {icon}",
"format-icons": ["", "", ""]
},
"backlight": {
// "device": "acpi_video1",
"format": "{percent}% {icon}",
"format-icons": ["", "", "", "", "", "", "", "", ""]
},
"battery": {
"states": {
// "good": 95,
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format-charging": "{capacity}% ",
"format-plugged": "{capacity}% ",
"format-alt": "{time} {icon}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
"bat": "BAT2"
},
"power-profiles-daemon": {
"format": "{icon}",
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
"tooltip": true,
"format-icons": {
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
"format-wifi": "{essid} ({signalStrength}%) ",
"format-ethernet": "{ipaddr}/{cidr} ",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"pulseaudio": {
// "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon} {format_source}",
"format-bluetooth-muted": " {icon} {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}% ",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
},
"on-click": "pavucontrol"
},
"custom/media": {
"format": "{icon} {text}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
},
"custom/power": {
"format" : "⏻ ",
"tooltip": false,
"menu": "on-click",
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
"menu-actions": {
"shutdown": "shutdown",
"reboot": "reboot",
"suspend": "systemctl suspend",
"hibernate": "systemctl hibernate"
}
}
}
-4
View File
@@ -1,4 +0,0 @@
#!/usr/bin/env bash
DATE=$(date +"%Y-%m-%d_%H%M")
echo -n "$DATE" | wl-copy
notify-send "Date copied" "$DATE"
-23
View File
@@ -1,23 +0,0 @@
#!/bin/bash
# GPU monitoring for waybar (AMD radeontop + sysfs temp)
GPU_DATA=$(timeout 1 radeontop -d - -l 1 2>/dev/null | tail -1)
if [ -z "$GPU_DATA" ]; then
echo "{\"text\": \"gpu:--\", \"tooltip\": \"Reading...\"}"
exit 0
fi
GPU=$(echo "$GPU_DATA" | grep -oP 'gpu \K[0-9.]+' | head -1)
GPU_INT=${GPU%.*}
VRAM=$(echo "$GPU_DATA" | grep -oP 'vram [\d.]+% \K[\d.]+' | head -1)
VRAM_INT=${VRAM%.*}
SCLK=$(echo "$GPU_DATA" | grep -oP 'sclk [\d.]+% \K[\d.]+' | head -1)
MCLK=$(echo "$GPU_DATA" | grep -oP 'mclk [\d.]+% \K[\d.]+' | head -1)
TEMP=$(( $(cat /sys/class/hwmon/hwmon2/temp1_input) / 1000 ))
POWER=$(( $(cat /sys/class/hwmon/hwmon2/power1_average) / 1000 ))
echo "{\"text\": \"gpu:${GPU_INT}% ${VRAM_INT}MB ${TEMP}C\", \"tooltip\": \"GPU: ${GPU}%\\nVRAM: ${VRAM}MB\\nTemp: ${TEMP}C\\nPower: ${POWER}W\\nSCLK: ${SCLK}GHz\\nMCLK: ${MCLK}GHz\"}"
-236
View File
@@ -1,236 +0,0 @@
/* -------------------------------------------------
Calm Glass (Hyprland / Waybar) — GTK CSS safe
-------------------------------------------------- */
* {
font-family: "JetBrainsMono Nerd Font", FontAwesome, sans-serif;
font-size: 13px;
}
/* ---------- GTK Color Definitions ---------- */
@define-color fg rgba(235, 238, 242, 0.92);
@define-color fg-dim rgba(235, 238, 242, 0.72);
@define-color fg-muted rgba(235, 238, 242, 0.55);
@define-color glass rgba(18, 22, 30, 0.55);
@define-color glass_2 rgba(18, 22, 30, 0.32);
@define-color glass_3 rgba(18, 22, 30, 0.22);
@define-color stroke rgba(255, 255, 255, 0.12);
@define-color stroke_2 rgba(255, 255, 255, 0.07);
/* ---------- Waybar Container ---------- */
window#waybar {
background-color: @glass;
color: @fg;
border-bottom: 1px solid @stroke;
box-shadow: 0 10px 30px rgba(0,0,0,0.30);
transition-property: background-color, opacity;
transition-duration: .5s;
}
window#waybar.hidden {
opacity: 0.35;
}
/* ---------- Buttons / Workspaces ---------- */
button {
box-shadow: inset 0 -2px transparent;
border: none;
border-radius: 0;
}
button:hover {
background: inherit;
box-shadow: inset 0 -2px rgba(255,255,255,0.18);
}
#workspaces button {
padding: 0 8px;
margin: 4px 3px;
background-color: rgba(255,255,255,0.04);
color: @fg-dim;
border: 1px solid rgba(255,255,255,0.06);
border-radius: 10px;
}
#workspaces button:hover {
background: rgba(255,255,255,0.07);
color: @fg;
}
#workspaces button.focused,
#workspaces button.active {
background-color: rgba(255,255,255,0.10);
color: @fg;
border: 1px solid rgba(255,255,255,0.12);
box-shadow: inset 0 -2px rgba(255,255,255,0.18);
}
#workspaces button.urgent {
background-color: rgba(190,110,120,0.35);
border-color: rgba(190,110,120,0.50);
color: @fg;
}
#window,
#workspaces {
margin: 0 4px;
}
.modules-left > widget:first-child > #workspaces {
margin-left: 0;
}
.modules-right > widget:last-child > #workspaces {
margin-right: 0;
}
/* ---------- Common “Chip” module style ---------- */
#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#mpd,
#language,
#keyboard-state,
#privacy,
#privacy-item {
padding: 0 10px;
color: @fg;
background-color: @glass_2;
border: 1px solid @stroke_2;
border-radius: 10px;
margin: 4px 4px;
}
#pulseaudio:hover,
#wireplumber:hover,
#network:hover,
#clock:hover {
background-color: @glass_3;
}
#clock {
border-color: rgba(140, 170, 190, 0.25);
}
/* Battery */
#battery.charging,
#battery.plugged {
background-color: rgba(120,170,140,0.22);
border-color: rgba(120,170,140,0.34);
}
@keyframes blink {
to {
background-color: rgba(190,110,120,0.18);
border-color: rgba(190,110,120,0.50);
}
}
#battery.critical:not(.charging) {
background-color: rgba(190,110,120,0.35);
border-color: rgba(190,110,120,0.55);
color: @fg;
animation-name: blink;
animation-duration: 0.6s;
animation-timing-function: steps(10);
animation-iteration-count: infinite;
animation-direction: alternate;
}
/* Network */
#network.disconnected {
background-color: rgba(190,110,120,0.30);
border-color: rgba(190,110,120,0.45);
}
/* Audio */
#pulseaudio:hover {
background-color: rgba(190,160,110,0.20);
border-color: rgba(190,160,110,0.28);
}
#pulseaudio.muted {
background-color: rgba(140,170,190,0.18);
border-color: rgba(140,170,190,0.26);
color: @fg-dim;
}
#wireplumber.muted {
background-color: rgba(190,110,120,0.28);
border-color: rgba(190,110,120,0.40);
}
/* Temperature */
#temperature.critical {
background-color: rgba(190,110,120,0.30);
border-color: rgba(190,110,120,0.45);
}
/* Tray */
#tray > .passive {
-gtk-icon-effect: dim;
}
#tray > .needs-attention {
-gtk-icon-effect: highlight;
background-color: rgba(190,110,120,0.30);
border-radius: 10px;
}
/* Idle inhibitor */
#idle_inhibitor.activated {
background-color: rgba(255,255,255,0.10);
border-color: rgba(255,255,255,0.14);
color: @fg;
}
/* Scratchpad */
#scratchpad {
background: rgba(255,255,255,0.05);
}
#scratchpad.empty {
background-color: transparent;
border-color: transparent;
}
/* Privacy */
#privacy {
padding: 0;
background-color: transparent;
border-color: transparent;
}
#privacy-item {
padding: 0 6px;
color: @fg;
}
#privacy-item.screenshare {
background-color: rgba(190,160,110,0.30);
border-color: rgba(190,160,110,0.40);
}
#privacy-item.audio-in {
background-color: rgba(120,170,140,0.25);
border-color: rgba(120,170,140,0.36);
}
#privacy-item.audio-out {
background-color: rgba(140,170,190,0.25);
border-color: rgba(140,170,190,0.36);
}
-6
View File
@@ -1,6 +0,0 @@
[default]
path = "~/.config/wpaperd/wallpapers/linked"
mode = "center"
#recursive = true
#sorting = "random"
#duration = "15m"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 975 KiB

-2
View File
@@ -1,2 +0,0 @@
scripts
.stow-ignore
-32
View File
@@ -1,32 +0,0 @@
# ---------------------------------------------------------------------------
# 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
hyprshutdown
wofi
-119
View File
@@ -1,119 +0,0 @@
#!/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
@@ -1,5 +1,5 @@
# ---------------------------------------------------------------------------
# System package list for basic/setup.sh
# System package list for setup/basic/setup.sh
#
# Every other dotfile branch depends on these foundational packages
# (base system, display manager, audio stack, AUR helper).
+68
View File
@@ -0,0 +1,68 @@
#!/bin/bash
set -euo pipefail
SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SETUP_DIR/packages.txt"
# shellcheck source=../lib/common.sh
source "$SETUP_DIR/../lib/common.sh"
# ---------------------------------------------------------------------------
# Docker: Dienst aktivieren/starten, Benutzer in die docker-Gruppe aufnehmen
# und den Dienst verifizieren. (docker selbst wird ueber setup/basic/packages.txt
# als Pacman-Paket installiert.)
# ---------------------------------------------------------------------------
setup_docker() {
if ! command -v docker >/dev/null 2>&1; then
echo "Warnung: docker nicht installiert; ueberspringe Docker-Setup."
return
fi
echo "==> Aktiviere und starte Docker-Dienst ..."
sudo systemctl enable --now docker
# Bei Aufruf via `sudo <script>` ist SUDO_USER der eigentliche Benutzer.
local target_user="${SUDO_USER:-$USER}"
echo "==> Stelle sicher, dass $target_user in der docker-Gruppe ist ..."
if [[ "$target_user" == "root" ]] || id -nG "$target_user" 2>/dev/null | grep -qw docker; then
echo "Benutzer $target_user ist bereits in der docker-Gruppe."
else
sudo usermod -aG docker "$target_user"
echo "Benutzer $target_user zur docker-Gruppe hinzugefuegt; wirksam nach dem naechsten Login."
fi
echo "==> Pruefe Docker-Dienst ..."
if systemctl is-active --quiet docker; then
echo "Docker-Dienst laeuft (Socket: /var/run/docker.sock)."
else
echo "Warnung: Docker-Dienst laeuft nicht; pruefe mit: systemctl status docker"
fi
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
local -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
echo "==> Aktiviere multilib ..."
enable_multilib
echo "==> System aktualisieren ..."
sudo pacman -Syu
echo "==> Sicherstelle yay ..."
ensure_yay
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages "$PACKAGES_FILE" pacman_pkgs aur_pkgs npm_pkgs
install_all_pkgs pacman_pkgs aur_pkgs npm_pkgs
echo "==> Richte Docker ein ..."
setup_docker
echo "Fertig. Die Basis-Systemumgebung ist eingerichtet."
}
main
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# Refresh vendored upstream port files (setup/fetch-ports.sh).
#
# This script lives outside the stow packages (setup/) and is NOT run
# by the test harness: it contacts the network. Run it manually when you
# want to pull newer upstream Catppuccin ports into the central theme:
#
# bash setup/fetch-ports.sh
#
# The central palette (theme.lua / theme.css roles / hypr.conf) remains the
# source of truth; after fetching, re-apply the provenance headers and the
# role-alias block at the end of theme.css if upstream overwrote them.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEST="$SCRIPT_DIR/../basic/.config/themes/themes/catppuccin-mocha"
# Pinned upstream revisions (bump deliberately, then run this script).
KITTY_PIN="main"
curl -fsSL "https://raw.githubusercontent.com/catppuccin/kitty/${KITTY_PIN}/themes/mocha.conf" \
-o "$DEST/kitty.conf"
echo "ports refreshed into $DEST"
echo "reminder: re-apply file headers + theme.css role aliases, then run scripts/sync-theme.sh"
+32
View File
@@ -0,0 +1,32 @@
# ---------------------------------------------------------------------------
# Hyprland compositor package list for setup/hypr/setup.sh
#
# Wayland compositor, screenshot tool and supporting utilities. The desktop
# shell (bar, launcher, notifications, lock screen, wallpaper, idle, session
# menu) on this branch is Caelestia (see hypr/.config/hypr/hyprland.lua:
# `caelestia shell -d`). Noctalia lives on main.
#
# - Lines starting with '#' and blank lines are ignored.
# - Use "@pacman", "@aur" or "@npm" markers to switch section.
# - The default section is @pacman.
# ---------------------------------------------------------------------------
@pacman
hyprland
hypridle
xdg-desktop-portal-hyprland
hyprpolkitagent
pantheon-shortcut-overlay
wev
wl-clipboard
hyprshot
brightnessctl
wtype
@aur
hyprmod
caelestia-shell
caelestia-cli
quickshell-git
hyprsaver
python-terminaltexteffects
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
set -euo pipefail
SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SETUP_DIR/packages.txt"
# shellcheck source=../lib/common.sh
source "$SETUP_DIR/../lib/common.sh"
# ---------------------------------------------------------------------------
# Post-install: run Hyprland environment & desktop integration scripts.
# ---------------------------------------------------------------------------
run_hypr_scripts() {
local scripts_dir
scripts_dir="$(repo_root)/hypr/.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() {
local -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages "$PACKAGES_FILE" pacman_pkgs aur_pkgs npm_pkgs
install_all_pkgs pacman_pkgs aur_pkgs npm_pkgs
run_hypr_scripts
echo "Fertig. Hyprland und das Compositor-Okosystem sind eingerichtet."
}
main
+24
View File
@@ -0,0 +1,24 @@
# ---------------------------------------------------------------------------
# Kreation package list for setup/kreation/setup.sh
#
# DAW, video and audio-plugin runtime.
#
# - Lines starting with '#' and blank lines are ignored.
# - Use "@pacman", "@aur" or "@npm" markers to switch section.
# - The default section is @pacman.
# ---------------------------------------------------------------------------
@pacman
reaper
guitarix
kdenlive
yabridge
yabridgectl
obs-studio
surge-xt
lsp-plugins
calf
dragonfly-reverb
@aur
numaplayer
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
set -euo pipefail
SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SETUP_DIR/packages.txt"
# shellcheck source=../lib/common.sh
source "$SETUP_DIR/../lib/common.sh"
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
local -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages "$PACKAGES_FILE" pacman_pkgs aur_pkgs npm_pkgs
install_all_pkgs pacman_pkgs aur_pkgs npm_pkgs
echo "Fertig. Kreation-Pakete (DAW, Video, Plugins) sind eingerichtet."
}
main
+124
View File
@@ -0,0 +1,124 @@
#!/bin/bash
# setup/lib/common.sh
#
# Shared helpers for the setup/install scripts under setup/.
# Source this file; do not execute it directly:
#
# SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# # shellcheck source=../lib/common.sh
# source "$SETUP_DIR/../lib/common.sh"
#
# Conventions:
# - The caller owns `set -euo pipefail` and PACKAGES_FILE.
# - Package lists use @pacman (default) / @aur / @npm section markers;
# '#' starts a comment, blank lines are ignored.
# - Set NPM_USE_SUDO=1 before calling install_npm_pkgs when the global
# npm root is root-owned (Arch installs npm to /usr/lib/node_modules).
# Print the repository root (setup/lib/ -> repo root).
repo_root() {
cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd
}
log() {
echo "==> $*"
}
# ---------------------------------------------------------------------------
# Read a packages.txt file, split into pacman / aur / npm sections.
# Usage: read_packages <file> <pacman_array> <aur_array> <npm_array>
# ---------------------------------------------------------------------------
read_packages() {
local file="$1" pacman_ref="$2" aur_ref="$3" npm_ref="$4"
local section="pacman"
local line current
local -n _pacman="$pacman_ref" _aur="$aur_ref" _npm="$npm_ref"
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+=("$current") ;;
aur) _aur+=("$current") ;;
npm) _npm+=("$current") ;;
esac
;;
esac
done < "$file"
}
# ---------------------------------------------------------------------------
# Install sections (arrays passed by nameref).
# ---------------------------------------------------------------------------
install_pacman_pkgs() {
local -n _pkgs="$1"
if ((${#_pkgs[@]})); then
log "Installiere Pacman-Pakete: ${_pkgs[*]}"
yay -S --needed "${_pkgs[@]}"
fi
}
install_aur_pkgs() {
local -n _pkgs="$1"
if ((${#_pkgs[@]})); then
log "Installiere AUR-Pakete: ${_pkgs[*]}"
yay -S --needed "${_pkgs[@]}"
fi
}
install_npm_pkgs() {
local -n _pkgs="$1"
if ((${#_pkgs[@]})); then
log "Installiere globale npm-Pakete: ${_pkgs[*]}"
if [[ "${NPM_USE_SUDO:-0}" == "1" ]]; then
sudo npm install -g "${_pkgs[@]}"
else
npm install -g "${_pkgs[@]}"
fi
fi
}
# Install all three sections at once.
install_all_pkgs() {
install_pacman_pkgs "$1"
install_aur_pkgs "$2"
install_npm_pkgs "$3"
}
# ---------------------------------------------------------------------------
# Enable multilib in /etc/pacman.conf (with a safety backup).
# ---------------------------------------------------------------------------
enable_multilib() {
sudo sed -i.bak '/^#\[multilib\]/,+1 s/^#//' /etc/pacman.conf
}
# ---------------------------------------------------------------------------
# Ensure yay (AUR helper) is installed.
# ---------------------------------------------------------------------------
ensure_yay() {
if pacman -Q yay &>/dev/null; then
echo "yay bereits installiert; fahre fort."
return
fi
if pacman -Si yay &>/dev/null; then
echo "Installiere yay mit pacman ..."
sudo pacman -S --needed yay
return
fi
echo "installiere yay via git ..."
sudo pacman -S --needed base-devel git
local tmp
tmp="$(mktemp -d)"
git clone https://aur.archlinux.org/yay.git "$tmp/yay"
(
cd "$tmp/yay"
makepkg -si
)
rm -rf "$tmp"
}
@@ -1,5 +1,5 @@
# ---------------------------------------------------------------------------
# Terminal package list for term/setup.sh
# Terminal package list for setup/term/setup.sh
#
# Maintenance:
# - Add / remove packages on separate lines.
+107
View File
@@ -0,0 +1,107 @@
#!/bin/bash
set -euo pipefail
SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SETUP_DIR/packages.txt"
# shellcheck source=../lib/common.sh
source "$SETUP_DIR/../lib/common.sh"
# Arch installiert npm nach /usr/lib/node_modules (root-owned),
# daher braucht der globale Install sudo.
NPM_USE_SUDO=1
# ---------------------------------------------------------------------------
# Post-install configuration.
# ---------------------------------------------------------------------------
set_fish_default_shell() {
if command -v fish >/dev/null 2>&1; then
if [[ "$SHELL" != "/usr/bin/fish" ]]; then
echo "Setze fish als Standard-Shell ..."
chsh -s /usr/bin/fish
else
echo "fish ist bereits die Standard-Shell."
fi
else
echo "Warnung: fish wurde nicht installiert; ueberspringe chsh."
fi
}
install_tmuxifier() {
if [[ -d "$HOME/.tmuxifier" ]]; then
echo "tmuxifier bereits installiert; fahre fort."
else
echo "Klone tmuxifier ..."
git clone https://github.com/jimeh/tmuxifier.git "$HOME/.tmuxifier"
fi
}
install_tmux_tpm() {
if [[ -x "$HOME/.config/tmux/plugins/tpm/tpm" ]]; then
echo "tmux TPM bereits installiert; fahre fort."
else
echo "Klone tmux TPM ..."
mkdir -p "$HOME/.config/tmux/plugins"
git clone https://github.com/tmux-plugins/tpm "$HOME/.config/tmux/plugins/tpm"
fi
}
install_tmux_plugins() {
local tpm_install="$HOME/.config/tmux/plugins/tpm/bin/install_plugins"
if ! command -v tmux >/dev/null 2>&1; then
echo "Warnung: tmux nicht installiert; ueberspringe Plugin-Installation (C-Space I beim ersten Start)."
return 0
fi
if ! command -v git >/dev/null 2>&1; then
echo "Warnung: git nicht installiert; ueberspringe tmux Plugin-Installation."
return 0
fi
if [[ ! -f "$HOME/.config/tmux/tmux.conf" ]]; then
echo "tmux.conf noch nicht verlinkt (stow laeuft nach setup.sh); Plugins werden beim ersten tmux-Start bzw. Re-Run installiert (C-Space I)."
return 0
fi
if [[ ! -x "$tpm_install" ]]; then
echo "Warnung: TPM install_plugins nicht gefunden; ueberspringe tmux Plugin-Installation."
return 0
fi
echo "Installiere tmux-Plugins via TPM ..."
"$tpm_install"
}
add_yazi_git_plugin() {
if command -v yazi >/dev/null 2>&1 && command -v ya >/dev/null 2>&1; then
if ya pkg list 2>/dev/null | grep -q 'yazi-rs/plugins:git'; then
echo "yazi git-Plugin bereits installiert; fahre fort."
else
echo "Fuege yazi git-Plugin hinzu ..."
ya pkg add yazi-rs/plugins:git
fi
fi
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
local -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
# Hinweis: multilib, yay und das System-Update werden von
# setup/basic/setup.sh uebernommen (laeuft vor term im Makefile).
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages "$PACKAGES_FILE" pacman_pkgs aur_pkgs npm_pkgs
install_all_pkgs pacman_pkgs aur_pkgs npm_pkgs
set_fish_default_shell
install_tmuxifier
install_tmux_tpm
install_tmux_plugins
add_yazi_git_plugin
echo "==> Aktualisiere locate-Datenbank ..."
sudo updatedb
echo "Fertig. Starte ein neues Terminal, damit fish und die Umgebung greifen."
}
main
@@ -1,5 +1,5 @@
# ---------------------------------------------------------------------------
# Standalone desktop utility package list for utils/setup.sh
# Standalone desktop utility package list for setup/utils/setup.sh
#
# Programs that are not core to every branch, but are expected on a full
# desktop: office / web / mail / native-app replacements (Wine), the
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
set -euo pipefail
SETUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGES_FILE="$SETUP_DIR/packages.txt"
# shellcheck source=../lib/common.sh
source "$SETUP_DIR/../lib/common.sh"
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
local -a pacman_pkgs=() aur_pkgs=() npm_pkgs=()
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages "$PACKAGES_FILE" pacman_pkgs aur_pkgs npm_pkgs
install_all_pkgs pacman_pkgs aur_pkgs npm_pkgs
echo "Fertig. Standalone Utilities sind eingerichtet."
}
main
+9
View File
@@ -37,3 +37,12 @@ fi
export DATAFLEX_BACKEND_REPO="/c/_Master/202602 DataFleX/repos/flexibility_platform_backend/"
export PATH="$HOME/.local/bin:$PATH"
# Central theme (basic/.config/themes): single source of truth for colors.
if [ -f "$HOME/.config/themes/current/theme.env.sh" ]; then
. "$HOME/.config/themes/current/theme.env.sh"
fi
if command -v fastfetch >/dev/null 2>&1; then
fastfetch --config ~/.config/fastfetch/config.jsonc
fi
-50
View File
@@ -42,36 +42,11 @@
"key": "├─󰍹",
"keyColor": "green"
},
{
"type": "brightness",
"key": "├─󰃞",
"keyColor": "green"
},
{
"type": "battery",
"key": "├─",
"keyColor": "green"
},
{
"type": "poweradapter",
"key": "├─",
"keyColor": "green"
},
{
"type": "gamepad",
"key": "├─",
"keyColor": "green"
},
{
"type": "bluetooth",
"key": "├─",
"keyColor": "green"
},
{
"type": "sound",
"key": "╰─",
"keyColor": "green"
},
"break",
{
@@ -104,21 +79,6 @@
"key": "├─",
"keyColor": "yellow"
},
{
"type": "theme",
"key": "├─󰉼",
"keyColor": "yellow"
},
{
"type": "icons",
"key": "├─󰀻",
"keyColor": "yellow"
},
{
"type": "wallpaper",
"key": "╰─󰸉",
"keyColor": "yellow"
},
"break",
{
@@ -137,21 +97,11 @@
"key": "├─",
"keyColor": "blue"
},
{
"type": "packages",
"key": "├─󰏖",
"keyColor": "blue"
},
{
"type": "uptime",
"key": "├─󰅐",
"keyColor": "blue"
},
{
"type": "media",
"key": "├─󰝚",
"keyColor": "blue"
},
{
"type": "localip",
"key": "├─󰩟",
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
for f in ~/.config/fastfetch/*.jsonc; do
echo "=== $f ==="
fastfetch --config "$f"
read -p "Enter for next..."
done
+9 -2
View File
@@ -1,15 +1,22 @@
# Central theme (basic/.config/themes): single source of truth for colors.
if test -f ~/.config/themes/current/theme.fish
source ~/.config/themes/current/theme.fish
end
# Enable OpenCode web search via Exa AI
set -gx OPENCODE_ENABLE_EXA 1
if status is-interactive
starship init fish | source
set -g fish_prompt_pwd_dir_length 0
# fastfetch
if type -q fastfetch
fastfetch --config ~/.config/fastfetch/config.jsonc
end
end
# Added by LM Studio CLI (lms)
set -gx PATH $PATH /home/mathias/.lmstudio/bin
set -gx PATH $PATH $HOME/.lmstudio/bin
# End of LM Studio CLI section
export EDITOR=nvim
@@ -16,6 +16,7 @@ return {
{ "<leader>bp", "<Cmd>BufferLinePick<CR>", desc = "Pick buffer" },
{ "<leader>bc", "<Cmd>BufferLinePickClose<CR>", desc = "Pick buffer to close" },
{ "<leader>bx", "<Cmd>BufferLineCloseOthers<CR>", desc = "Close other buffers" },
{ "<leader>bq", "<Cmd>BufferLineCyclePrev<CR><Cmd>bdelete #<CR>", desc = "Close buffer and go left" },
},
opts = {
options = {
+5 -2
View File
@@ -4,7 +4,10 @@ return {
lazy = false,
priority = 1000,
config = function()
require("catppuccin").setup({ flavor = "mocha" })
vim.cmd.colorscheme("catppuccin")
-- Central theme (basic/.config/themes): flavor/colorscheme come from
-- $CATPPUCCIN_FLAVOR / $THEME_NVIM_COLORSCHEME so a future theme only
-- changes the central files (see themes/registry.conf).
require("catppuccin").setup({ flavor = os.getenv("CATPPUCCIN_FLAVOR") or "mocha" })
vim.cmd.colorscheme(os.getenv("THEME_NVIM_COLORSCHEME") or "catppuccin")
end,
}
+5 -83
View File
@@ -169,6 +169,11 @@ show_notifications = true
min_time_to_notify = 45000
min_time = 0
# Central theme note: starship has no `include` mechanism, so this palette is
# a declared mirror of basic/.config/themes/themes/catppuccin-mocha (see
# theme.env.sh / theme.css for the source of truth). Only the active
# palette is kept here; switch flavors by replacing this block from the
# central theme (scripts/switch-theme.sh reminds you). Do not hand-edit hex.
[palettes.catppuccin_mocha]
rosewater = "#f5e0dc"
flamingo = "#f2cdcd"
@@ -197,86 +202,3 @@ base = "#1e1e2e"
mantle = "#181825"
crust = "#11111b"
[palettes.catppuccin_frappe]
rosewater = "#f2d5cf"
flamingo = "#eebebe"
pink = "#f4b8e4"
mauve = "#ca9ee6"
red = "#e78284"
maroon = "#ea999c"
peach = "#ef9f76"
yellow = "#e5c890"
green = "#a6d189"
teal = "#81c8be"
sky = "#99d1db"
sapphire = "#85c1dc"
blue = "#8caaee"
lavender = "#babbf1"
text = "#c6d0f5"
subtext1 = "#b5bfe2"
subtext0 = "#a5adce"
overlay2 = "#949cbb"
overlay1 = "#838ba7"
overlay0 = "#737994"
surface2 = "#626880"
surface1 = "#51576d"
surface0 = "#414559"
base = "#303446"
mantle = "#292c3c"
crust = "#232634"
[palettes.catppuccin_latte]
rosewater = "#dc8a78"
flamingo = "#dd7878"
pink = "#ea76cb"
mauve = "#8839ef"
red = "#d20f39"
maroon = "#e64553"
peach = "#fe640b"
yellow = "#df8e1d"
green = "#40a02b"
teal = "#179299"
sky = "#04a5e5"
sapphire = "#209fb5"
blue = "#1e66f5"
lavender = "#7287fd"
text = "#4c4f69"
subtext1 = "#5c5f77"
subtext0 = "#6c6f85"
overlay2 = "#7c7f93"
overlay1 = "#8c8fa1"
overlay0 = "#9ca0b0"
surface2 = "#acb0be"
surface1 = "#bcc0cc"
surface0 = "#ccd0da"
base = "#eff1f5"
mantle = "#e6e9ef"
crust = "#dce0e8"
[palettes.catppuccin_macchiato]
rosewater = "#f4dbd6"
flamingo = "#f0c6c6"
pink = "#f5bde6"
mauve = "#c6a0f6"
red = "#ed8796"
maroon = "#ee99a0"
peach = "#f5a97f"
yellow = "#eed49f"
green = "#a6da95"
teal = "#8bd5ca"
sky = "#91d7e3"
sapphire = "#7dc4e4"
blue = "#8aadf4"
lavender = "#b7bdf8"
text = "#cad3f5"
subtext1 = "#b8c0e0"
subtext0 = "#a5adcb"
overlay2 = "#939ab7"
overlay1 = "#8087a2"
overlay0 = "#6e738d"
surface2 = "#5b6078"
surface1 = "#494d64"
surface0 = "#363a4f"
base = "#24273a"
mantle = "#1e2030"
crust = "#181926"
+17 -9
View File
@@ -42,6 +42,11 @@ bind x kill-pane
# Auto-bootstrap TPM if not installed
if "test ! -d ~/.config/tmux/plugins/tpm" \
"run 'git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm && ~/.config/tmux/plugins/tpm/bin/install_plugins'"
# Auto-install missing plugins when TPM exists but a plugin dir is absent
# (e.g. a new @plugin was added after the first bootstrap).
# NOTE: TPM clones `user/repo` to `plugins/repo`, so catppuccin/tmux -> plugins/tmux.
if "test ! -d ~/.config/tmux/plugins/tmux" \
"run '~/.config/tmux/plugins/tpm/bin/install_plugins'"
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
@@ -52,12 +57,14 @@ set -g @plugin 'jimeh/tmuxifier'
# Persist sessions across reboots and restore them when tmux starts.
set -g @continuum-save-interval '5'
set -g @continuum-restore 'on'
# set -g @continuum-restore 'on'
# set -g @resurrect-capture-pane-contents 'on'
# Catppuccin theme
# Central theme (basic/.config/themes): flavor comes from $CATPPUCCIN_FLAVOR
# (theme.env.sh / theme.fish), defaulting to mocha. The plugin itself is
# owned by TPM (see registry.conf for the theme -> plugin mapping).
set -g @plugin 'catppuccin/tmux'
set -g @catppuccin_flavor "mocha"
run-shell 'tmux set -g @catppuccin_flavor "${CATPPUCCIN_FLAVOR:-mocha}"'
set -g @catppuccin_window_status_style "rounded"
set -g @catppuccin_window_text "#W"
@@ -67,16 +74,17 @@ set -g @catppuccin_window_current_text "#W"
set-environment -g TMUXIFIER_LAYOUT_PATH "$HOME/.tmuxifier/layouts"
# ── Initialize TPM (must be last line before status bar) ──────────────────────
run '~/.config/tmux/plugins/tpm/tpm'
# ── Status bar ────────────────────────────────────────────────────────────────
# (must come after TPM run so catppuccin variables are available)
# NOTE: #{E:@catppuccin_...} expands at display time, so this intentionally
# comes before `run tpm` (TPM requires `run tpm` to be the last line).
set -g status-position top
set -g status-left-length 100
set -g status-right-length 100
set -g status-left "#{E:@catppuccin_status_session}"
set -g status-right "#{E:@catppuccin_status_date_time}"
# ── Initialize TPM (must be last) ───────────────────────────────────────────
run '~/.config/tmux/plugins/tpm/tpm'
+5 -3
View File
@@ -1,3 +1,8 @@
# Central theme note: yazi has no `include` mechanism, so this file is a
# declared mirror of basic/.config/themes/themes/catppuccin-mocha (Catppuccin
# Mocha). Do not hand-tweak hex values here; port them from the central theme.
# (Also note: syntect_theme below points at ~/.config/yazi/, which is not
# stowed on a fresh setup until `stow term` runs.)
[app]
overall = { bg = "#1e1e2e" }
@@ -152,7 +157,6 @@ files = [
{ name = "dockerfile", text = "󰡨", fg = "#89b4fa" },
{ name = ".git-blame-ignore-revs", text = "", fg = "#fab387" },
{ name = ".nvmrc", text = "", fg = "#a6e3a1" },
{ name = "hyprpaper.conf", text = "", fg = "#74c7ec" },
{ name = ".prettierignore", text = "", fg = "#89b4fa" },
{ name = "rakefile", text = "", fg = "#313244" },
{ name = "code_of_conduct", text = "", fg = "#f38ba8" },
@@ -279,9 +283,7 @@ files = [
{ name = "commitlint.config.js", text = "󰜘", fg = "#94e2d5" },
{ name = ".gitmodules", text = "", fg = "#fab387" },
{ name = "gradle-wrapper.properties", text = "", fg = "#585b70" },
{ name = "hypridle.conf", text = "", fg = "#74c7ec" },
{ name = "vercel.json", text = "▲", fg = "#f5e0dc" },
{ name = "hyprlock.conf", text = "", fg = "#74c7ec" },
{ name = "go.sum", text = "", fg = "#74c7ec" },
{ name = "kdenlive-layoutsrc", text = "", fg = "#89b4fa" },
{ name = "gruntfile.babel.js", text = "", fg = "#fab387" },
-2
View File
@@ -1,2 +0,0 @@
scripts
.stow-ignore
+1
View File
@@ -0,0 +1 @@
.config/tmux/plugins
-121
View File
@@ -1,121 +0,0 @@
#!/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[*]}"
# Arch installiert npm nach /usr/lib/node_modules (root-owned),
# daher braucht der globale Install sudo.
sudo npm install -g "${npm_pkgs[@]}"
fi
}
# ---------------------------------------------------------------------------
# Post-install configuration.
# ---------------------------------------------------------------------------
set_fish_default_shell() {
if command -v fish >/dev/null 2>&1; then
if [[ "$SHELL" != "/usr/bin/fish" ]]; then
echo "Setze fish als Standard-Shell ..."
chsh -s /usr/bin/fish
else
echo "fish ist bereits die Standard-Shell."
fi
else
echo "Warnung: fish wurde nicht installiert; ueberspringe chsh."
fi
}
install_tmuxifier() {
if [[ -d "$HOME/.tmuxifier" ]]; then
echo "tmuxifier bereits installiert; fahre fort."
else
echo "Klone tmuxifier ..."
git clone https://github.com/jimeh/tmuxifier.git "$HOME/.tmuxifier"
fi
}
add_yazi_git_plugin() {
if command -v yazi >/dev/null 2>&1 && command -v ya >/dev/null 2>&1; then
if ya pkg list 2>/dev/null | grep -q 'yazi-rs/plugins:git'; then
echo "yazi git-Plugin bereits installiert; fahre fort."
else
echo "Fuege yazi git-Plugin hinzu ..."
ya pkg add yazi-rs/plugins:git
fi
fi
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
# Hinweis: multilib, yay und das System-Update werden von
# basic/setup.sh uebernommen (laeuft vor term im Makefile).
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages
install_pacman
install_aur
install_npm
set_fish_default_shell
install_tmuxifier
add_yazi_git_plugin
echo "==> Aktualisiere locate-Datenbank ..."
sudo updatedb
echo "Fertig. Starte ein neues Terminal, damit fish und die Umgebung greifen."
}
main
+30 -39
View File
@@ -10,7 +10,7 @@
# - `stow --simulate` to prove every stow target resolves
# 2. REAL SMOKE (guarded by RUN_SMOKE=1)
# - resolves every @pacman entry against the repo DB
# - exercises term/setup.sh (pacman + npm) and re-runs it to prove
# - exercises setup/term/setup.sh (pacman + npm) and re-runs it to prove
# idempotency
# - verifies stow actually creates symlinks into $HOME
# AUR + kreation/buntes-monster only run with RUN_FULL=1.
@@ -78,14 +78,13 @@ done
# 1b. stow --simulate for every package the Makefile stows.
while IFS= read -r pkg; do
[[ -z "$pkg" ]] && continue
if stow --simulate --ignore='.stow-ignore' --ignore='scripts' \
--dir="$REPO" --target="$REPO" "$pkg" 2>"$ERR_LOG"; then
if stow --simulate --dir="$REPO" --target="$REPO" "$pkg" 2>"$ERR_LOG"; then
say_ok "stow --simulate $pkg resolves"
else
say_fail "stow --simulate $pkg (non-existent package or conflict)"
sed 's/^/ /' "$ERR_LOG" 2>/dev/null
fi
done < <(grep -P '^\t' Makefile | grep -oE 'stow [A-Za-z0-9_-]+' | awk '{print $2}' | sort -u)
done < <(grep -P '^\t' Makefile | grep -E '\bstow\b' | awk '{print $NF}' | sort -u)
# 1c. run the repo's own lint + probe scripts (they're mounted here).
if [[ -x test/lint.sh ]] || [[ -f test/lint.sh ]]; then
@@ -140,7 +139,7 @@ NOOP
echo "[stub] chsh $*"
exit 0
NOOP
# The AUR section is stripped for the smoke, so term/setup.sh only ever
# The AUR section is stripped for the smoke, so setup/term/setup.sh only ever
# passes repo packages (+ npm) here; route yay through pacman directly.
# --noconfirm is needed because the container isn't interactive.
cat > "$HOME/bin/yay" <<'NOOP'
@@ -153,16 +152,11 @@ NOOP
export PATH="$HOME/bin:$PATH"
# 2c. setup.sh package parsing sanity (mirrors read_packages) for each
# 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
SETUP_PATH="$d/setup.sh"
PKG_PATH="$d/packages.txt"
fi
# setup/$d target. All setup scripts + package lists live in setup/
# (outside the stow packages) and share setup/lib/common.sh.
for d in basic term utils hypr kreation; do
SETUP_PATH="setup/$d/setup.sh"
PKG_PATH="setup/$d/packages.txt"
if ( cd "$REPO" && bash -n "$SETUP_PATH" ); then
say_ok "$SETUP_PATH syntax OK"
else
@@ -188,12 +182,8 @@ 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 hypr; do
if [[ "$d" == "term" || "$d" == "hypr" ]]; then
PKG_PATH="$d/scripts/packages.txt"
else
PKG_PATH="$d/packages.txt"
fi
for d in basic term utils hypr kreation; do
PKG_PATH="setup/$d/packages.txt"
while IFS= read -r pkg; do
[[ -z "$pkg" ]] && continue
if pacman -S --print-format '%n' "$pkg" >/dev/null 2>&1; then
@@ -213,44 +203,46 @@ NOOP
done
# 2d. If network allowed and not skipped, actually install the pacman
# and npm sections of term/setup.sh (mirrors `make term` without AUR;
# the @aur section stays RUN_FULL-gated since it needs yay/AUR builds).
# and npm sections of setup/term/setup.sh (mirrors `make term` without
# AUR; the @aur section stays RUN_FULL-gated since it needs yay/AUR builds).
if [[ "${SKIP_NET:-0}" != "1" ]]; then
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/scripts/packages.txt" "$HOME/packages.txt.full"
cp "$REPO/setup/term/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/scripts/packages.txt" > "$HOME/packages.txt.term-smoke"
' "$REPO/setup/term/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/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/scripts/setup.sh" "$HOME/term/setup.sh"
cp "$HOME/packages.txt.term-smoke" "$HOME/term/packages.txt"
' "$REPO/setup/term/packages.txt" > "$HOME/packages.txt.term-only"
# Stage a scratch copy of the term setup incl. setup/lib/common.sh
# (setup.sh sources it via a path relative to its own location).
mkdir -p "$HOME/smoke/term" "$HOME/smoke/lib"
cp "$REPO/setup/term/setup.sh" "$HOME/smoke/term/setup.sh"
cp "$REPO/setup/lib/common.sh" "$HOME/smoke/lib/common.sh"
cp "$HOME/packages.txt.term-smoke" "$HOME/smoke/term/packages.txt"
# chsh is stubbed via $HOME/bin so even `chsh` works without a pty.
setup_ok=0
if ( cd "$HOME/term" && bash setup.sh ) ; then
say_ok "term/setup.sh (pacman+npm) completed"
if ( cd "$HOME/smoke/term" && bash setup.sh ) ; then
say_ok "setup/term/setup.sh (pacman+npm) completed"
setup_ok=1
else
say_fail "term/setup.sh (pacman+npm) failed (exit $?)"
say_fail "setup/term/setup.sh (pacman+npm) failed (exit $?)"
fi
# 2d1. Idempotency probe: a second run must also succeed. Catches
# steps that break on re-runs over an already-populated state (e.g.
# `ya pkg add` failing with "already exists").
if [[ "$setup_ok" == "1" ]]; then
if ( cd "$HOME/term" && bash setup.sh ) ; then
say_ok "term/setup.sh re-run: idempotent"
if ( cd "$HOME/smoke/term" && bash setup.sh ) ; then
say_ok "setup/term/setup.sh re-run: idempotent"
else
say_fail "term/setup.sh re-run failed (exit $?) - not idempotent"
say_fail "setup/term/setup.sh re-run failed (exit $?) - not idempotent"
fi
else
echo " skipping idempotency probe (first run did not complete)"
@@ -278,14 +270,13 @@ NOOP
# 2e. stow --actual into $HOME to prove real symlinks are created.
header "stow real symlinks into \$HOME"
# term/setup.sh may have just re-created the yazi plugin (`ya pkg add`)
# setup/term/setup.sh may have just re-created the yazi plugin (`ya pkg add`)
# as real files. The repo vendors the same plugin under term/.config/yazi,
# so drop the duplicate first, letting stow take ownership of that config.
rm -rf "$HOME/.config/yazi"
for pkg in term hypr kreation local_ai; do
if [[ -d "$REPO/$pkg" ]]; then
if stow --ignore='.stow-ignore' --ignore='scripts' \
--dir="$REPO" --target="$HOME" "$pkg" 2>"$ERR_LOG"; then
if stow --dir="$REPO" --target="$HOME" "$pkg" 2>"$ERR_LOG"; then
say_ok "stow $pkg into \$HOME"
else
say_fail "stow $pkg into \$HOME"
+35 -21
View File
@@ -77,19 +77,14 @@ else
fi
# ---------------------------------------------------------------------------
# 4. packages.txt parsing sanity (mirrors each setup.sh read_packages).
# 4. packages.txt parsing sanity (mirrors setup/lib/common.sh read_packages).
# ---------------------------------------------------------------------------
echo "== Checking packages.txt markers =="
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
for pkgdir in term basic utils hypr kreation; do
# Setup scripts + package lists live in setup/ (outside the stow
# packages), sharing one parser in setup/lib/common.sh.
PKG_FILE="setup/$pkgdir/packages.txt"
SETUP_FILE="setup/$pkgdir/setup.sh"
if ! [[ -f "$PKG_FILE" ]]; then
say_fail "$PKG_FILE missing"
continue
@@ -99,12 +94,15 @@ for pkgdir in term basic utils hypr; do
else
say_fail "$PKG_FILE missing @pacman marker"
fi
# every @aur/@npm marker must be matched by a real consumer in setup.sh
# every @aur/@npm marker must be matched by a real consumer: either the
# thin setup.sh itself or the shared setup/lib/common.sh it sources.
for marker in '@aur' '@npm'; do
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"
if grep -q "$marker" "$SETUP_FILE" || grep -q "$marker" "setup/lib/common.sh"; then
say_pass "$PKG_FILE $marker handled by $SETUP_FILE (via common.sh)"
else
say_fail "$PKG_FILE uses $marker but neither $SETUP_FILE nor setup/lib/common.sh handles it"
fi
else
say_pass "$PKG_FILE has no $marker section"
fi
@@ -112,12 +110,12 @@ for pkgdir in term basic utils hypr; do
done
# ---------------------------------------------------------------------------
# 5. Makefile <-> install script name consistency.
# Catches typos such as `_install_skripte_install_basic_pcks.sh`
# 5. Makefile <-> setup script name consistency.
# Catches typos such as `setup/basic/setuo.sh`
# (missing '/') in Makefile targets.
# ---------------------------------------------------------------------------
echo "== Checking Makefile references install scripts that exist =="
# Pull out every `*_install_*_pcks.sh` token mentioned in the Makefile.
echo "== Checking Makefile references setup scripts that exist =="
# Pull out every `setup/...sh` token mentioned in the Makefile.
while IFS= read -r tok; do
[[ -z "$tok" ]] && continue
if [[ -e "$REPO_ROOT/$tok" ]]; then
@@ -125,7 +123,7 @@ while IFS= read -r tok; do
else
say_fail "Makefile references missing script: $tok"
fi
done < <(grep -P '^\t' Makefile | grep -oE '[_A-Za-z0-9/-]*install_[A-Za-z0-9_-]*\.sh' | sort -u)
done < <(grep -P '^\t' Makefile | grep -oE 'setup/[_A-Za-z0-9./-]+\.sh' | sort -u)
# ---------------------------------------------------------------------------
# 6. Makefile <-> stow package name consistency.
@@ -155,7 +153,23 @@ while IFS= read -r pkg; do
else
say_fail "Makefile stows non-existent package: $pkg"
fi
done < <(grep -P '^\t' Makefile | grep -oE 'stow [A-Za-z0-9_-]+' | awk '{print $2}' | sort -u)
done < <(grep -P '^\t' Makefile | grep -E '\bstow\b' | awk '{print $NF}' | sort -u)
# ---------------------------------------------------------------------------
# 7. Central theme drift guard: no hardcoded theme colors outside
# basic/.config/themes (plus declared mirrors). See
# basic/.config/themes/scripts/sync-theme.sh.
# ---------------------------------------------------------------------------
echo "== Checking central theme has no hardcoded copies =="
if [[ -f "basic/.config/themes/scripts/sync-theme.sh" ]]; then
if bash basic/.config/themes/scripts/sync-theme.sh; then
say_pass "central theme drift guard"
else
say_fail "central theme drift guard"
fi
else
say_fail "basic/.config/themes/scripts/sync-theme.sh missing"
fi
# ---------------------------------------------------------------------------
# Summary
+1 -1
View File
@@ -66,7 +66,7 @@ done
# Cross-check: does the Makefile stow anything that is NOT in our package set?
echo "== Checking Makefile stow targets against stow-able packages =="
make_pkgs="$(grep -P '^\t' Makefile | grep -oE 'stow [A-Za-z0-9_-]+' | awk '{print $2}' | sort -u)"
make_pkgs="$(grep -P '^\t' Makefile | grep -E '\bstow\b' | awk '{print $NF}' | sort -u)"
for mp in $make_pkgs; do
if is_stowable "$mp"; then
echo "ok: Makefile 'stow $mp' matches a stow-able package"
+1 -7
View File
@@ -56,15 +56,9 @@ declare -A BINS=(
[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"
[brightnessctl]="brightnessctl --version"
[wpaperd]="wpaperd --version"
)
-74
View File
@@ -1,74 +0,0 @@
#!/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
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
echo "==> Lese Paketliste: $PACKAGES_FILE"
read_packages
install_pacman
install_aur
install_npm
echo "Fertig. Standalone Utilities sind eingerichtet."
}
main