Files
nixos/Droidnix
2026-03-19 14:01:44 +00:00
..
2026-03-17 20:38:24 +00:00
2026-03-19 11:52:13 +00:00
2026-03-19 12:38:26 +00:00
2026-03-19 13:48:10 +00:00
2026-03-19 14:01:44 +00:00

Droidnix: A Dendritic NixOS + Home Manager Configuration NixOS Configuration Structure

Introduction   intro

What is Droidnix

Droidnix is a modular, declarative NixOS + Home Manager configuration system. It allows users to choose between Hyprland and Mangowc as their window manager, with shared and WM-specific configurations managed via Emacs Org and Nix Flakes. The project is designed for reproducibility, maintainability, and cross-machine compatibility.

Installed components:

Core
Hyprland
Mangowc

Goals, project Structure, import hierarchy

This project uses a modular NixOS configuration with Hyprland and MangoWC support, designed for literate programming and cross-device reusability. The Droidnix repository is organized into two main parts:

  1. .assets/: Static, non-generated files (e.g., configs, scripts, themes).
  2. Generated folders (system, hyprland, mangowc): NixOS and Home Manager configurations, generated from Org files.

Root Level

  • flake.nix is the entry point and imports:

    • generated/system/
    • generated/modules/desktop/
    • Machine-specific configurations from assets/machines/

Generated Structure

The generated/ directory contains all generated configurations, divided into three main groups: system, hyprland, and mangowc.

First Setup

  1. Clone this repository.
  2. Run the setup script: ./setup_droid.
  3. Edit .assets/system/conf/base.conf to choose your window manager (wm = "hyprland" or wm = "mangowc").
  4. Tangle this Org file to generate Nix configurations: C-c C-v t in Emacs or use this: emacs README.org --batch -f org-babel-tangle && emacs --batch --eval "(setq org-html-htmlize-output-type nil)" README.org -f org-html-export-to-html
  5. Build and switch: sudo nixos-rebuild switch --flake .#<hostname>.

The Assets Folder   assets

The .assets/ folder contains all static files, such as configs, scripts, and themes. These files are not generated and can be edited directly.

The Actual Code   code

This section contains the Org blocks for tangling Nix code into the generated folders.

flake.nix

The Nix flake definition for Droidnix.

{
  description = "Droidnix: A dendritic NixOS + Home Manager configuration";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    hyprland.url = "github:hyprwm/Hyprland";
    flake-parts.url = "github:hercules-ci/flake-parts";
    import-tree.url = "github:vic/import-tree";

    stylix = {
      url = "github:nix-community/stylix";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    emacs-overlay = {
      url = "github:nix-community/emacs-overlay";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    zen-browser = {
      url = "github:youwen5/zen-browser-flake";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ flake-parts, nixpkgs, ... }:
     flake-parts.lib.mkFlake { inherit inputs; } {

       systems = [ "x86_64-linux" ];

       flake = {
         nixosConfigurations.traveldroid = nixpkgs.lib.nixosSystem {
           system = "x86_64-linux";

           specialArgs = { inherit inputs; };

           modules =
             [
               # ./generated/system/mysystem.nix
             ]
             ++ (inputs.import-tree ./generated/modules).imports
             ++ [
               ./generated/hosts/traveldroid/traveldroid.nix
               ./generated/hosts/traveldroid/boot.nix
               ./generated/hosts/traveldroid/hardware-configuration.nix

               inputs.stylix.nixosModules.default
               inputs.home-manager.nixosModules.home-manager
             ];
          };
       };
     };
 }

Let's define the core of the system

generated/hosts/traveldroid/networking.nix

This sets the networking.

{ lib, config, pkgs,... }:

let
  coreEnabled = config.mySystem.system.core.enable or false;
in
{
  options.mySystem.system.locale.enable =
    lib.mkEnableOption "Network settings";

  config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {

  networking = {
    useDHCP = lib.mkDefault true;
    networkmanager.enable = true;
    networkmanager.wifi.backend = "iwd";
    wireless.iwd.enable = true;
    wireless.userControlled.enable = true;
    firewall = {
      enable = true;
      # KDE Connect: discovery + encrypted connections
      allowedTCPPortRanges = [
        {
          from = 1714;
          to = 1764;
        }
      ];
      allowedUDPPortRanges = [
        {
          from = 1714;
          to = 1764;
        }
      ];
    };
  };

  # Install NetworkManager
  environment.systemPackages = with pkgs; [
    networkmanager
  ];
};
}

generated/hosts/traveldroid/services.nix

This sets the networking.

{ lib, config, ... }:

let
  coreEnabled = config.mySystem.system.core.enable or false;
in
{
  options.mySystem.system.locale.enable =
    lib.mkEnableOption "Services settings (printing / audio)";

  config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {

    # --- Services (Printing & Audio) ---
    services.printing.enable = true;
    services.pulseaudio.enable = false;
    security.rtkit.enable = true;
    services.pipewire = {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
    };
  };
}

generated/hosts/traveldroid/users/user.nix

This is the default user, just search and replace henrov another name if you want to change

{
  config,
  pkgs,
  lib,
  inputs,
  ...
}:

let
  user = import ./henrov.nix;
in
{
  home-manager.users.${user.username} = {
    home.stateVersion = "26.05";
    home.username = user.username;
    home.homeDirectory = user.homeDirectory;
  };

  # Ensure the user is in the necessary groups
  users.users.${config.users.users.${user.username}.username} = {
    extraGroups = [ "wheel" "networkmanager" ];
  };
}

generated/hosts/traveldroid/users/henrov.nix

This is the default user, just search and replace henrov another name if you want to change

{
  username = "henrov";
  hashedPassword = "$6$ISAmsPLyFi7idYXr$VmZsq.zMsyh1irSkyDNqtorNXG0oEHbbMVqTii1t8bymvrQ5ZQmbdi4OiBNeNYe/huHGrojXM.3TST2fTLz0T.";
  homeDirectory = "/home/henrov";
  stateVersion = "26.05";
  locale = "nl_NL.UTF-8";
}

generated/hosts/traveldroid/homebase.nix

{ lib, config, ... }:

let
  coreEnabled = config.mySystem.system.core.enable or false;
in
{
  options.mySystem.system.locale.enable =
    lib.mkEnableOption "Home-Manager settings";

  config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {

    # --- Home Manager Base ---
    home-manager = {
      backupFileExtension = "backup";

      users.henrov = {
	  home.sessionVariables = {
	    TERMINAL = "kitty";
	    EDITOR = "emacs";
	    BROWSER = "zen";
	  };

        home.stateVersion = "26.05";
      };
    };

  };
}

generated/hosts/traveldroid/nix.nix

{ lib, config, ... }:

let
  coreEnabled = config.mySystem.system.core.enable or false;
in
{
  # Top-level option for this module
  options.mySystem.system.locale.enable =
    lib.mkEnableOption "Enable Nix & Flake specific settings";

  # Top-level container for all custom program configs (your myPrograms idea)
  options.myPrograms = lib.mkOption {
    type = lib.types.attrsOf lib.types.any;
    default = {};
    description = "Container for all custom program configurations";
  };

  # Apply the configuration only if core or locale is enabled
  config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {
    nix.settings = {
      experimental-features = [ "nix-command" "flakes" ];
      download-buffer-size = 536870912; # 512 MB
      cores = 2;
      max-jobs = 1;
    };
  };
}

generated/hosts/traveldroid/boot.nix

{ inputs, config, lib, pkgs, ... }:
{

  boot.loader.grub = {
    enable = true;
    efiSupport = true;
    device = "nodev";
    useOSProber = true;
  };
  #boot.efi.canTouchEfiVariables = true;

  boot.kernelParams = [
    "systemd.mask=dev-tpm0.device"
    "systemd.mask=dev-tpmrm0.device"
  ];
}

First the nix-files that flake really needs and that do not fit wel in the hierarchical structure

generated/hosts/traveldroid/traveldroid.nix

{ config, lib, ... }:

{
  # Host-specific system configuration
  networking.hostName = "traveldroid";
  system.stateVersion = "26.05";
  # User-defined features
  mySystem.system.core.enable = true;
  # Hardware overrides
  hardware.nvidia.enabled = false;
}

generated/hosts/traveldroid/hardware-configuration.nix

  1. Boot into NixOS Live ISO or your installed system.
  2. Open a terminal.
  3. Run: <code>sudo nixos-generate-config root /mnt</code> (Omit root /mnt if already running NixOS.)
{
  hostname,
  pkgs,
  lib,
  modulesPath,
  user,
  config,
  ...
}:
{
  imports = [
    # (modulesPath + "/installer/scan/not-detected.nix")
    #../../hardware/hardware.nix
  ];

  boot.initrd.availableKernelModules = [
    "xhci_pci"
    "nvme"
    "usb_storage"
    "sd_mod"
    "rtsx_usb_sdmmc"
  ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  fileSystems."/" = {
    device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2";
    fsType = "ext4";
  };

  fileSystems."/boot" = {
    device = "/dev/disk/by-uuid/811D-0676";
    fsType = "vfat";
    options = [
      "fmask=0077"
      "dmask=0077"
    ];
  };

  swapDevices = [
    { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; }
  ];

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

generated/hosts/traveldroid/dbus.nix

This sets the dbus implementation

{ config, pkgs, lib, ... }:
{
  services.dbus = lib.mkForce {
    enable = true; # Force this to be true
  };

  # Configure dbus-broker via its configuration file
  environment.etc."dbus-broker/launch.conf".text = ''
    [General]
    LogLevel=warning
    MaxConnectionsPerUser=2048
  '';
}

generated/hosts/traveldroid/bluetooth.nix

This sets the bluetooth implementation

{ config, pkgs, ... }:
{
  # Enable Bluetooth hardware and daemon
  hardware.bluetooth = {
    enable = true;
    powerOnBoot = true;
    packages = with pkgs; [ bluez ];
  };

  # Enable Bluetooth audio support in PipeWire
  services.pipewire = {
    config.pulse = {
      bluez5.enable = true;
    };
  };

  # Optional: Additional Bluetooth settings
  hardware.bluetooth.extraConfig = ''
    AutoEnable=true
    DiscoverableTimeout=0
    PairableTimeout=0
  '';

  # Install a graphical Bluetooth manager (optional)
  environment.systemPackages = with pkgs; [
    blueman
  ];
}

generated/hosts/traveldroid/xdg.nix

This sets the XDG implementation

{ config, pkgs, ... }:
{
  xdg.portal = {
    enable = true;
    config.system.default = [ "hyprland" "gtk" ];
  };
}

generated/modules/desktop/stylix.nix

This sets the stylix implementation

{ lib, config, pkgs, flakeRoot, ... }:

let
  # --- Program definition ---
  programName = "stylix";

  # Assets (theme + wallpaper)
  programAssets = "${flakeRoot}/assets/system/theming/${programName}";
  programFiles =
    if builtins.pathExists programAssets
    then builtins.readDir programAssets
    else {};
  files = lib.genAttrs (builtins.attrNames programFiles) (name: {
    src = "${programAssets}/${name}";
  });

  # Enable toggle (must match option)
  enableProgram = config.enableStylix or true;

  # Resolve user safely (outside mkIf)
  user = config.defaultUser or "henrov";

  # --- Stylix configuration (self-contained) ---
  stylixCfg = {
    enable = true;

    base16Scheme =
      "${flakeRoot}/assets/system/theming/stylix/catppuccin-mocha.yaml";

    image =
      "${flakeRoot}/assets/hyprland/wallpaperstuff/pictures/wall1.jpg";

    polarity = "dark";

    cursor = {
      package = pkgs.phinger-cursors;
      name = "phinger-cursors-light";
      size = 24;
    };

    fonts = {
      monospace = {
        package = pkgs.nerd-fonts.fira-code;
        name = "Fira Code Nerd Font";
      };
      sansSerif = {
        package = pkgs.lato;
        name = "Lato";
      };
    };

    icons = {
      enable = true;
      package = pkgs.papirus-icon-theme;
      dark = "Papirus-Dark";
      light = "Papirus-Light";
    };
  };
in
{
  # --- Option ---
  options.enableStylix =
    lib.mkEnableOption "Enable Stylix system theming";

  # --- Config ---
  config = lib.mkIf enableProgram {

    # --- Dendritic app definition ---
    mySystem.${programName} = {
      enable = true;
      assetsDir = programAssets;
      files = files;
      inherit user;

      theme = "catppuccin-mocha";
      polarity = "dark";
    };

    # --- Stylix theming ---
    stylix = stylixCfg;

    # --- Optional: wallpaper helper (kept dendritic) ---
    mySystem.wallpaper = {
      enable = true;
      packages = [ "feh" "st" ];
    };

    # --- Cursor environment variables ---
    home-manager.users.${user}.home.sessionVariables = {
      XCURSOR_THEME    = stylixCfg.cursor.name;
      XCURSOR_SIZE     = toString stylixCfg.cursor.size;
      HYPRCURSOR_THEME = stylixCfg.cursor.name;
      HYPRCURSOR_SIZE  = toString stylixCfg.cursor.size;
    };
  };
}

generated/hosts/traveldroid/terminal.nix

Sets theming for the terminal

{ config, pkgs, ... }:

{
  # (NVF = Neovim/terminal flavor)
  stylix.targets.nvf.enable = true;
  # feh wallpaper integration
  stylix.targets.feh.enable = true;
}

generated/modules/desktop/rotating_wallpaper.nix

rotating_wallpaper.nix installs wpaperd and deploys your wallpaper files from the repo (./assets/hyprland/wallpaperstuff/) into ~/Droidnix/wallpaperstuff/. You can edit assets/hyprland/wallpaperstuff/wallpaper.toml to change settings Finally, it creates a systemd user service (wpaperd.service) that automatically starts wpaperd at login and keeps it running, using your override config so wallpapers rotate according to your settings.

{ lib, … }:

{ flake.nixosModules.rotating-wallpaper = { config, pkgs, lib, … }:

let wallpaperConf = ../../../assets/hyprland/wallpaperstuff/wallpaper.toml; in { options.mySystem.desktop.wallpaper.enable = lib.mkEnableOption "Enable rotating wallpaper via wpaperd";

config = lib.mkIf (config.mySystem.desktop.wallpaper.enable or false) {

home-manager.users.henrov = {

home.packages = [ pkgs.wpaperd ];

home.file.".config/wpaperd/wallpaper.toml".source = wallpaperConf;

systemd.user.services.wpaperd = { description = "wpaperd wallpaper daemon"; wantedBy = [ "default.target" ];

serviceConfig = { Type = "simple"; ExecStart = "${pkgs.wpaperd}/bin/wpaperd config ~/.config/wpaperd/wallpaper.toml"; Restart = "on-failure"; RestartSec = 1; }; }; }; }; }; }

generated/modules/desktop/hyprland.nix

Setting up Hyprland

{ lib, config, flakeRoot, ... }:

let
  # --- Program definition ---
  programName = "hyprland";

  # --- Assets ---
  programAssets = "${flakeRoot}/assets/hyprland/conf/hypr";

  programFiles =
    if builtins.pathExists programAssets
    then builtins.readDir programAssets
    else {};

  fileNames = builtins.attrNames programFiles;

  # Exclude main config (handled separately)
  otherFiles = lib.filter (name: name != "hyprland.conf") fileNames;

  # Generate file mappings
  files = lib.genAttrs otherFiles (name: {
    src = "${programAssets}/${name}";
  });

  # Main config (inline)
  mainConfigPath = "${programAssets}/hyprland.conf";

  # Enable toggle (must match option)
  enableProgram = config.enableHyprland or true;

  # Resolve user safely
  user = config.defaultUser or "henrov";
in
{
  # --- Option ---
  options.enableHyprland =
    lib.mkEnableOption "Enable Hyprland desktop";

  # --- Config ---
  config = lib.mkIf enableProgram {

    # --- Dendritic app definition ---
    mySystem.${programName} = {
      enable = true;
      assetsDir = programAssets;
      files = files;
      inherit user;

      compositor = "hyprland";
    };

    # --- System-level enable ---
    programs.hyprland.enable = true;

    # --- Home Manager wiring ---
    home-manager.users.${user} = {

      home.stateVersion = "26.05";
      home.username = user;
      home.homeDirectory = "/home/${user}";

      wayland.windowManager.hyprland = {
        enable = true;

        settings.general."col.active_border" =
          lib.mkForce "0xff97cbcd 0xff89b4fa";
      };

      # --- Config files ---
      xdg.configFile =
        (lib.mapAttrs' (name: value: {
          name = "hypr/${name}";
          value.source = value.src;
        }) files)
        // {
          "hypr/hyprland.conf".text =
            if builtins.pathExists mainConfigPath
            then builtins.readFile mainConfigPath
            else "";

          "hypr/.keep".text = "";
        };
    };
  };
}

generated/modules/apps/zenbrowser.nix

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

{ lib, pkgs, config, ... }:

let
  programName = "zenbrowser";

  # Optional: path to any assets (empty here since you don't need config)
  programAssets = ../../../assets/system/conf/${programName};
  programFiles = builtins.readDir programAssets;
  files = lib.genAttrs (builtins.attrNames programFiles) (name: {
    src = "${programAssets}/${name}";
  });

  # Toggle variable referring to the module option
  enableProgram = config.enableZenBrowser or false;

in {
  # Top-level toggle option for the module
  options.enableZenBrowser = lib.mkEnableOption "Install Zen Browser";

  # Wrap all configuration in mkIf(enable)
  config = lib.mkIf enableProgram {
    # mySystem container
    mySystem = {
      ${programName} = {
        enable = true;
        assetsDir = programAssets;
        files = files;
        user = config.defaultUser or "henrov";
      };
    };

    # Install the package system-wide
    environment.systemPackages = [ pkgs.zen-browser ];
  };
}

generated/modules/apps/flatpaks.nix

This will import all packages listed in ../../assets/system/apps/flatpaks.conf

{ lib, pkgs, config, ... }:

let
  flatpakConfPath = ../../../assets/system/apps/flatpaks.conf;
  enableProgram = config.enableFlatpaks or false;
in
{
  # Top-level toggle
  options.enableFlatpaks = lib.mkEnableOption "Enable automatic Flatpak installation";

  # Config assignments
  config = lib.mkIf enableProgram {
    # Use programs.flatpaks instead of myApps.flatpaks
    programs.flatpaks = {
      enable    = true;
      user      = config.defaultUser or "henrov";
      assetsDir = flatpakConfPath;
      files     = []; # handled at runtime
    };

    # Deploy the conf file
    environment.etc."flatpak/flatpaks.conf".source = flatpakConfPath;

    # Enable system flatpak service
    services.flatpak.enable = true;
    xdg.portal.enable = true;

    # Systemd service for installing listed flatpaks
    systemd.services.flatpak-sync = {
      description = "Install Flatpak apps listed in flatpaks.conf";
      wantedBy    = [ "multi-user.target" ];
      wants       = [ "network-online.target" ];
      after       = [ "network-online.target" ];

      serviceConfig = {
        Type = "oneshot";
        ExecStart = ''
          set -euo pipefail
          CONF="${flatpakConfPath}"

          if ! flatpak remotes --system --columns=name | grep -qx flathub; then
            flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
          fi

          while IFS= read -r app || [ -n "$app" ]; do
            app=$(echo "$app" | sed 's/#.*//;s/^[[:space:]]*//;s/[[:space:]]*$//')
            if [ -n "$app" ]; then
              if ! flatpak info --system "$app" >/dev/null 2>&1; then
                flatpak install --system -y --noninteractive flathub "$app"
              fi
            fi
          done < "$CONF"
        '';
      };

      restartTriggers = [ flatpakConfPath ];
      path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
    };
  };
}

generated/hosts/traveldroid/gtk.nix

Setting up GTK

{ pkgs, user, ... }:
{
  environment.systemPackages = with pkgs; [
      gtk3     # GTK target
      gtk4     # GTK target
    ];
  # Stylix GTK target
  stylix.targets.gtk.enable = true;

  home-manager.users.${user.username} = {
    gtk = {
      enable = true;
      theme = {
        name = "Catppuccin-Mocha-Standard-Blue-Dark";
        package = pkgs.magnetic-catppuccin-gtk;
      };
      iconTheme = {
        name = "Papirus-Dark";
        package = pkgs.papirus-icon-theme;
      };
      gtk3.extraConfig = {
        gtk-application-prefer-dark-theme = 1;
      };
      gtk4.extraConfig = {
        gtk-application-prefer-dark-theme = 1;
      };
    };

  };
}

generated/modules/desktop/fonts.nix

This file installs and configures fonts

{ lib, pkgs, config, ... }:

{
  options.enableFonts = lib.mkEnableOption "Enable nerd fonts";

  config = lib.mkIf (config.enableFonts or false) {
    fonts.packages = with pkgs; [
      nerd-fonts.iosevka
      nerd-fonts.fira-code
    ];
  };
}

generated/modules/desktop/waybar.nix

This file installs and configures waybar

{ lib, pkgs, config, ... }:

let
  programName = "waybar";

  # Path to configuration assets
  programAssets = ../../../assets/system/conf/${programName};
  programFiles  = builtins.readDir programAssets;
  files         = lib.genAttrs (builtins.attrNames programFiles) (name: {
    src = "${programAssets}/${name}";
  });

  # Toggle variable referring to the top-level option
  enableProgram = config.enableWaybar or false;

  # Default user fallback
  defaultUser = "henrov";

in {
  # Top-level toggle for the module
  options.enableWaybar = lib.mkEnableOption "Enable Waybar status bar";

  # Wrap all actual configuration in mkIf(enableProgram)
  config = lib.mkIf enableProgram {
    # mySystem container for dendritic structure
    mySystem = {
      ${programName} = {
        enable    = true;
        user      = config.defaultUser or defaultUser;
        assetsDir = programAssets;
        files     = files;
      };
    };
  };
}

generated/hosts/traveldroid/login-tuigreeter.nix

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

{ pkgs, user, ... } :
{
environment.systemPackages = with pkgs; [
tuigreet
];
services.greetd = {
enable = true;
settings = {
  default_session = {
  command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'";
  };
};
};
}

generated/modules/desktop/wayland.nix

This file sets up wayland

{ lib, config, ... }:

let
  # --- Program definition ---
  programName = "wayland";

  # Assets (optional, kept for consistency with template)
  programAssets = ../../../assets/system/conf/${programName};
  programFiles =
    if builtins.pathExists programAssets
    then builtins.readDir programAssets
    else {};
  files = lib.genAttrs (builtins.attrNames programFiles) (name: {
    src = "${programAssets}/${name}";
  });

  # Enable toggle (must match option name)
  enableProgram = config.enableWayland or true;

  # Resolve user safely (outside mkIf)
  user = config.defaultUser or "henrov";
in
{
  # --- Option ---
  options.enableWayland =
    lib.mkEnableOption "Enable Wayland + portals";

  # --- Config ---
  config = lib.mkIf enableProgram {

    # --- Dendritic app definition ---
    mySystem.${programName} = {
      enable = true;
      assetsDir = programAssets;
      files = files;
      inherit user;

      # Wayland-specific metadata
      portals = [ "hyprland" ];
    };

    # --- Actual system wiring ---
    home-manager.users.${user} = {

      xdg.portal = {
        enable = true;

        # pkgs is unavoidable here (real package dependency)
        extraPortals = [
          config.pkgs.xdg-desktop-portal-hyprland
        ];

        config.hyprland = {
          "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
        };
      };

      home.packages = [
        config.pkgs.uwsm
      ];
    };
  };
}

generated/modules/apps/thunar.nix

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

{ lib, pkgs, config, ... }:

let
  enableProgram = config.enableThunar or false;
in
{
  # Top-level toggle
  options.enableThunar = lib.mkEnableOption "Enable Thunar file manager";

  # Config assignments
  config = lib.mkIf enableProgram {
    # Replace myApps.thunar with programs.thunar (or your own flat container)
    programs.thunar = {
      user = config.defaultUser or "henrov";
      # Add extra Thunar options here
    };

    environment.systemPackages = [
      pkgs.thunar
      pkgs.thunar-plugins
      pkgs.xarchiver
    ];
  };
}

generated/modules/terminals/kitty.nix

This file sets up Kitty terminal

{ lib, config, pkgs, flakeRoot, ... }:

let
  # --- Module metadata ---
  moduleName   = "kitty";                                         # Change per module
  assetPath    = "${flakeRoot}/assets/system/conf/${moduleName}"; # Path to kitty config
  username     = config.defaultUser or "henrov";                  # Use default user
  enableProgram = config.enableKitty or true;                     # Toggle for this module

  # Read asset files
  assetFiles = builtins.readDir assetPath;

  # Map files → attrset
  files = lib.genAttrs (builtins.attrNames assetFiles) (name: {
    src = "${assetPath}/${name}";
  });
in
{
  # --- Top-level toggle option ---
  options.enableKitty = lib.mkEnableOption "Enable Kitty terminal integration";

  # --- Apply configuration only if enabled ---
  config = lib.mkIf enableProgram {

    # Dendritic container for this program
    myApps.${moduleName} = {
      enable    = true;
      user      = username;
      assetsDir = assetPath;
      files     = files;

      # Program-specific metadata
      theme = "catppuccin-mocha";
    };

    # Deploy config files to XDG config
    home-manager.users.${username} = {
      programs.kitty.enable = true;

      xdg.configFile = lib.mapAttrs' (name: value: {
        name = "${moduleName}/${name}";
        value.source = value.src;
      }) files;
    };

    # Optional systemd service to sync Kitty config (example)
    systemd.services."${moduleName}-sync" = {
      description = "Sync ${moduleName} configuration";
      wantedBy    = [ "multi-user.target" ];
      wants       = [ "network-online.target" ];
      after       = [ "network-online.target" ];

      serviceConfig = {
        Type = "oneshot";
        ExecStart = ''
          set -euo pipefail
          CONF="${assetPath}"

          # Sync each file (example logic)
          for f in ${lib.concatStringsSep " " (builtins.attrNames files)}; do
            cp -u "$CONF/$f" "${HOME}/.config/${moduleName}/$f"
          done
        '';
      };

      restartTriggers = [ assetPath ];

      # Use system-wide binaries without referencing pkgs directly
      path = [
        "/run/current-system/sw/bin/coreutils"
      ];
    };
  };
}

generated/modules/terminals/starship.nix

This file sets up starship prompt

{ lib, ... }:

let
  # Path to your Starship config inside the flake
  starshipAssets = ../../../assets/system/conf/starship.toml;

  # Read and parse the TOML file as a symbolic value
  starshipConfig = lib.importTOML starshipAssets;

  # Toggle on/off
  enableStarship = true;
in
{
  # Declare a top-level module option
  options.starship = {
    enable = lib.mkEnableOption "Enable Starship prompt";
    configFiles = lib.mkOption {
      type = lib.types.attrsOf lib.types.any;
      default = {};
      description = "Symbolic Starship configuration files";
    };
  };

  # Populate the option safely
  config = lib.mkIf enableStarship {
    starship.enable = true;
    starship.configFiles = {
      "starship.toml" = starshipConfig;
      assetsDir = ../../../assets/system/conf;
    };
  };
}

generated/modules/terminals/zsh.nix

This sets up the zsh in the terminal

{ lib, ... }:

let
  # --- Program-specific paths/assets ---
  programName = "zsh";
  programAssets = ../../../assets/system/conf/${programName};
  programFiles = builtins.readDir programAssets;
  files = lib.genAttrs (builtins.attrNames programFiles) (name: {
    src = "${programAssets}/${name}";
  });
in
{
  # Top-level toggle for this program
  options.enableZsh =
    lib.mkEnableOption "Enable Zsh terminal with Oh-My-Zsh";

  # Wrap everything in config if enabled
  config = { config, ... }: let
    # Enable flag now safely references the toggle option
    enableProgram = config.enableZsh or false;

    # Safe reference to defaultUser inside mkIf
    username = config.defaultUser or "henrov";
  in lib.mkIf enableProgram {
    mySystem = {
      zsh = {
        enable = true;
        assetsDir = programAssets;
        files = files;
        user = username;

        # Zsh-specific settings
        ohMyZsh = {
          enable = true;
          theme = "catppuccin-mocha";
          plugins = [
            "git"
            "docker"
            "direnv"
            "zsh-autosuggestions"
            "zsh-completions"
            "zsh-history-substring-search"
            # zsh-syntax-highlighting is sourced in initExtra
          ];
        };

        initExtra = ''
          # Catppuccin Mocha colors
          local mocha_base="#1E1E2E"
          local mocha_surface0="#313244"
          local mocha_text="#CDD6F4"
          local mocha_lavender="#B4BEFE"
          local mocha_blue="#89B4FA"
          local mocha_sapphire="#74C7EC"
          local mocha_teal="#94D2D5"
          local mocha_green="#A6E3A1"
          local mocha_yellow="#F9E2AF"
          local mocha_peach="#FAB387"
          local mocha_maroon="#EBA0AC"
          local mocha_red="#F38BA8"
          local mocha_mauve="#CBA6F7"
          local mocha_pink="#F5E2C7"
          local mocha_flamingo="#F2CDCD"
          local mocha_rosewater="#F5E0DC"

          # Prompt
          PROMPT='%{$fg[$mocha_blue]%}%n%{$reset_color%}@%{$fg[$mocha_peach]%}%m%{$reset_color%} %{$fg[$mocha_lavender]%}%~%{$reset_color%} %{$fg[$mocha_red]%}$%{$reset_color%} '
          RPROMPT='%{$fg[$mocha_green]%}%T%{$reset_color%}'

          # Source zsh-syntax-highlighting if present
          if [ -f ${files."zsh-syntax-highlighting".src} ]; then
            source ${files."zsh-syntax-highlighting".src}
          fi
        '';
      };
    };
  };
}#+END_SRC

** =generated/modules/apps/emacs/emacs.nix=
This sets up the emacs terminal
#+BEGIN_SRC nix :tangle generated/modules/apps/emacs/emacs.nix :noweb tangle :mkdirp yes :eval never-html
{ lib, ... }:

{
  flake.nixosModules.emacs = { config, pkgs, lib, ... }:

  {
    # Optie om de module aan/uit te zetten
    options.mySystem.system.emacs.enable = lib.mkEnableOption "Enable Emacs config";

    config = lib.mkIf (config.mySystem.system.emacs.enable or false) {
      # System packages (optioneel)
      environment.systemPackages = with pkgs; [
        # Voeg systeem-brede packages toe als je wilt
      ];

      # Home Manager configuratie
      home-manager.users.henrov = {
        programs.emacs = {
          enable = true;
          package = pkgs.emacs-pgtk.override { withTreeSitter = true; };

          extraPackages = epkgs: with epkgs; [
            # Tree-sitter and language support
            manualPackages.treesit-grammars.with-all-grammars
            rust-mode
            rustic
            nix-mode
            hcl-mode

            # UI/UX and navigation
            nerd-icons
            doom-modeline
            diminish
            eldoc
            eldoc-box
            pulsar
            which-key
            avy
            consult
            vertico
            marginalia
            crux
            shell-pop

            # Completion and snippets
            nerd-icons-corfu
            corfu
            cape
            orderless
            yasnippet
            yasnippet-snippets

            # Utilities and tools
            rg
            exec-path-from-shell
            eat
            f
            gptel
            nixpkgs-fmt
            envrc

            # Theming
            catppuccin-theme

            # Git
            magit

            # Editing and workflow
            expreg
            vundo
            puni

            # Error and side panel support
            sideline
            sideline-flymake
            sideline-eglot
          ];
        };

        home.sessionVariables = {
          EDITOR = "emacs";
          XDG_SCREENSHOTS_DIR = "~/screenshots";
        };
      };
    };
  };
}

generated/modules/apps/emacs/early-init.el

This helps set up the emacs terminal

;;; package --- early init -*- lexical-binding: t -*-
 ;;; Commentary:
 ;;; Prevents white flash and better Emacs defaults
 ;;; Code:
 (set-language-environment "UTF-8")
 (setq-default
default-frame-alist
'((background-color . "#1e1e2e")
  (bottom-divider-width . 1)    ; Thin horizontal window divider
  (foreground-color . "#bac2de")    ; Default foreground color
  (fullscreen . maximized)      ; Maximize the window by default
  (horizontal-scroll-bars . nil)    ; No horizontal scroll-bars
  (left-fringe . 8)       ; Thin left fringe
  (menu-bar-lines . 0)      ; No menu bar
  (right-divider-width . 1)     ; Thin vertical window divider
  (right-fringe . 8)        ; Thin right fringe
  (tool-bar-lines . 0)      ; No tool bar
  (undecorated . t)       ; Remove extraneous X decorations
  (vertical-scroll-bars . nil))   ; No vertical scroll-bars
user-full-name "Henrov henrov"      ; ME!
;; memory configuration
;; Higher garbage collection threshold, prevents frequent gc locks, reset later
gc-cons-threshold most-positive-fixnum
;; Ignore warnings for (obsolete) elisp compilations
byte-compile-warnings '(not obsolete)
;; And other log types completely
warning-suppress-log-types '((comp) (bytecomp))
;; Large files are okay in the new millenium.
large-file-warning-threshold 100000000
;; dont show garbage collection messages at startup, will reset later
garbage-collection-messages nil
;; native compilation
package-native-compile t
native-comp-warning-on-missing-source nil
native-comp-async-report-warnings-errors 'silent
;; Read more based on system pipe capacity
read-process-output-max (max (* 10240 10240) read-process-output-max)
;; scroll configuration
scroll-margin 0           ; Lets scroll to the end of the margin
scroll-conservatively 100000        ; Never recenter the window
scroll-preserve-screen-position 1     ; Scrolling back and forth
;; frame config
;; Improve emacs startup time by not resizing to adjust for custom settings
frame-inhibit-implied-resize t
;; Dont resize based on character height / width but to exact pixels
frame-resize-pixelwise t
;; backups & files
backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter
backup-by-copying t           ; Don't clobber symlinks
create-lockfiles nil          ; Don't have temp files
delete-old-versions t         ; Cleanup automatically
kept-new-versions 6           ; Update every few times
kept-old-versions 2           ; And cleanup even more
version-control t           ; Version them backups
delete-by-moving-to-trash t       ; Dont delete, send to trash instead
;; startup
inhibit-startup-screen t        ; I have already done the tutorial. Twice
inhibit-startup-message t         ; I know I am ready
inhibit-startup-echo-area-message t     ; Yep, still know it
initial-scratch-message nil       ; I know it is the scratch buffer!
initial-buffer-choice nil
inhibit-startup-buffer-menu t
inhibit-x-resources t
initial-major-mode 'fundamental-mode
pgtk-wait-for-event-timeout 0.001     ; faster child frames
ad-redefinition-action 'accept      ; dont care about legacy things being redefined
inhibit-compacting-font-caches t
;; tabs
tab-width 4             ; Always tab 4 spaces.
indent-tabs-mode nil          ; Never use actual tabs.
;; rendering
cursor-in-non-selected-windows nil      ; dont render cursors other windows
;; packages
use-package-always-defer t
load-prefer-newer t
default-input-method nil
use-dialog-box nil
use-file-dialog nil
use-package-expand-minimally t
package-enable-at-startup nil
use-package-enable-imenu-support t
auto-mode-case-fold nil  ; No second pass of case-insensitive search over auto-mode-alist.
package-archives '(("melpa"    . "https://melpa.org/packages/")
        ("gnu"    . "https://elpa.gnu.org/packages/")
        ("nongnu"   . "https://elpa.nongnu.org/nongnu/")
        ("melpa-stable" . "https://stable.melpa.org/packages/"))
package-archive-priorities '(("gnu"  . 99)
            ("nongnu" . 80)
            ("melpa"  . 70)
            ("melpa-stable" . 50))
)
;;; early-init.el ends here

generated/modules/apps/emacs/init.el

This helps set up the emacs terminal

;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-

;;; Commentary:
;;; Simple Emacs setup I carry everywhere

;;; Code:
(setq custom-file (locate-user-emacs-file "custom.el"))
(load custom-file 'noerror)    ;; no error on missing custom file

(require 'package)
(package-initialize)

(defun reset-custom-vars ()
"Resets the custom variables that were set to crazy numbers"
(setopt gc-cons-threshold (* 1024 1024 100))
(setopt garbage-collection-messages t))

(use-package emacs
:custom
(native-comp-async-query-on-exit t)
(read-answer-short t)
(use-short-answers t)
(enable-recursive-minibuffers t)
(which-func-update-delay 1.0)
(visible-bell nil)
(custom-buffer-done-kill t)
(whitespace-line-column nil)
(x-underline-at-descent-line t)
(imenu-auto-rescan t)
(uniquify-buffer-name-style 'forward)
(confirm-nonexistent-file-or-buffer nil)
(create-lockfiles nil)
(make-backup-files nil)
(kill-do-not-save-duplicates t)
(sentence-end-double-space nil)
(treesit-enabled-modes t)
:init
;; base visual
(menu-bar-mode -1)       ;; no menu bar
(toggle-scroll-bar -1)     ;; no scroll bar
(tool-bar-mode -1)       ;; no tool bar either
(blink-cursor-mode -1)     ;; stop blinking

;; font of the century
(set-frame-font "Aporetic Sans Mono 12" nil t)

:bind
(("C-<wheel-up>" . pixel-scroll-precision) ; dont zoom in please, just scroll
 ("C-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
 ("C-x k"    . kill-current-buffer)) ; kill the buffer, dont ask
:hook
(text-mode . delete-trailing-whitespace-mode)
(prog-mode . delete-trailing-whitespace-mode)
(after-init . global-display-line-numbers-mode) ;; always show line numbers
(after-init . column-number-mode)     ;; column number in the mode line
(after-init . size-indication-mode)     ;; file size in the mode line
(after-init . pixel-scroll-precision-mode)  ;; smooth mouse scroll
(after-init . electric-pair-mode)     ;; i mean ... parens should auto create
(after-init . reset-custom-vars)
)

(use-package autorevert
:ensure nil
:custom
(auto-revert-interval 3)
(auto-revert-remote-files nil)
(auto-revert-use-notify t)
(auto-revert-avoid-polling nil)
(auto-revert-verbose t)
:hook
(after-init . global-auto-revert-mode))

(use-package recentf
:ensure nil
:commands (recentf-mode recentf-cleanup)
:hook
(after-init . recentf-mode)
:custom
(recentf-auto-cleanup 'never)
(recentf-exclude
 (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
   "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
   "\\.7z$" "\\.rar$"
   "COMMIT_EDITMSG\\'"
   "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
   "-autoloads\\.el$" "autoload\\.el$"))

:config
;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
;; `recentf-save-list', allowing stale entries to be removed before the list
;; is saved by `recentf-save-list', which is automatically added to
;; `kill-emacs-hook' by `recentf-mode'.
(add-hook 'kill-emacs-hook #'recentf-cleanup -90))

(use-package savehist
:ensure nil
:commands (savehist-mode savehist-save)
:hook
(after-init . savehist-mode)
:custom
(savehist-autosave-interval 600)
(savehist-additional-variables
 '(kill-ring        ; clipboard
 register-alist       ; macros
 mark-ring global-mark-ring   ; marks
 search-ring regexp-search-ring)))

(use-package hl-line
:ensure nil
:custom
(hl-line-sticky-flag nil)
(global-hl-line-sticky-flag nil)
:hook
(after-init . global-hl-line-mode))

(use-package saveplace
:ensure nil
:commands (save-place-mode save-place-local-mode)
:hook
(after-init . save-place-mode)
:custom
(save-place-limit 400))

(use-package nerd-icons
:custom
;; disable bright icon colors
(nerd-icons-color-icons nil))hells.nix

(use-package doom-modeline
:custom
(inhibit-compacting-font-caches t)  ;; speed
(doom-modeline-buffer-file-name-style 'relative-from-project)
(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you
(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway
(doom-modeline-buffer-state-icon nil) ;; the filename already shows me
(doom-modeline-lsp nil)     ;; lsp state is too distracting, too often
:hook (after-init . doom-modeline-mode))

(load-theme 'catppuccin :no-confirm)

(use-package diminish :demand t)   ;; declutter the modeline
(use-package eldoc
:diminish eldoc-mode
:custom
(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything

(use-package eldoc-box
:defer t
:config
(set-face-background 'eldoc-box-border (catppuccin-color 'green))
(set-face-background 'eldoc-box-body (catppuccin-color 'base))
:bind
(("M-h" . eldoc-box-help-at-point)))

(use-package pulsar
:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
:init
(defface pulsar-catppuccin
`((default :extend t)
  (((class color) (min-colors 88) (background light))
 :background ,(catppuccin-color 'sapphire))
  (((class color) (min-colors 88) (background dark))
 :background ,(catppuccin-color 'sapphire))
  (t :inverse-video t))
"Alternative nord face for `pulsar-face'."
:group 'pulsar-faces)
:custom
(pulsar-face 'pulsar-catppuccin)
:hook
(after-init . pulsar-global-mode))

(use-package which-key
:commands which-key-mode
:diminish which-key-mode
:hook
(after-init . which-key-mode))

(use-package expreg
:bind ("M-m" . expreg-expand))

(use-package vundo) ;; undo tree

;; better structured editing
(use-package puni
:commands puni-global-mode
:hook
(after-init . puni-global-mode))

(use-package avy
:bind
("M-i" . avy-goto-char-2)
:custom
(avy-background t))

(use-package consult
:bind
("C-x b" . consult-buffer)   ;; orig. switch-to-buffer
("M-y"   . consult-yank-pop) ;; orig. yank-pop
("M-g M-g" . consult-goto-line)  ;; orig. goto-line
("M-g i" . consult-imenu)  ;; consult version is interactive
("M-g r" . consult-ripgrep)  ;; find in project also works
:custom
(consult-narrow-key "<"))

(use-package vertico
:commands vertico-mode
:custom
(read-file-name-completion-ignore-case t)
(read-buffer-completion-ignore-case t)
(completion-ignore-case t)
(enable-recursive-minibuffers t)
(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
:init
(vertico-mode)
:hook
(minibuffer-setup-hook . cursor-intangible-mode))

(use-package marginalia
:commands marginalia-mode
:hook (after-init . marginalia-mode))

(use-package crux
:bind
("C-c M-e" . crux-find-user-init-file)
("C-c C-w" . crux-transpose-windows)
("C-c M-d" . crux-find-current-directory-dir-locals-file)
("C-a"   . crux-move-beginning-of-line))

(use-package magit
:bind (("C-M-g" . magit-status)))

(use-package nerd-icons-corfu
:commands nerd-icons-corfu-formatter
:defines corfu-margin-formatters)

(use-package corfu
:commands global-corfu-mode
:custom
(corfu-cycle t)
(corfu-auto t)
(corfu-auto-delay  1)
(corfu-auto-prefix 3)
(corfu-separator ?_)
:hook
(after-init . global-corfu-mode)
:config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))

(use-package cape)

(use-package orderless
:custom
(completion-styles '(orderless partial-completion basic))
(completion-category-defaults nil)
(completion-category-overrides nil))

(use-package yasnippet
:commands yas-global-mode
:diminish yas-minor-mode
:hook
(after-init . yas-global-mode))

(use-package yasnippet-snippets :after yasnippet)

(use-package exec-path-from-shell
:commands exec-path-from-shell-initialize
:custom
(exec-path-from-shell-arguments nil)
:hook
(after-init . exec-path-from-shell-initialize))

(use-package nixpkgs-fmt
:custom
(nixpkgs-fmt-command "nixfmt"))

(use-package eat
:bind
(("C-c e p" . eat-project)
 ("C-c e t" . eat)))

(use-package f :demand t)

(use-package envrc
:commands envrc-global-mode
:hook
(after-init . envrc-global-mode))

(use-package gptel
:commands gptel-make-anthropic f-read-text
:config
(gptel-make-anthropic "Claude"
:stream t :key (f-read-text "/run/secrets/claude_key")))

(use-package sideline-flymake)
(use-package sideline-eglot)
(use-package sideline
:custom
(sideline-backends-right '(sideline-flymake sideline-eglot))
:hook
(eglot-managed-mode . sideline-mode)
(flymake-mode . sideline-mode))

(use-package eglot
:custom
(eglot-extend-to-xref t)
(eglot-ignored-server-capabilities '(:inlayHintProvider))
(jsonrpc-event-hook nil)
:hook
(eglot-managed-mode . eldoc-box-hover-mode)
(before-save . eldoc-format-buffer)
:bind
(:map eglot-mode-map
  ("C-c l a" . eglot-code-actions)
  ("C-c l r" . eglot-rename)
  ("C-c l h" . eldoc)
  ("C-c l g" . xref-find-references)
  ("C-c l w" . eglot-reconnect)))

(use-package proced
:custom
(proced-auto-update-flag t)
(proced-auto-update-interval 3)
(proced-enable-color-flag t)
(proced-show-remote-processes t))

(use-package org
:ensure t
:defer t
:commands (org-mode org-capture org-agenda)
:init
(defvar org-journal-file "~/nextcloud/org/journal.org")
(defvar org-archive-file "~/nextcloud/org/archive.org")
(defvar org-notes-file "~/nextcloud/org/notes.org")
(defvar org-inbox-file "~/nextcloud/org/inbox.org")
(defvar org-work-file "~/nextcloud/org/work.org")
(defun my/org-capture-project-target-heading ()
"Determine Org target headings from the current file's project path.

This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
for an Org capture template.

If the current buffer is not visi
ting a file within such a
project structure, it returns nil, causing capture to default to
the top of the file."
(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
  (let ((path-parts (split-string path "/" t " ")))
  (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
      (company  (nth (+ 1 projects-pos) path-parts))
      (project  (nth (+ 2 projects-pos) path-parts)))
  ;; Return a list of headlines for Org to find or create.
  (list company project)))))
:bind
(("C-c c" . org-capture)
 ("C-c i" . org-store-link)
 ("C-c a" . org-agenda)
 :map org-mode-map
 ("C-c t" . org-toggle-inline-images)
 ("C-c l" . org-toggle-link-display))
:custom
(org-agenda-files (list org-inbox-file org-journal-file))
(org-directory "~/nextcloud/org")
(org-default-notes-file org-inbox-file)
(org-archive-location (concat org-archive-file "::* From %s"))
(org-log-done 'time)
(org-log-into-drawer t)
(org-hide-emphasis-markers t)
(org-src-fontify-natively t)
(org-src-tab-acts-natively t)
(org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
        "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
         ("j" "Journal" entry (file+olp+datetree org-journal-file)
        "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
         ("n" "Note" entry (file org-notes-file)
        "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
         ("p" "Project Task" item
        (file+function org-work-file my/org-capture-project-target-heading)
        "* TODO %? \n  CLOCK: %U"
        ))
       )
:config
;; Enable syntax highlighting in code blocks
(add-hook 'org-mode-hook 'turn-on-font-lock)
(add-hook 'org-mode-hook 'org-indent-mode))

;; extras
(use-package comp-run
:ensure nil
:config
(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))

(use-package rustic
:custom
(rustic-lsp-client 'eglot))

(provide 'init)

;;; init.el ends here

generated/modules/apps/wofi.nix

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

{ lib, config, ... }:

let
  # Path to your  configuration assets
  wofiAssets = ../../../assets/system/conf/wofi;

  # Read the files in that directory
  wofiFiles = builtins.readDir wofiAssets;

  # Build an attribute set mapping filenames to their full paths
  wofiConfs = lib.genAttrs (builtins.attrNames wofiFiles) (name: {
    src = "${wofiAssets}/${name}";
  });

  # Toggle for enabling Wofi
  enableWofi = true;
in
{
  # Module option to enable/disable Wofi
  options.enableWofi = lib.mkEnableOption "Enable Wofi terminal launcher";

  # Everything in config is wrapped safely with mkIf
  config = lib.mkIf enableWofi {
    # Use mySystem as a container for all your programs
    mySystem = {
      wofi = {
        enable = true;
        assetsDir = wofiAssets;
        files = wofiConfs;

        # Example: you could reference a top-level user option
        user = config.defaultUser or "henrov";
      };
    };
  };
}