aboutsummaryrefslogtreecommitdiffstats
path: root/install.sh
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-29 09:55:45 +0200
committerDanilo M. <danix@danix.xyz>2026-09-29 09:55:45 +0200
commit1e4d2b4be7ad20dd108503fb65c264673ca6457b (patch)
tree8d76604d4bdebe5fa4b4e60be2447df61475789f /install.sh
parenta06d8f948c4d5a60bff992c3d6f26b5fb54f80cb (diff)
downloadunified-desktop-theme-1e4d2b4be7ad20dd108503fb65c264673ca6457b.tar.gz
unified-desktop-theme-1e4d2b4be7ad20dd108503fb65c264673ca6457b.zip
feat(install): track rofi scripts, wire nvim and hypr-theme, merge qt/gtk keys
The rofi menus' launch scripts lived loose in ~/bin, so the themes were tracked and the only things that open them were not. They now live in bin/ and are symlinked under the names hypr-theme's keybindings call. neovim gets a generated colorscheme: catppuccin/nvim with all 26 palette colours overridden from the active scheme, selected by rewriting only the colorscheme line of init.vim. hypr-theme is linked as the whole of ~/.config/hypr, leaving a real directory there alone. The qt-gtk templates were reference copies nothing installed. They now hold theme keys only and ini_merge writes them into the live qt5ct, qt6ct and gtk3 files key by key, keeping every other line; tests/ini-merge.sh checks it. The stale kvantum.kvconfig template is gone, install.sh writes that file. Fresh-machine fixes: settings.ini and ~/.config/gtk-4.0 are created when missing instead of aborting under set -e, and conky is found as a sibling checkout and skipped when absent, in udt-palette as well as install.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'install.sh')
-rwxr-xr-xinstall.sh111
1 files changed, 98 insertions, 13 deletions
diff --git a/install.sh b/install.sh
index 36903ea..9626431 100755
--- a/install.sh
+++ b/install.sh
@@ -9,6 +9,47 @@ target="$HOME/.config/rofi/udt"
mkdir -p "$target" "$HOME/bin" "$HOME/.cache/udt"
+# Merge an ini template into a live file key by key: every key the template
+# sets is written, every other line of the live file is kept as it was. Keys
+# missing from a section are appended to it, missing sections to the end. The
+# live file is written through rather than replaced, so a symlink survives.
+ini_merge() {
+ local tmpl="$1" live="$2"
+ mkdir -p "$(dirname "$live")"
+ [ -e "$live" ] || : > "$live"
+ awk '
+ function flush( i, p) {
+ for (i = 1; i <= n; i++) {
+ split(order[i], p, SUBSEP)
+ if (p[1] == sec && !(order[i] in done)) { print want[order[i]]; done[order[i]] = 1 }
+ }
+ for (; blank > 0; blank--) print ""
+ }
+ FNR == NR {
+ if (/^\[/) ts = $0
+ else if (/^[^#;].*=/) { k = ts SUBSEP substr($0, 1, index($0, "=") - 1); want[k] = $0; order[++n] = k }
+ next
+ }
+ /^[[:space:]]*$/ { blank++; next }
+ /^\[/ { flush(); sec = $0; print; next }
+ { for (; blank > 0; blank--) print "" }
+ index($0, "=") && ((sec SUBSEP substr($0, 1, index($0, "=") - 1)) in want) {
+ k = sec SUBSEP substr($0, 1, index($0, "=") - 1)
+ print want[k]; done[k] = 1; next
+ }
+ { print }
+ END {
+ flush()
+ for (i = 1; i <= n; i++) if (!(order[i] in done)) {
+ split(order[i], p, SUBSEP)
+ if (!(p[1] in hdr)) { print p[1]; hdr[p[1]] = 1 }
+ print want[order[i]]
+ }
+ }' "$tmpl" "$live" > "$live.udt-tmp"
+ cat "$live.udt-tmp" > "$live"
+ rm -f "$live.udt-tmp"
+}
+
# Generate every themed config from the selected scheme first: the rofi palette
# symlinked below is one of its outputs, so this has to run before anything is
# linked. It fails loudly if a role names a colour the scheme does not define,
@@ -61,8 +102,11 @@ fi
mkdir -p "$HOME/.cache/wal"
ln -sfn "$HOME/.cache/udt/colors.json" "$HOME/.cache/wal/colors.json"
-ln -sfn "$repo/bin/udt-accent" "$HOME/bin/udt-accent"
-ln -sfn "$repo/bin/udt-palette" "$HOME/bin/udt-palette"
+# The rofi menus are bound by name in hypr-theme's keybindings, so they keep
+# the names they had when they lived loose in ~/bin.
+for f in udt-accent udt-palette udt-powermenu.sh udt-launcher.sh qar-scrotmenu.sh; do
+ ln -sfn "$repo/bin/$f" "$HOME/bin/$f"
+done
# The generated configs for everything that is not rofi. These are copied
# rather than symlinked: each app owns its config file and mixes theme keys
@@ -171,15 +215,43 @@ done
# GTK3 reads the theme name from gsettings on Wayland, not settings.ini: the
# file is written too, but gsettings is what actually wins. It was once pinned
-# to Breeze, silently overriding the file.
-sed -i 's/^gtk-theme-name=.*/gtk-theme-name=udt/' "$HOME/.config/gtk-3.0/settings.ini"
+# to Breeze, silently overriding the file. Every scheme is dark, so
+# prefer-dark is set too; the portal passes it to libadwaita apps.
+ini_merge "$repo/templates/qt-gtk/gtk3-settings.ini" "$HOME/.config/gtk-3.0/settings.ini"
if command -v gsettings >/dev/null 2>&1; then
gsettings set org.gnome.desktop.interface gtk-theme 'udt' 2>/dev/null || true
+ gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null || true
fi
# GTK4 ignores gtk-theme-name entirely; its stylesheet is imported by
-# ~/.config/gtk-4.0/gtk.css through this symlink.
+# ~/.config/gtk-4.0/gtk.css through this symlink. gtk.css is seeded when
+# missing, and otherwise only gets the import prepended if it lacks one.
+mkdir -p "$HOME/.config/gtk-4.0"
ln -sfn "$gtk_theme/gtk-4.0" "$HOME/.config/gtk-4.0/theme"
+gtk4_css="$HOME/.config/gtk-4.0/gtk.css"
+if [ ! -f "$gtk4_css" ]; then
+ cp "$repo/templates/qt-gtk/gtk4-gtk.css" "$gtk4_css"
+elif ! grep -q '@import url("theme/gtk.css")' "$gtk4_css"; then
+ { echo '@import url("theme/gtk.css");'; cat "$gtk4_css"; } > "$gtk4_css.udt-tmp"
+ cat "$gtk4_css.udt-tmp" > "$gtk4_css"
+ rm -f "$gtk4_css.udt-tmp"
+fi
+
+# qt5ct and qt6ct hand Qt apps to Kvantum. Theme keys only: both files also
+# hold settings and personal lists that are none of this repo's business.
+ini_merge "$repo/templates/qt-gtk/qt5ct.conf" "$HOME/.config/qt5ct/qt5ct.conf"
+ini_merge "$repo/templates/qt-gtk/qt6ct.conf" "$HOME/.config/qt6ct/qt6ct.conf"
+
+# neovim. The colorscheme is generated, and selected with one line in
+# init.vim, rewritten only if it names something else. Like Sublime's
+# color_scheme key: the rest of init.vim is none of this repo's business.
+mkdir -p "$HOME/.config/nvim/colors"
+ln -sfn "$repo/templates/nvim/udt.lua" "$HOME/.config/nvim/colors/udt.lua"
+nvim_init="$HOME/.config/nvim/init.vim"
+if [ -f "$nvim_init" ] && ! grep -qx 'colorscheme udt' "$nvim_init"; then
+ sed -i 's/^colorscheme .*/colorscheme udt/' "$nvim_init"
+ grep -qx 'colorscheme udt' "$nvim_init" && echo "nvim: colorscheme switched to udt"
+fi
# Obsidian and Typora need more than a copy: the Obsidian snippet has to be
# enabled in each vault's appearance.json without disturbing the snippets
@@ -192,14 +264,27 @@ ln -sfn "$gtk_theme/gtk-4.0" "$HOME/.config/gtk-4.0/theme"
# The Lua dashboard lives in its own repo; udt-palette renders its colours into
# conky.conf there. Both the config and the Lua it loads are linked, since
# lua_load points at ~/.config/conky/dashboard.lua.
-conky_repo="$HOME/Programming/GIT/conky-theme-udt"
-mkdir -p "$HOME/.config/conky"
-ln -sfn "$conky_repo/conky.conf" "$HOME/.config/conky/conky.conf"
-ln -sfn "$conky_repo/dashboard.lua" "$HOME/.config/conky/dashboard.lua"
-ln -sfn "$conky_repo/lib" "$HOME/.config/conky/lib"
-ln -sfn "$conky_repo/widgets" "$HOME/.config/conky/widgets"
-# bin/ holds the weather fetch script, which conky.text runs on an execi.
-ln -sfn "$conky_repo/bin" "$HOME/.config/conky/bin"
+# A sibling checkout, like waybar-theme-udt, and skipped when absent.
+conky_repo="$(realpath -m "$repo/../conky-theme-udt")"
+if [ -d "$conky_repo" ]; then
+ mkdir -p "$HOME/.config/conky"
+ # bin/ holds the weather fetch script, which conky.text runs on an execi.
+ for f in conky.conf dashboard.lua lib widgets bin; do
+ ln -sfn "$conky_repo/$f" "$HOME/.config/conky/$f"
+ done
+fi
+
+# Hyprland. hypr-theme is the whole of ~/.config/hypr, linked as one
+# directory, and it reads the border this repo generates. A real directory
+# there is someone's config: it is left alone rather than replaced.
+hypr_repo="$(realpath -m "$repo/../hypr-theme")"
+if [ -d "$hypr_repo" ]; then
+ if [ -L "$HOME/.config/hypr" ] || [ ! -e "$HOME/.config/hypr" ]; then
+ ln -sfn "$hypr_repo" "$HOME/.config/hypr"
+ elif [ "$(realpath "$HOME/.config/hypr")" != "$hypr_repo" ]; then
+ echo "hypr: ~/.config/hypr is a real directory, left alone; move it aside to link hypr-theme" >&2
+ fi
+fi
# Reload what is running. Writing the configs is not enough: waybar, kitty and
# Hyprland reread on a signal, conky only on a restart, and rofi