feat(core): migrate system state to unified declarative JSON
- Consolidate all configuration toggles (suspend, idle, waybar, etc.) into ~/.config/home-manager/state.json - Introduce nomarchy.toggles and nomarchy.hyprland options in Nix - Inject toggle states into all bin/ scripts via environment variables - Update toggle scripts to mutate JSON and trigger background rebuilds - Add a migration script to transition legacy flag files to the new format
This commit is contained in:
@@ -11,12 +11,14 @@ if [[ -z $font_name ]]; then
|
||||
fi
|
||||
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
STATE_FILE="$STATE_DIR/font-state.nix"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
if fc-list | grep -iq "$font_name"; then
|
||||
echo "$font_name" > "$STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".font = \"$font_name\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
echo "Font set to $font_name declaratively. Applying changes..."
|
||||
env-update
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
# Toggles the window gaps globally between no gaps and the default 10/5/2, declaratively and instantly.
|
||||
|
||||
STATE_FILE="$HOME/.config/home-manager/hyprland-state.json"
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
echo '{"gaps_out": 10, "gaps_in": 5, "border_size": 2}' > "$STATE_FILE"
|
||||
echo "{}" > "$STATE_FILE"
|
||||
fi
|
||||
|
||||
gaps=$(jq -r '.gaps_out' "$STATE_FILE")
|
||||
gaps=$(jq -r '.hyprland.gaps_out // 10' "$STATE_FILE")
|
||||
|
||||
if [[ $gaps == "0" ]]; then
|
||||
NEW_STATE='{"gaps_out": 10, "gaps_in": 5, "border_size": 2}'
|
||||
@@ -23,5 +23,7 @@ else
|
||||
hyprctl keyword general:border_size 0
|
||||
fi
|
||||
|
||||
echo "$NEW_STATE" > "$STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".hyprland = $NEW_STATE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Toggled gaps to $NEW_STATE declaratively."
|
||||
|
||||
@@ -11,10 +11,12 @@ fi
|
||||
pgrep -f org.nomarchy.screensaver && exit 0
|
||||
|
||||
# Allow screensaver to be turned off but also force started
|
||||
if [[ -f ~/.local/state/nomarchy/toggles/screensaver-off ]] && [[ $1 != "force" ]]; then
|
||||
exit 1
|
||||
# Skip if screensaver is disabled in configuration
|
||||
if [[ $NOMARCHY_TOGGLE_SCREENSAVER == "false" ]] && [[ $1 != "force" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# Silently quit Walker on overlay
|
||||
walker -q
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Manage persistent state files for Nomarchy toggles and settings.
|
||||
# Manage persistent runtime state files for Nomarchy indicators.
|
||||
# Usage: nomarchy-state <set|clear> <state-name-or-pattern>
|
||||
# Used to track whether features like suspend, idle lock, etc are enabled or disabled.
|
||||
# Used to track whether things like reboot, restart, etc are required.
|
||||
# DO NOT use this for configuration toggles (suspend, screensaver, etc).
|
||||
# Use declarative Nomarchy NixOS home-manager options for those instead.
|
||||
|
||||
STATE_DIR="$HOME/.local/state/nomarchy"
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
# Declarative + Hybrid (instant swww) for Nomarchy NixOS.
|
||||
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
|
||||
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
THEME_NAME=$(cat "$THEME_STATE_FILE" 2>/dev/null || echo "nord")
|
||||
THEME_NAME=$(jq -r '.theme // "nord"' "$STATE_FILE")
|
||||
|
||||
if [ -d "/etc/nixos/nomarchy/themes" ]; then
|
||||
THEMES_DIR="/etc/nixos/nomarchy/themes"
|
||||
@@ -32,7 +33,7 @@ if (( TOTAL == 0 )); then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_BG=$(cat "$WALLPAPER_STATE_FILE" 2>/dev/null)
|
||||
CURRENT_BG=$(jq -r '.wallpaper' "$STATE_FILE")
|
||||
INDEX=-1
|
||||
for i in "${!BACKGROUNDS[@]}"; do
|
||||
if [[ "$BG_DIR/${BACKGROUNDS[$i]}" == "$CURRENT_BG" ]]; then
|
||||
@@ -44,7 +45,8 @@ done
|
||||
NEXT_INDEX=$(((INDEX + 1) % TOTAL))
|
||||
NEW_BG="$BG_DIR/${BACKGROUNDS[$NEXT_INDEX]}"
|
||||
|
||||
echo "$NEW_BG" > "$WALLPAPER_STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".wallpaper = \"$NEW_BG\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
# Instant feedback via swww
|
||||
if pgrep -x swww-daemon >/dev/null; then
|
||||
|
||||
@@ -11,8 +11,7 @@ if [[ -z $THEME_NAME ]]; then
|
||||
fi
|
||||
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
|
||||
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
|
||||
# Logic for finding themes
|
||||
if [ -d "/etc/nixos/nomarchy/themes" ]; then
|
||||
@@ -24,6 +23,7 @@ else
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
if [ ! -d "$THEMES_DIR/$THEME_NAME" ] && ! [[ "$THEME_NAME" == "nord" ]]; then
|
||||
echo "Theme '$THEME_NAME' not found in $THEMES_DIR"
|
||||
@@ -31,18 +31,23 @@ if [ ! -d "$THEMES_DIR/$THEME_NAME" ] && ! [[ "$THEME_NAME" == "nord" ]]; then
|
||||
# (Assuming nomarchy-palettes.nix is imported in Nix)
|
||||
fi
|
||||
|
||||
echo "$THEME_NAME" > "$THEME_STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".theme = \"$THEME_NAME\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
# Try to find a background for this theme
|
||||
BG_DIR="$THEMES_DIR/$THEME_NAME/backgrounds"
|
||||
if [ -d "$BG_DIR" ]; then
|
||||
BG=$(ls "$BG_DIR" | head -n 1)
|
||||
if [ -n "$BG" ]; then
|
||||
echo "$BG_DIR/$BG" > "$WALLPAPER_STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".wallpaper = \"$BG_DIR/$BG\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Theme set to $THEME_NAME. Applying changes with env-update..."
|
||||
rm -rf "$HOME/.config/nomarchy/current/theme"
|
||||
env-update
|
||||
|
||||
nomarchy-theme-set-templates
|
||||
|
||||
nomarchy-hook theme-set "$THEME_NAME"
|
||||
|
||||
@@ -7,9 +7,8 @@ VS_CODE_THEME="$HOME/.config/nomarchy/current/theme/vscode.json"
|
||||
set_theme() {
|
||||
local editor_cmd="$1"
|
||||
local settings_path="$2"
|
||||
local skip_flag="$3"
|
||||
|
||||
nomarchy-cmd-present "$editor_cmd" && [[ ! -f $skip_flag ]] || return 0
|
||||
nomarchy-cmd-present "$editor_cmd" && [[ $NOMARCHY_TOGGLE_SKIP_VSCODE_THEME != "true" ]] || return 0
|
||||
|
||||
if [[ -f $VS_CODE_THEME ]]; then
|
||||
theme_name=$(jq -r '.name' "$VS_CODE_THEME")
|
||||
@@ -34,7 +33,7 @@ set_theme() {
|
||||
fi
|
||||
}
|
||||
|
||||
set_theme "code" "$HOME/.config/Code/User/settings.json" "$HOME/.local/state/nomarchy/toggles/skip-vscode-theme-changes"
|
||||
set_theme "code-insiders" "$HOME/.config/Code - Insiders/User/settings.json" "$HOME/.local/state/nomarchy/toggles/skip-vscode-insiders-theme-changes"
|
||||
set_theme "codium" "$HOME/.config/VSCodium/User/settings.json" "$HOME/.local/state/nomarchy/toggles/skip-codium-theme-changes"
|
||||
set_theme "cursor" "$HOME/.config/Cursor/User/settings.json" "$HOME/.local/state/nomarchy/toggles/skip-cursor-theme-changes"
|
||||
set_theme "code" "$HOME/.config/Code/User/settings.json"
|
||||
set_theme "code-insiders" "$HOME/.config/Code - Insiders/User/settings.json"
|
||||
set_theme "codium" "$HOME/.config/VSCodium/User/settings.json"
|
||||
set_theme "cursor" "$HOME/.config/Cursor/User/settings.json"
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Toggles the idle daemon (hypridle) between enabled and disabled.
|
||||
# Declarative + Hybrid (instant IPC/kill) for Nomarchy NixOS.
|
||||
# Hybrid: updates state.json and provides instant feedback.
|
||||
|
||||
STATE_FILE="$HOME/.config/home-manager/idle-state.json"
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
echo '{"enabled": true}' > "$STATE_FILE"
|
||||
fi
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
enabled=$(jq -r '.enabled' "$STATE_FILE")
|
||||
|
||||
if [[ $enabled == "true" ]]; then
|
||||
NEW_ENABLED="false"
|
||||
pkill -x hypridle
|
||||
notify-send -u low " Stop locking computer when idle"
|
||||
else
|
||||
NEW_ENABLED="true"
|
||||
if [[ $NOMARCHY_TOGGLE_IDLE == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
setsid hypridle >/dev/null 2>&1 &
|
||||
notify-send -u low " Now locking computer when idle"
|
||||
else
|
||||
NEW_VALUE="false"
|
||||
pkill -x hypridle
|
||||
notify-send -u low " Stop locking computer when idle"
|
||||
fi
|
||||
|
||||
echo "{\"enabled\": $NEW_ENABLED}" > "$STATE_FILE"
|
||||
echo "Idle daemon set to $NEW_ENABLED declaratively."
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".idle = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Idle state set to $NEW_VALUE. Environment will be fully updated on next rebuild."
|
||||
|
||||
pkill -RTMIN+9 waybar # Signal waybar if needed
|
||||
|
||||
@@ -1,36 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Toggles the nightlight (hyprsunset) between enabled (4000) and disabled (6500)
|
||||
# Declarative + Hybrid (instant IPC) for Nomarchy NixOS.
|
||||
# Toggles the nightlight (hyprsunset).
|
||||
# Hybrid: updates state.json and provides instant feedback.
|
||||
|
||||
STATE_FILE="$HOME/.config/home-manager/hyprsunset-state.json"
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
echo '{"enabled": false, "temperature": 4000}' > "$STATE_FILE"
|
||||
fi
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
enabled=$(jq -r '.enabled' "$STATE_FILE")
|
||||
|
||||
if [[ $enabled == "true" ]]; then
|
||||
NEW_ENABLED="false"
|
||||
TEMP=6500
|
||||
notify-send -u low " Nightlight DISABLED"
|
||||
if [[ $NOMARCHY_TOGGLE_NIGHTLIGHT == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
hyprctl dispatch exec hyprsunset --temperature 4000
|
||||
notify-send -u low " Nightlight enabled"
|
||||
else
|
||||
NEW_ENABLED="true"
|
||||
TEMP=4000
|
||||
notify-send -u low " Nightlight ENABLED"
|
||||
NEW_VALUE="false"
|
||||
pkill hyprsunset
|
||||
notify-send -u low " Nightlight disabled"
|
||||
fi
|
||||
|
||||
# Instant feedback via IPC
|
||||
if pgrep -x hyprsunset >/dev/null; then
|
||||
hyprctl hyprsunset temperature $TEMP
|
||||
else
|
||||
# Should be started by systemd, but just in case
|
||||
setsid hyprsunset -t $TEMP &
|
||||
fi
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".nightlight = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "{\"enabled\": $NEW_ENABLED, \"temperature\": 4000}" > "$STATE_FILE"
|
||||
echo "Nightlight set to $NEW_ENABLED ($TEMP) declaratively."
|
||||
# No need to run env-update if we don't want the delay,
|
||||
# as next HM switch will pick it up and apply it.
|
||||
echo "Nightlight state set to $NEW_VALUE. Environment will be fully updated on next rebuild."
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
STATE_FILE=~/.local/state/nomarchy/toggles/screensaver-off
|
||||
# Toggles the screensaver availability.
|
||||
# Hybrid: updates state.json and runs env-update for persistence.
|
||||
|
||||
if [[ -f $STATE_FILE ]]; then
|
||||
rm -f $STATE_FILE
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
if [[ $NOMARCHY_TOGGLE_SCREENSAVER == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
notify-send -u low " Screensaver enabled"
|
||||
else
|
||||
mkdir -p "$(dirname $STATE_FILE)"
|
||||
touch $STATE_FILE
|
||||
NEW_VALUE="false"
|
||||
notify-send -u low " Screensaver disabled"
|
||||
fi
|
||||
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".screensaver = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Screensaver state set to $NEW_VALUE. Updating environment..."
|
||||
|
||||
env-update
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
STATE_FILE=~/.local/state/nomarchy/toggles/suspend-off
|
||||
# Toggles the suspend menu option availability.
|
||||
# Hybrid: updates state.json and runs env-update for persistence.
|
||||
|
||||
if [[ -f $STATE_FILE ]]; then
|
||||
rm -f $STATE_FILE
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# Get current state from env or state file
|
||||
if [[ $NOMARCHY_TOGGLE_SUSPEND == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
notify-send -u low " Suspend now available in system menu"
|
||||
else
|
||||
mkdir -p "$(dirname $STATE_FILE)"
|
||||
touch $STATE_FILE
|
||||
NEW_VALUE="false"
|
||||
notify-send -u low " Suspend removed from system menu"
|
||||
fi
|
||||
|
||||
# Update JSON using jq
|
||||
# We use a temporary file to avoid corruption if the shell is interrupted
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".suspend = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Suspend availability set to $NEW_VALUE. Updating environment..."
|
||||
|
||||
# Run env-update to apply changes to the menu
|
||||
env-update
|
||||
|
||||
@@ -1,7 +1,25 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if pgrep -x waybar >/dev/null; then
|
||||
pkill -x waybar
|
||||
else
|
||||
# Toggles the waybar top bar.
|
||||
# Hybrid: updates state.json and provides instant feedback.
|
||||
|
||||
STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
if [[ $NOMARCHY_TOGGLE_WAYBAR == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
uwsm-app -- waybar >/dev/null 2>&1 &
|
||||
notify-send -u low " Top bar enabled"
|
||||
else
|
||||
NEW_VALUE="false"
|
||||
pkill -x waybar
|
||||
notify-send -u low " Top bar disabled"
|
||||
fi
|
||||
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".waybar = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Waybar state set to $NEW_VALUE. Environment will be fully updated on next rebuild."
|
||||
|
||||
89
migrations/20260404_migrate_state_to_json.sh
Normal file
89
migrations/20260404_migrate_state_to_json.sh
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Migration: Migrate individual state files to unified state.json
|
||||
# Version: 20260404
|
||||
|
||||
OLD_TOGGLES_DIR="$HOME/.local/state/nomarchy/toggles"
|
||||
IDLE_STATE_FILE="$HOME/.config/home-manager/idle-state.json"
|
||||
NIGHTLIGHT_STATE_FILE="$HOME/.config/home-manager/hyprsunset-state.json"
|
||||
HYPRLAND_STATE_FILE="$HOME/.config/home-manager/hyprland-state.json"
|
||||
THEME_STATE_FILE="$HOME/.config/home-manager/theme-state.nix"
|
||||
WALLPAPER_STATE_FILE="$HOME/.config/home-manager/wallpaper-state.nix"
|
||||
FONT_STATE_FILE="$HOME/.config/home-manager/font-state.nix"
|
||||
NEW_STATE_FILE="$HOME/.config/home-manager/state.json"
|
||||
|
||||
mkdir -p "$(dirname "$NEW_STATE_FILE")"
|
||||
[[ ! -f $NEW_STATE_FILE ]] && echo "{}" > "$NEW_STATE_FILE"
|
||||
|
||||
# 1. Migrate .local/state/nomarchy/toggles (these were empty 'off' flag files)
|
||||
if [[ -d $OLD_TOGGLES_DIR ]]; then
|
||||
for file in "$OLD_TOGGLES_DIR"/*; do
|
||||
[[ -e "$file" ]] || continue
|
||||
filename=$(basename "$file")
|
||||
case "$filename" in
|
||||
suspend-off)
|
||||
echo "Migrating suspend-off -> suspend: false"
|
||||
jq '.suspend = false' "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
;;
|
||||
screensaver-off)
|
||||
echo "Migrating screensaver-off -> screensaver: false"
|
||||
jq '.screensaver = false' "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
;;
|
||||
skip-vscode-theme-changes)
|
||||
echo "Migrating skip-vscode-theme-changes -> skipVsCodeTheme: true"
|
||||
jq '.skipVsCodeTheme = true' "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
;;
|
||||
esac
|
||||
rm "$file"
|
||||
done
|
||||
rmdir "$OLD_TOGGLES_DIR" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 2. Migrate existing JSON state files
|
||||
if [[ -f $IDLE_STATE_FILE ]]; then
|
||||
echo "Migrating idle-state.json -> state.json"
|
||||
ENABLED=$(jq '.enabled' "$IDLE_STATE_FILE")
|
||||
jq ".idle = $ENABLED" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$IDLE_STATE_FILE"
|
||||
fi
|
||||
|
||||
if [[ -f $NIGHTLIGHT_STATE_FILE ]]; then
|
||||
echo "Migrating hyprsunset-state.json -> state.json"
|
||||
ENABLED=$(jq '.enabled' "$NIGHTLIGHT_STATE_FILE")
|
||||
TEMP=$(jq '.temperature' "$NIGHTLIGHT_STATE_FILE")
|
||||
jq ".nightlight = $ENABLED | .nightlightTemperature = $TEMP" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$NIGHTLIGHT_STATE_FILE"
|
||||
fi
|
||||
|
||||
if [[ -f $HYPRLAND_STATE_FILE ]]; then
|
||||
echo "Migrating hyprland-state.json -> state.json"
|
||||
GAPS_OUT=$(jq '.gaps_out' "$HYPRLAND_STATE_FILE")
|
||||
GAPS_IN=$(jq '.gaps_in' "$HYPRLAND_STATE_FILE")
|
||||
BORDER_SIZE=$(jq '.border_size' "$HYPRLAND_STATE_FILE")
|
||||
jq ".hyprland = {\"gaps_out\": $GAPS_OUT, \"gaps_in\": $GAPS_IN, \"border_size\": $BORDER_SIZE}" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$HYPRLAND_STATE_FILE"
|
||||
fi
|
||||
|
||||
# 3. Migrate plaintext string state files
|
||||
if [[ -f $THEME_STATE_FILE ]]; then
|
||||
echo "Migrating theme-state.nix -> state.json"
|
||||
THEME=$(cat "$THEME_STATE_FILE" | tr -d '\n')
|
||||
jq ".theme = \"$THEME\"" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$THEME_STATE_FILE"
|
||||
fi
|
||||
|
||||
if [[ -f $WALLPAPER_STATE_FILE ]]; then
|
||||
echo "Migrating wallpaper-state.nix -> state.json"
|
||||
WALLPAPER=$(cat "$WALLPAPER_STATE_FILE" | tr -d '\n')
|
||||
jq ".wallpaper = \"$WALLPAPER\"" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$WALLPAPER_STATE_FILE"
|
||||
fi
|
||||
|
||||
if [[ -f $FONT_STATE_FILE ]]; then
|
||||
echo "Migrating font-state.nix -> state.json"
|
||||
FONT=$(cat "$FONT_STATE_FILE" | tr -d '\n')
|
||||
jq ".font = \"$FONT\"" "$NEW_STATE_FILE" > "$NEW_STATE_FILE.tmp" && mv "$NEW_STATE_FILE.tmp" "$NEW_STATE_FILE"
|
||||
rm "$FONT_STATE_FILE"
|
||||
fi
|
||||
|
||||
echo "State migration complete."
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
let
|
||||
palettes = import ../../themes/nomarchy-palettes.nix;
|
||||
# Reads the state file. If it doesn't exist, defaults to nord.
|
||||
stateFile = "${config.home.homeDirectory}/.config/home-manager/theme-state.nix";
|
||||
activeThemeName = if builtins.pathExists stateFile then
|
||||
lib.removeSuffix "\n" (builtins.readFile stateFile)
|
||||
else "nord";
|
||||
userPackagesFile = "${config.home.homeDirectory}/.config/home-manager/user-packages.json";
|
||||
userPackages = if builtins.pathExists userPackagesFile then
|
||||
let
|
||||
@@ -20,6 +15,9 @@ in
|
||||
imports = [
|
||||
inputs.nix-colors.homeManagerModules.default
|
||||
inputs.walker.homeManagerModules.default
|
||||
./options.nix
|
||||
./state.nix
|
||||
./theme-files.nix
|
||||
./fonts.nix
|
||||
./alacritty.nix
|
||||
./nightlight.nix
|
||||
@@ -34,7 +32,7 @@ in
|
||||
./swayosd.nix
|
||||
];
|
||||
|
||||
colorScheme = palettes.${activeThemeName} or palettes.nord;
|
||||
colorScheme = palettes.${config.nomarchy.theme} or palettes.nord;
|
||||
|
||||
home.packages = with pkgs; [
|
||||
firefox
|
||||
|
||||
@@ -1,22 +1,6 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{ ... }:
|
||||
|
||||
let
|
||||
# Standardize state files to a common directory
|
||||
stateDir = "${config.home.homeDirectory}/.config/home-manager";
|
||||
fontStateFile = "${stateDir}/font-state.nix";
|
||||
activeFont = if builtins.pathExists fontStateFile then
|
||||
lib.removeSuffix "\n" (builtins.readFile fontStateFile)
|
||||
else "JetBrainsMono Nerd Font";
|
||||
in
|
||||
{
|
||||
options.nomarchy.fonts = {
|
||||
monospace = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = activeFont;
|
||||
description = "Monospace font for the system";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
fonts.fontconfig.enable = true;
|
||||
xdg.dataFile."fonts/nomarchy.ttf".source = ../../config/nomarchy.ttf;
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
wallpaperStateFile = "${config.home.homeDirectory}/.config/home-manager/wallpaper-state.nix";
|
||||
activeWallpaper = if builtins.pathExists wallpaperStateFile then
|
||||
lib.removeSuffix "\n" (builtins.readFile wallpaperStateFile)
|
||||
else "";
|
||||
hyprlandStateFile = "${config.home.homeDirectory}/.config/home-manager/hyprland-state.json";
|
||||
hyprlandState = if builtins.pathExists hyprlandStateFile then
|
||||
builtins.fromJSON (builtins.readFile hyprlandStateFile)
|
||||
else { gaps_out = 10; gaps_in = 5; border_size = 2; };
|
||||
activeWallpaper = config.nomarchy.wallpaper;
|
||||
hyprlandState = config.nomarchy.hyprland;
|
||||
in
|
||||
{
|
||||
wayland.windowManager.hyprland = {
|
||||
@@ -23,10 +17,9 @@ in
|
||||
};
|
||||
"exec-once" = [
|
||||
"swww-daemon & sleep 0.5 && swww img ${activeWallpaper} --transition-type none"
|
||||
"waybar"
|
||||
"nomarchy-on-boot"
|
||||
"nomarchy-welcome"
|
||||
];
|
||||
] ++ (lib.optional config.nomarchy.toggles.waybar "waybar");
|
||||
"bind" = [
|
||||
"SUPER, Space, exec, walker"
|
||||
"SUPER ALT, Space, exec, nomarchy-theme-selector"
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
{ config, pkgs, ... }:
|
||||
{ config, ... }:
|
||||
|
||||
let
|
||||
stateFile = "${config.home.homeDirectory}/.config/home-manager/idle-state.json";
|
||||
idleState = if builtins.pathExists stateFile then
|
||||
builtins.fromJSON (builtins.readFile stateFile)
|
||||
else { enabled = true; };
|
||||
in
|
||||
{
|
||||
services.hypridle = {
|
||||
enable = idleState.enabled;
|
||||
enable = config.nomarchy.toggles.idle;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
{ config, pkgs, ... }:
|
||||
{ config, ... }:
|
||||
|
||||
let
|
||||
stateFile = "${config.home.homeDirectory}/.config/home-manager/hyprsunset-state.json";
|
||||
hyprsunsetState = if builtins.pathExists stateFile then
|
||||
builtins.fromJSON (builtins.readFile stateFile)
|
||||
else { enabled = false; temperature = 4000; };
|
||||
temp = toString (if hyprsunsetState.enabled then hyprsunsetState.temperature else 6500);
|
||||
temp = toString (if config.nomarchy.toggles.nightlight then config.nomarchy.nightlightTemperature else 6500);
|
||||
in
|
||||
{
|
||||
services.hyprsunset = {
|
||||
|
||||
77
modules/home/options.nix
Normal file
77
modules/home/options.nix
Normal file
@@ -0,0 +1,77 @@
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options.nomarchy = {
|
||||
toggles = {
|
||||
suspend = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to show suspend in system menu.";
|
||||
};
|
||||
screensaver = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether the screensaver is enabled.";
|
||||
};
|
||||
idle = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether the idle lock is enabled.";
|
||||
};
|
||||
nightlight = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether the nightlight is enabled.";
|
||||
};
|
||||
waybar = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether the top bar is enabled.";
|
||||
};
|
||||
skipVsCodeTheme = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to skip theme changes in VSCode.";
|
||||
};
|
||||
};
|
||||
nightlightTemperature = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 4000;
|
||||
description = "Temperature for the nightlight.";
|
||||
};
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nord";
|
||||
description = "System theme name.";
|
||||
};
|
||||
wallpaper = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "System wallpaper path.";
|
||||
};
|
||||
hyprland = {
|
||||
gaps_in = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5;
|
||||
description = "Inner gaps for Hyprland.";
|
||||
};
|
||||
gaps_out = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
description = "Outer gaps for Hyprland.";
|
||||
};
|
||||
border_size = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2;
|
||||
description = "Border size for Hyprland.";
|
||||
};
|
||||
};
|
||||
fonts = {
|
||||
monospace = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "JetBrainsMono Nerd Font";
|
||||
description = "System monospace font.";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -42,11 +42,18 @@ let
|
||||
cp -r * $out/bin/
|
||||
chmod +x $out/bin/*
|
||||
|
||||
# Wrap every script to ensure dependencies are in PATH
|
||||
# Wrap every script to ensure dependencies are in PATH and inject configuration
|
||||
for file in $out/bin/*; do
|
||||
if [ -f "$file" ]; then
|
||||
wrapProgram "$file" \
|
||||
--prefix PATH : ${lib.makeBinPath nomarchy-deps}
|
||||
--prefix PATH : ${lib.makeBinPath nomarchy-deps} \
|
||||
--set NOMARCHY_TOGGLE_SUSPEND "${if config.nomarchy.toggles.suspend then "true" else "false"}" \
|
||||
--set NOMARCHY_TOGGLE_SCREENSAVER "${if config.nomarchy.toggles.screensaver then "true" else "false"}" \
|
||||
--set NOMARCHY_TOGGLE_IDLE "${if config.nomarchy.toggles.idle then "true" else "false"}" \
|
||||
--set NOMARCHY_TOGGLE_NIGHTLIGHT "${if config.nomarchy.toggles.nightlight then "true" else "false"}" \
|
||||
--set NOMARCHY_TOGGLE_WAYBAR "${if config.nomarchy.toggles.waybar then "true" else "false"}" \
|
||||
--set NOMARCHY_TOGGLE_SKIP_VSCODE_THEME "${if config.nomarchy.toggles.skipVsCodeTheme then "true" else "false"}" \
|
||||
--set NOMARCHY_MONOSPACE_FONT "${config.nomarchy.fonts.monospace}"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
43
modules/home/state.nix
Normal file
43
modules/home/state.nix
Normal file
@@ -0,0 +1,43 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
stateDir = "${config.home.homeDirectory}/.config/home-manager";
|
||||
|
||||
# Helper to read state from a file, with a default
|
||||
readState = file: default:
|
||||
if builtins.pathExists "${stateDir}/${file}" then
|
||||
let
|
||||
content = builtins.readFile "${stateDir}/${file}";
|
||||
cleanContent = lib.removeSuffix "\n" content;
|
||||
in
|
||||
if lib.hasSuffix ".json" file then
|
||||
builtins.fromJSON cleanContent
|
||||
else
|
||||
cleanContent
|
||||
else
|
||||
default;
|
||||
|
||||
# Unified state reading
|
||||
togglesState = readState "state.json" {};
|
||||
in
|
||||
{
|
||||
config.nomarchy = {
|
||||
toggles = {
|
||||
suspend = togglesState.suspend or true;
|
||||
screensaver = togglesState.screensaver or true;
|
||||
idle = togglesState.idle or true;
|
||||
nightlight = togglesState.nightlight or false;
|
||||
waybar = togglesState.waybar or true;
|
||||
skipVsCodeTheme = togglesState.skipVsCodeTheme or false;
|
||||
};
|
||||
nightlightTemperature = togglesState.nightlightTemperature or 4000;
|
||||
theme = togglesState.theme or "nord";
|
||||
wallpaper = togglesState.wallpaper or "";
|
||||
hyprland = {
|
||||
gaps_in = togglesState.hyprland.gaps_in or 5;
|
||||
gaps_out = togglesState.hyprland.gaps_out or 10;
|
||||
border_size = togglesState.hyprland.border_size or 2;
|
||||
};
|
||||
fonts.monospace = togglesState.font or "JetBrainsMono Nerd Font";
|
||||
};
|
||||
}
|
||||
@@ -4,14 +4,9 @@ let
|
||||
# Re-use our state-based logic
|
||||
palettes = import ../../themes/nomarchy-palettes.nix;
|
||||
|
||||
themeStateFile = "${config.home.homeDirectory}/.config/home-manager/theme-state.nix";
|
||||
activeThemeName = if builtins.pathExists themeStateFile then
|
||||
lib.removeSuffix "\n" (builtins.readFile themeStateFile)
|
||||
else "nord";
|
||||
|
||||
wallpaperStateFile = "${config.home.homeDirectory}/.config/home-manager/wallpaper-state.nix";
|
||||
activeWallpaper = if builtins.pathExists wallpaperStateFile then
|
||||
lib.removeSuffix "\n" (builtins.readFile wallpaperStateFile)
|
||||
activeThemeName = config.nomarchy.theme;
|
||||
activeWallpaper = if config.nomarchy.wallpaper != "" then
|
||||
config.nomarchy.wallpaper
|
||||
else "${../../themes/catppuccin/backgrounds/1-totoro.png}"; # Fallback
|
||||
|
||||
# Map nix-colors palette to a format Stylix expects (attrset of hex strings)
|
||||
|
||||
@@ -6,55 +6,32 @@ let
|
||||
themeList = builtins.concatStringsSep "\\n" themeNames;
|
||||
|
||||
nomarchy-theme-selector = pkgs.writeShellScriptBin "nomarchy-theme-selector" ''
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
|
||||
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
|
||||
if [ -d "/etc/nixos/nomarchy/themes" ]; then
|
||||
THEMES_DIR="/etc/nixos/nomarchy/themes"
|
||||
elif [ -d "/etc/nomarchy/themes" ]; then
|
||||
THEMES_DIR="/etc/nomarchy/themes"
|
||||
else
|
||||
THEMES_DIR="/etc/nixos/themes"
|
||||
fi # This depends on where the repo is cloned
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
SELECTED_THEME=$(echo -e "${themeList}" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_THEME" ]; then
|
||||
echo "$SELECTED_THEME" > "$THEME_STATE_FILE"
|
||||
|
||||
# Try to find a background for this theme
|
||||
BG_DIR="$THEMES_DIR/$SELECTED_THEME/backgrounds"
|
||||
if [ -d "$BG_DIR" ]; then
|
||||
BG=$(ls "$BG_DIR" | head -n 1)
|
||||
if [ -n "$BG" ]; then
|
||||
echo "$BG_DIR/$BG" > "$WALLPAPER_STATE_FILE"
|
||||
swww img "$BG_DIR/$BG" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90 &
|
||||
fi
|
||||
fi
|
||||
|
||||
env-update
|
||||
nomarchy-theme-set "$SELECTED_THEME"
|
||||
fi
|
||||
'';
|
||||
nomarchy-font-selector = pkgs.writeShellScriptBin "nomarchy-font-selector" ''
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
STATE_FILE="$STATE_DIR/font-state.nix"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# Simple list of common nerd fonts, could be expanded
|
||||
FONTS="JetBrainsMono Nerd Font\nRobotoMono Nerd Font\nFiraCode Nerd Font\nUbuntuMono Nerd Font"
|
||||
SELECTED_FONT=$(echo -e "$FONTS" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_FONT" ]; then
|
||||
echo "$SELECTED_FONT" > "$STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".font = \"$SELECTED_FONT\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
env-update
|
||||
fi
|
||||
'';
|
||||
nomarchy-wallpaper-selector = pkgs.writeShellScriptBin "nomarchy-wallpaper-selector" ''
|
||||
STATE_DIR="$HOME/.config/home-manager"
|
||||
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
if [ -d "/etc/nixos/nomarchy/themes" ]; then
|
||||
THEMES_DIR="/etc/nixos/nomarchy/themes"
|
||||
elif [ -d "/etc/nomarchy/themes" ]; then
|
||||
@@ -64,13 +41,15 @@ let
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# List all images in all themes backgrounds
|
||||
WALLPAPERS=$(find "$THEMES_DIR" -type f \( -name "*.jpg" -o -name "*.png" \))
|
||||
SELECTED_WP=$(echo -e "$WALLPAPERS" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_WP" ]; then
|
||||
echo "$SELECTED_WP" > "$WALLPAPER_STATE_FILE"
|
||||
TMP_JSON=$(mktemp)
|
||||
jq ".wallpaper = \"$SELECTED_WP\"" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
swww img "$SELECTED_WP" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90 &
|
||||
env-update
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user