# Writable mode for dots-hyprland # Stages configuration to .configstaging and provides setup script { config, lib, pkgs, ... }: with lib; let cfg = config.programs.dots-hyprland.writable-mode; mainCfg = config.programs.dots-hyprland; # Create the initial setup script setupScript = pkgs.writeShellScript "dots-hyprland-setup" '' #!/usr/bin/env bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log() { echo -e "''${GREEN}[dots-hyprland]''${NC} $1" } warn() { echo -e "''${YELLOW}[dots-hyprland]''${NC} WARNING: $1" } error() { echo -e "''${RED}[dots-hyprland]''${NC} ERROR: $1" } info() { echo -e "''${BLUE}[dots-hyprland]''${NC} $1" } STAGING_DIR="$HOME/${cfg.stagingDir}" CONFIG_DIR="$HOME/.config" BACKUP_DIR="$HOME/.config-backup-$(date +%Y%m%d-%H%M%S)" log "🚀 dots-hyprland Initial Setup" log "📁 Staging: $STAGING_DIR" log "🎯 Target: $CONFIG_DIR" # Check if staging directory exists if [[ ! -d "$STAGING_DIR" ]]; then error "Staging directory not found: $STAGING_DIR" error "Please run 'home-manager switch' first to create the staging area" exit 1 fi # Backup existing configuration if requested ${optionalString cfg.backupExisting '' if [[ -d "$CONFIG_DIR" ]]; then log "💾 Creating backup at $BACKUP_DIR" mkdir -p "$BACKUP_DIR" # Backup specific directories that will be overwritten for dir in quickshell hypr fish foot kitty fuzzel wlogout; do if [[ -d "$CONFIG_DIR/$dir" ]]; then info " Backing up $dir" cp -r "$CONFIG_DIR/$dir" "$BACKUP_DIR/" 2>/dev/null || true fi done log "✅ Backup complete" fi ''} # Function to copy or symlink files copy_config() { local src="$1" local dst="$2" local name="$(basename "$src")" if [[ -d "$src" ]]; then info "📂 Processing directory: $name" mkdir -p "$dst" ${if cfg.symlinkMode then '' # Create symlink if [[ -L "$dst" ]]; then rm "$dst" elif [[ -d "$dst" ]]; then rm -rf "$dst" fi ln -sf "$src" "$dst" info " 🔗 Symlinked: $name" '' else '' # Copy files cp -rf "$src"/* "$dst/" 2>/dev/null || true info " 📋 Copied: $name" ''} elif [[ -f "$src" ]]; then info "📄 Processing file: $name" mkdir -p "$(dirname "$dst")" ${if cfg.symlinkMode then '' # Create symlink if [[ -L "$dst" ]] || [[ -f "$dst" ]]; then rm "$dst" fi ln -sf "$src" "$dst" info " 🔗 Symlinked: $name" '' else '' # Copy file cp "$src" "$dst" info " 📋 Copied: $name" ''} fi } # Copy/symlink all staged configuration log "🔄 ${if cfg.symlinkMode then "Symlinking" else "Copying"} configuration files..." # Process all directories in staging for item in "$STAGING_DIR"/*; do if [[ -e "$item" ]]; then name="$(basename "$item")" copy_config "$item" "$CONFIG_DIR/$name" fi done # Copy .local/share files if they exist if [[ -d "$STAGING_DIR/.local/share" ]]; then log "📦 Processing .local/share files..." mkdir -p "$HOME/.local/share" copy_config "$STAGING_DIR/.local/share/icons" "$HOME/.local/share/icons" copy_config "$STAGING_DIR/.local/share/konsole" "$HOME/.local/share/konsole" fi log "✅ Configuration setup complete!" log "" log "📋 Next steps:" log " 1. Your configuration is now ${if cfg.symlinkMode then "symlinked" else "copied"} to ~/.config/" log " 2. ${if cfg.symlinkMode then "Files are symlinked - changes to staging will reflect immediately" else "Files are copied - you can now modify them freely"}" log " 3. Test quickshell: quickshell" log " 4. Test Python environment: test-dots-hyprland-venv" ${optionalString cfg.backupExisting '' log " 5. Your original config was backed up to: $BACKUP_DIR" ''} log "" log "🎉 Enjoy your dots-hyprland setup!" ''; # Create a status/info script statusScript = pkgs.writeShellScript "dots-hyprland-status" '' #!/usr/bin/env bash GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' echo -e "''${GREEN}dots-hyprland Status''${NC}" echo "====================" # Check staging directory STAGING_DIR="$HOME/${cfg.stagingDir}" if [[ -d "$STAGING_DIR" ]]; then echo -e "✅ Staging directory: ''${GREEN}$STAGING_DIR''${NC}" echo " $(find "$STAGING_DIR" -type f | wc -l) files staged" else echo -e "❌ Staging directory: ''${RED}Not found''${NC}" fi # Check Python virtual environment VENV_PATH="$HOME/.local/state/quickshell/.venv" if [[ -d "$VENV_PATH" ]]; then echo -e "✅ Python venv: ''${GREEN}$VENV_PATH''${NC}" if [[ -f "$VENV_PATH/bin/python" ]]; then VERSION=$("$VENV_PATH/bin/python" --version 2>&1) echo " $VERSION" fi else echo -e "❌ Python venv: ''${RED}Not found''${NC}" fi # Check quickshell config if [[ -d "$HOME/.config/quickshell" ]]; then echo -e "✅ Quickshell config: ''${GREEN}~/.config/quickshell''${NC}" if [[ -L "$HOME/.config/quickshell" ]]; then echo " (symlinked to staging)" else echo " (copied from staging)" fi else echo -e "❌ Quickshell config: ''${RED}Not found''${NC}" fi # Check environment variable if [[ -n "$ILLOGICAL_IMPULSE_VIRTUAL_ENV" ]]; then echo -e "✅ Environment variable: ''${GREEN}ILLOGICAL_IMPULSE_VIRTUAL_ENV''${NC}" echo " $ILLOGICAL_IMPULSE_VIRTUAL_ENV" else echo -e "❌ Environment variable: ''${RED}ILLOGICAL_IMPULSE_VIRTUAL_ENV not set''${NC}" fi echo "" echo "Commands:" echo " ${cfg.setupScript} - Run initial setup" echo " dots-hyprland-status - Show this status" echo " test-dots-hyprland-venv - Test Python environment" ''; in { options.programs.dots-hyprland.writable-mode = { enable = mkEnableOption "Writable mode for dots-hyprland configuration"; source = mkOption { type = types.path; description = "Source path for dots-hyprland configuration"; }; stagingDir = mkOption { type = types.str; default = ".configstaging"; description = "Directory to stage configuration files"; }; setupScript = mkOption { type = types.str; default = "initialSetup.sh"; description = "Name of the setup script"; }; backupExisting = mkOption { type = types.bool; default = true; description = "Backup existing configuration files"; }; symlinkMode = mkOption { type = types.bool; default = false; description = "Create symlinks instead of copying files"; }; }; config = mkIf cfg.enable { # Stage all configuration files and install scripts home.file = let # Get all config directories from source configDirs = [ "quickshell" "hypr" "fish" "foot" "kitty" "fuzzel" "wlogout" "matugen" ]; # Create staging entries for each config directory stagingEntries = listToAttrs (map (dir: { name = "${cfg.stagingDir}/${dir}"; value = { source = "${cfg.source}/.config/${dir}"; recursive = true; }; }) configDirs); # Add NixOS-specific patches nixosPatches = { }; # Add .local/share files to staging localShareEntries = { "${cfg.stagingDir}/.local/share/icons" = { source = "${cfg.source}/.local/share/icons"; recursive = true; }; "${cfg.stagingDir}/.local/share/konsole" = { source = "${cfg.source}/.local/share/konsole"; recursive = true; }; }; # Scripts and utilities scriptEntries = { ".local/bin/${cfg.setupScript}" = { source = setupScript; executable = true; }; ".local/bin/dots-hyprland-status" = { source = statusScript; executable = true; }; "${cfg.stagingDir}/README.md" = { text = '' # dots-hyprland Configuration Staging This directory contains the staged configuration files from the original dots-hyprland repository. ## Setup Run the setup script to copy/symlink these files to your ~/.config directory: ```bash ~/.local/bin/${cfg.setupScript} ``` ## Mode: ${if cfg.symlinkMode then "Symlink" else "Copy"} ${if cfg.symlinkMode then '' **Symlink Mode**: Files will be symlinked to ~/.config/ - Changes to files in staging will reflect immediately - Useful for development and testing - Files remain managed by Home Manager '' else '' **Copy Mode**: Files will be copied to ~/.config/ - You can modify the copied files freely - Changes won't affect the staging area - Full user control over configuration ''} ## Status Check the current status with: ```bash dots-hyprland-status ``` ## Files Staged - quickshell/ - Widget system configuration - hypr/ - Hyprland window manager configuration - fish/ - Fish shell configuration - foot/ - Foot terminal configuration - kitty/ - Kitty terminal configuration - fuzzel/ - Fuzzel launcher configuration - wlogout/ - Logout menu configuration - .local/share/icons/ - Custom icons - .local/share/konsole/ - Konsole profiles ## Python Environment The Python virtual environment is managed separately and will be created at: `~/.local/state/quickshell/.venv` Test it with: `test-dots-hyprland-venv` ''; }; }; in stagingEntries // localShareEntries // scriptEntries // nixosPatches; }; }