Files
alt-illogical-impulse/modules/home-manager.nix
T
Celes Renata c90cc9427c Add matugen directory to backup handling
- Add matugen to writable-mode backup script directory list
- Add matugen conflict handling to Home Manager activation script
- Handle both symlinked and regular matugen directories
- Prevents activation failures due to existing matugen configs

This resolves the 'mkdir: cannot create directory' and 'ln: failed to create symbolic link'
errors that occur when ~/.config/matugen already exists during Home Manager activation.
2025-08-10 13:25:22 -07:00

244 lines
9.3 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Main Home Manager module for dots-hyprland
# Supports both declarative and writable modes
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.dots-hyprland;
packages = import ../packages { inherit pkgs; };
in
{
imports = [
./python-environment.nix
./configuration.nix
./writable-mode.nix
./components/quickshell-service.nix
./components/quickshell-config.nix
./components/hyprland-config.nix
./components/terminal-config.nix
./components/touchegg.nix
./components/config-override.nix
];
options.programs.dots-hyprland = {
enable = mkEnableOption "dots-hyprland desktop environment";
source = mkOption {
type = types.path;
description = "Source path for clean dots-hyprland configuration";
example = "inputs.dots-hyprland";
};
packageSet = mkOption {
type = types.enum [ "minimal" "essential" "all" ];
default = "essential";
description = "Which package set to install";
};
mode = mkOption {
type = types.enum [ "declarative" "writable" "hybrid" ];
default = "hybrid";
description = ''
Configuration mode:
- hybrid: Hyprland declarative + Quickshell copied (recommended)
- declarative: Files managed by Home Manager (read-only)
- writable: Files staged to .configstaging, user copies and modifies
'';
};
writable = mkOption {
type = types.submodule {
options = {
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 in ~/.local/bin/";
};
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";
};
};
};
default = {};
description = "Writable mode configuration";
};
};
config = mkIf cfg.enable {
# Enable Python environment for color generation
programs.dots-hyprland.python = {
enable = true;
autoSetup = true;
};
# Install packages based on selected set
home.packages =
let
packageSets = import ../packages/dots-hyprland-packages.nix { inherit lib pkgs; };
in
if cfg.packageSet == "minimal" then packageSets.minimalPackages
else if cfg.packageSet == "essential" then packageSets.essentialPackages
else packageSets.allPackages;
# Enable configuration management based on mode
programs.dots-hyprland.configuration = mkIf (cfg.mode == "declarative" || cfg.mode == "hybrid") {
enable = mkDefault (cfg.mode == "hybrid"); # Enable copying for hybrid mode
source = cfg.source;
# In hybrid mode, copy Quickshell but not Hyprland (use overrides instead)
copyMiscConfig = mkDefault (cfg.mode == "hybrid");
copyFishConfig = mkDefault true;
copyHyprlandConfig = mkDefault (cfg.mode == "declarative"); # Only copy in pure declarative mode
};
# Enable writable mode
programs.dots-hyprland.writable-mode = mkIf (cfg.mode == "writable") {
enable = true;
source = cfg.source;
inherit (cfg.writable) stagingDir setupScript backupExisting symlinkMode;
};
# Enable quickshell service (works with both modes)
programs.dots-hyprland.quickshell = {
enable = true;
autoStart = true;
restartOnFailure = true;
logLevel = "info";
};
# Enable touchegg gesture support
programs.dots-hyprland.touchegg = {
enable = true;
};
# Enable custom keybindings
# Set critical environment variables (required for both modes)
home.sessionVariables = {
ILLOGICAL_IMPULSE_VIRTUAL_ENV = "$HOME/.local/state/quickshell/.venv";
# Ensure GNOME schemas are available for gsettings
XDG_DATA_DIRS = "$XDG_DATA_DIRS:${pkgs.gsettings-desktop-schemas}/share";
};
# Ensure ~/.local/bin is in PATH for our working qs script
home.sessionPath = [ "$HOME/.local/bin" ];
# Generate qmldir files for all modes (runs after all config is in place)
home.activation.generateQmldirFiles = lib.hm.dag.entryAfter ["linkGeneration"] ''
if [[ -d "$HOME/.config/quickshell/ii" ]]; then
$DRY_RUN_CMD echo "🔧 Generating qmldir files with singleton detection..."
$DRY_RUN_CMD ${packages.generate-qmldir}/bin/generate-qmldir "$HOME/.config/quickshell/ii"
$DRY_RUN_CMD echo " qmldir files generated successfully for ${cfg.mode} mode"
else
$DRY_RUN_CMD echo " Warning: quickshell/ii directory not found, skipping qmldir generation"
fi
'';
# Create working qs script with Qt5Compat support
home.activation.createWorkingQsScript = lib.hm.dag.entryAfter ["linkGeneration"] ''
$DRY_RUN_CMD echo "🔧 Creating working qs script with Qt5Compat support..."
$DRY_RUN_CMD mkdir -p "$HOME/.local/bin"
$DRY_RUN_CMD cat > "$HOME/.local/bin/qs" << 'EOF'
#!/usr/bin/env bash
export QML2_IMPORT_PATH="${pkgs.kdePackages.qt5compat}/lib/qt-6/qml:$HOME/.config/quickshell/ii:$HOME/.config/quickshell:$QML2_IMPORT_PATH"
exec quickshell "$@"
EOF
$DRY_RUN_CMD chmod +x "$HOME/.local/bin/qs"
$DRY_RUN_CMD echo " Working qs script created successfully"
# Also install the quickshell reset script
$DRY_RUN_CMD echo "🔧 Installing quickshell reset script..."
$DRY_RUN_CMD cp "${packages.quickshell-reset}/bin/quickshell-reset.sh" "$HOME/.local/bin/"
$DRY_RUN_CMD chmod +x "$HOME/.local/bin/quickshell-reset.sh"
$DRY_RUN_CMD echo " Quickshell reset script installed successfully"
'';
# Custom activation script to copy quickshell configs (needed for relative imports)
home.activation.copyQuickshellConfigs = lib.hm.dag.entryBefore ["linkGeneration"] ''
$DRY_RUN_CMD echo "🔧 Setting up quickshell configuration for ${cfg.mode} mode..."
# Remove any existing symlinked configs to avoid conflicts with system home-manager
if [[ -L "$HOME/.config/quickshell" ]]; then
$DRY_RUN_CMD rm "$HOME/.config/quickshell"
$DRY_RUN_CMD echo " Removed conflicting symlinked quickshell config"
fi
# Handle conflicting .local/share symlinks that may interfere with home-manager
if [[ -L "$HOME/.local/share/icons" ]]; then
$DRY_RUN_CMD rm "$HOME/.local/share/icons"
$DRY_RUN_CMD echo " Removed conflicting symlinked icons directory"
fi
if [[ -L "$HOME/.local/share/konsole" ]]; then
$DRY_RUN_CMD rm "$HOME/.local/share/konsole"
$DRY_RUN_CMD echo " Removed conflicting symlinked konsole directory"
fi
# Handle conflicting .config directories
if [[ -L "$HOME/.config/fish" ]]; then
$DRY_RUN_CMD rm "$HOME/.config/fish"
$DRY_RUN_CMD echo " Removed conflicting symlinked fish config"
fi
if [[ -L "$HOME/.config/matugen" ]]; then
$DRY_RUN_CMD rm "$HOME/.config/matugen"
$DRY_RUN_CMD echo " Removed conflicting symlinked matugen config"
fi
# Also handle if they exist as regular directories
if [[ -d "$HOME/.local/share/konsole" && ! -L "$HOME/.local/share/konsole" ]]; then
$DRY_RUN_CMD mv "$HOME/.local/share/konsole" "$HOME/.local/share/konsole.backup-$(date +%Y%m%d-%H%M%S)"
$DRY_RUN_CMD echo " Backed up existing konsole directory"
fi
if [[ -d "$HOME/.config/fish" && ! -L "$HOME/.config/fish" ]]; then
$DRY_RUN_CMD mv "$HOME/.config/fish" "$HOME/.config/fish.backup-$(date +%Y%m%d-%H%M%S)"
$DRY_RUN_CMD echo " Backed up existing fish config directory"
fi
if [[ -d "$HOME/.config/matugen" && ! -L "$HOME/.config/matugen" ]]; then
$DRY_RUN_CMD mv "$HOME/.config/matugen" "$HOME/.config/matugen.backup-$(date +%Y%m%d-%H%M%S)"
$DRY_RUN_CMD echo " Backed up existing matugen config directory"
fi
'';
# Copy quickshell config after link generation
home.activation.setupQuickshellConfig = lib.hm.dag.entryAfter ["linkGeneration"] ''
${optionalString (cfg.mode == "hybrid") ''
# Copy quickshell config to enable relative imports
if [[ ! -d "$HOME/.config/quickshell" ]] || [[ -L "$HOME/.config/quickshell" ]]; then
$DRY_RUN_CMD mkdir -p "$HOME/.config"
$DRY_RUN_CMD cp -r "${cfg.source}/quickshell" "$HOME/.config/"
$DRY_RUN_CMD chmod -R u+w "$HOME/.config/quickshell"
$DRY_RUN_CMD echo " Quickshell configuration copied successfully"
else
$DRY_RUN_CMD echo " Quickshell configuration already exists"
fi
# Ensure our working qs script takes precedence over any system-managed quickshell
$DRY_RUN_CMD mkdir -p "$HOME/.local/bin"
$DRY_RUN_CMD echo " Ensuring ~/.local/bin is in PATH for hybrid mode"
''}
'';
# Ensure XDG directories exist (installer requirement)
xdg.enable = true;
xdg.userDirs.enable = true;
};
}