56 KiB
Droidnix: A Dendritic NixOS + Home Manager Configuration NixOS Configuration Structure
- Shortcuts
- Introduction
- Root Level
- Generated Structure
- The Assets Folder
- The Actual Code
- Let's define the core of the system
generated/hosts/traveldroid/core.nixgenerated/hosts/traveldroid/locale.nixgenerated/hosts/traveldroid/networking.nixgenerated/hosts/traveldroid/services.nixgenerated/hosts/traveldroid/users/user.nixgenerated/hosts/traveldroid/users/henrov.nixgenerated/hosts/traveldroid/homebase.nixgenerated/hosts/traveldroid/nix.nixgenerated/hosts/traveldroid/boot.nix
- First the nix-files that flake really needs and that do not fit wel in the hierarchical structure
generated/hosts/traveldroid/traveldroid.nixgenerated/hosts/traveldroid/hardware-configuration.nixgenerated/hosts/traveldroid/dbus.nixgenerated/hosts/traveldroid/bluetooth.nixgenerated/hosts/traveldroid/xdg.nixgenerated/modules/desktop/stylix.nixgenerated/hosts/traveldroid/terminal.nixgenerated/modules/desktop/rotating_wallpaper.nixgenerated/modules/desktop/hyprland.nixgenerated/modules/apps/zenbrowser.nixgenerated/modules/apps/packages.nixgenerated/modules/apps/flatpaks.nixgenerated/hosts/traveldroid/gtk.nixgenerated/modules/desktop/fonts.nixgenerated/modules/desktop/eww.nixgenerated/modules/desktop/waybar.nixgenerated/hosts/traveldroid/login-tuigreeter.nixgenerated/modules/desktop/wayland.nixgenerated/modules/apps/thunar.nixgenerated/modules/terminals/kitty.nixgenerated/modules/terminals/starship.nixgenerated/modules/terminals/zsh.nixgenerated/modules/apps/emacs/emacs.nixgenerated/modules/apps/emacs/init.elgenerated/modules/apps/wofi.nix
Shortcuts
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:
.assets/: Static, non-generated files (e.g., configs, scripts, themes).- Generated folders (
system,hyprland,mangowc): NixOS and Home Manager configurations, generated from Org files.
Root Level
-
flake.nixis 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
- Clone this repository.
- Run the setup script:
./setup_droid. - Edit
.assets/system/conf/base.confto choose your window manager (wm = "hyprland"orwm = "mangowc"). - Tangle this Org file to generate Nix configurations:
C-c C-v tin 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 - 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,
self,
nixpkgs,
home-manager,
emacs-overlay,
zen-browser,
hyprland,
stylix,
import-tree,
...
}:
flake-parts.lib.mkFlake { inherit inputs; } {
# Declare supported systems for flake-parts
systems = [ "x86_64-linux" ];
# Import dendritic/flake modules here
imports = [
(import-tree ./generated/modules) # Only mySystem.* stuff
];
# Define NixOS configurations for hosts
flake = {
nixosConfigurations.traveldroid =
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
# Host-specific configuration (NixOS context)
./generated/hosts/traveldroid/traveldroid.nix
# Boot configuration (NixOS context)
./generated/hosts/traveldroid/boot.nix
# Stylix NixOS module
stylix.nixosModules.default
];
};
};
};
}
Let's define the core of the system
generated/hosts/traveldroid/core.nix
{ lib, config, ... }:
let
cfg = config.mySystem.system.core;
in
{
options.mySystem.system.core.enable =
lib.mkEnableOption "Core System Settings";
imports = [
./locale.nix
./networking.nix
./services.nix
./users/user.nix
./homebase.nix
./nix.nix
./boot.nix
];
config = lib.mkIf cfg.enable {
# alleen echt "core-specifieke" dingen hier
nixpkgs.config.allowUnfree = true;
};
}
generated/hosts/traveldroid/locale.nix
{ lib, config, ... }:
let
coreEnabled = config.mySystem.system.core.enable or false;
in
{
options.mySystem.system.locale.enable =
lib.mkEnableOption "Locale settings";
config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {
time.timeZone = "Europe/Amsterdam";
i18n.defaultLocale = "nl_NL.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "nl_NL.UTF-8";
LC_IDENTIFICATION = "nl_NL.UTF-8";
LC_MEASUREMENT = "nl_NL.UTF-8";
LC_MONETARY = "nl_NL.UTF-8";
LC_NAME = "nl_NL.UTF-8";
LC_NUMERIC = "nl_NL.UTF-8";
LC_PAPER = "nl_NL.UTF-8";
LC_TELEPHONE = "nl_NL.UTF-8";
LC_TIME = "nl_NL.UTF-8";
};
};
}
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 = "25.11";
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 = "25.11";
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 = "25.11";
};
};
};
}
generated/hosts/traveldroid/nix.nix
{ lib, config, ... }:
let
coreEnabled = config.mySystem.system.core.enable or false;
in
{
options.mySystem.system.locale.enable =
lib.mkEnableOption "Flake & Nix settings";
config = lib.mkIf (coreEnabled || config.mySystem.system.locale.enable) {
# --- Flakes & Nix Settings ---
nix.settings = {
experimental-features = [ "nix-command" "flakes" ];
download-buffer-size = 536870912; # 512 MB
cores = 2;
max-jobs = 1;
};
};
}
generated/hosts/traveldroid/boot.nix
# ./generated/hosts/traveldroid/traveldroid.nix
{ config, pkgs, lib, ... }:
let
coreEnabled = config.mySystem.system.core.enable or false;
in lib.mkIf coreEnabled {
boot = {
initrd = {
verbose = false;
kernelModules = [ ];
};
extraModulePackages = [ ];
kernelPackages = pkgs.linuxPackages_latest;
kernelParams = [ "silent" ];
consoleLogLevel = 0;
plymouth.enable = true;
supportedFilesystems = [ "ntfs" ];
loader = {
systemd-boot.enable = true;
systemd-boot.configurationLimit = 10;
efi.canTouchEfiVariables = true;
timeout = 5;
};
};
}
First the nix-files that flake really needs and that do not fit wel in the hierarchical structure
generated/hosts/traveldroid/traveldroid.nix
{ inputs, config, ... }:
{
flake.nixosConfigurations."traveldroid" = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules =
[
inputs.home-manager.nixosModules.home-manager
inputs.stylix.nixosModules.stylix
] ++
(builtins.attrValues config.flake.nixosModules) ++
[
./hardware-configuration.nix
({ ... }: {
networking.hostName = "traveldroid";
system.stateVersion = "25.11";
boot = {
loader = {
grub = {
enable = true;
efiSupport = true;
device = "nodev";
useOSProber = true;
};
efi.canTouchEfiVariables = true;
};
# initrd.systemd.tpm2.enable = false;
kernelParams = [
"systemd.mask=dev-tpm0.device"
"systemd.mask=dev-tpmrm0.device"
];
};
# systemd.tpm2.enable = false;
# Enable various user-defined modules
mySystem = {
# Turn on the core system
system.core.enable = true;
# Hardware-specific modules
hardware.nvidia.enable = false;
# Define Environment
desktop = {
hyprland.enable = true;
noctalia.enable = true;
stylix.enable = true;
};
};
})
];
};
}
generated/hosts/traveldroid/hardware-configuration.nix
- Boot into NixOS Live ISO or your installed system.
- Open a terminal.
- 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, pkgs, flakeRoot, ... }:
let
username = "henrov";
in
{
flake.nixosModules.stylix = { config, pkgs, lib, ... }:
let
# --- Default stylix config ---
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
{
options.mySystem.desktop.stylix.enable =
lib.mkEnableOption "Enable Stylix System Theming";
config = lib.mkIf (stylixCfg.enable or false) {
# --- Desktop / wallpaper packages ---
mySystem.apps.wallpaper = {
enable = true;
packages = [ "feh" "st" ];
};
# --- Stylix theming ---
stylix = stylixCfg;
# --- Home session variables ---
home-manager.users.${username}.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 context
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, pkgs, flakeRoot, ... }:
let
# --- Define user locally ---
username = "henrov";
# --- Hyprland conf directory ---
hyprConfDir = "${flakeRoot}/assets/hyprland/conf/hypr";
# --- Read files ---
hyprlandFiles = builtins.attrNames (builtins.readDir hyprConfDir);
# --- Exclude main hyprland.conf from automatic symlinks ---
otherHyprlandFiles = lib.filter (name: name != "hyprland.conf") hyprlandFiles;
# --- Generate xdg.configFile entries for the other files ---
otherConfigs = lib.genAttrs otherHyprlandFiles (name: {
target = "hypr/${name}";
source = "${hyprConfDir}/${name}";
});
# --- Add main hyprland.conf separately ---
hyprlandConf = {
"hypr/hyprland.conf".text = builtins.readFile "${hyprConfDir}/hyprland.conf";
"hypr/.keep".text = "";
};
in
{
flake.nixosModules.hyprland = { config, pkgs, lib, ... }:
{
options.mySystem.desktop.hyprland.enable =
lib.mkEnableOption "Enable Hyprland Desktop";
config = lib.mkIf (config.mySystem.desktop.hyprland.enable or false) {
programs.hyprland.enable = true;
home-manager.users.${username} = {
home.stateVersion = "25.11";
home.username = username;
home.homeDirectory = "/home/${username}";
wayland.windowManager.hyprland = {
enable = true;
settings.general."col.active_border" = lib.mkForce "0xff97cbcd 0xff89b4fa";
};
xdg.configFile = otherConfigs // hyprlandConf;
};
};
};
}
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
# ./generated/modules/apps/zenbrowser.nix
{ config, pkgs, lib, ... }:
let
username = "henrov"; # optional, if you want user-specific stuff
in
{
# Declare a module option for enabling Zen Browser
options.mySystem.apps.zenBrowser.enable =
lib.mkEnableOption "Enable Zen Browser";
# Declare a module option for the package reference
options.mySystem.apps.zenBrowser.packageRef =
lib.mkOption {
type = lib.types.str;
default = "zen-browser";
description = "Package reference for Zen Browser";
};
# Apply the configuration if the module is enabled
config = lib.mkIf (config.mySystem.apps.zenBrowser.enable) {
# Add the package to systemPackages
environment.systemPackages = [
pkgs.${config.mySystem.apps.zenBrowser.packageRef}
];
};
}
generated/modules/apps/packages.nix
This will import all packages listed in ./assets/system/apps/packages.conf
{ lib, ... }:
let
# --- Path naar je packages.conf, relatief aan dit bestand ---
packagesConfPath = ./assets/system/apps/packages.conf;
# --- Lees en split ---
raw = builtins.readFile packagesConfPath;
rawLines = lib.splitString "\n" raw;
_guard = assert !(builtins.stringLength raw > 1 &&
builtins.length rawLines == builtins.stringLength raw); true;
cleanLine = line:
let
noCR = lib.replaceStrings [ "\r" ] [ "" ] line;
noComment = lib.head (lib.splitString "#" noCR);
in
lib.strings.trim noComment;
entries = builtins.filter (l: l != "") (map cleanLine rawLines);
in
{
# --- Flake NixOS module export ---
flake.nixosModules.packages = { config, pkgs, lib, ... }:
let
# Resolve packages via pkgs
resolvePkg = name:
let
parts = lib.splitString "." name;
found = lib.attrByPath parts null pkgs;
in
if found == null then
throw ''
packages.nix: package not found in pkgs
Token : ${builtins.toJSON name}
packages.conf : ${toString packagesConfPath}
''
else
found;
packages = builtins.seq _guard (map resolvePkg entries);
in
{
options.mySystem.system.packages.enable = lib.mkEnableOption "Enable packages from packages.conf";
config = lib.mkIf (config.mySystem.system.packages.enable or false) {
environment.systemPackages = packages;
};
};
}
generated/modules/apps/flatpaks.nix
This will import all packages listed in ./assets/system/apps/flatpaks.conf
{ lib, ... }:
let
moduleName = "install-flatpaks";
# --- Relatief pad binnen deze module (geen flakeRoot) ---
flatpakConfPath = ./assets/system/apps/flatpaks.conf;
# --- Lees en split het bestand ---
raw = builtins.readFile flatpakConfPath;
rawLines = lib.splitString "\n" raw;
# --- Guard: check dat we niet per karakter hebben gesplit ---
_guard =
assert !(builtins.stringLength raw > 1 && builtins.length rawLines == builtins.stringLength raw);
true;
# --- Cleanup per regel ---
cleanLine = line:
let
noCR = lib.replaceStrings [ "\r" ] [ "" ] line;
noInlineComment = lib.head (lib.splitString "#" noCR);
in
lib.strings.trim noInlineComment;
entries = builtins.filter (l: l != "") (map cleanLine rawLines);
# --- Validatie: min 2 dots (reverse-DNS stijl) ---
dotCount = s: builtins.length (lib.splitString "." s) - 1;
isValidId = s: (dotCount s) >= 2;
_validate = builtins.seq _guard (
builtins.map (id:
if isValidId id then true
else throw ''
${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots)
Token : ${builtins.toJSON id}
flatpaks.conf : ${toString flatpakConfPath}
Fix: remove stray tokens or comment them out with '#'.
''
) entries
);
flatpakApps = builtins.seq _validate entries;
in
{
# --- Export as NixOS module via flake.nixosModules ---
flake.nixosModules.flatpaks = { config, pkgs, lib, ... }:
let
syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" ''
set -euo pipefail
CONF="/etc/flatpak/flatpaks.conf"
if [[ -f "$CONF" ]]; then
echo "flatpak-sync: using $CONF"
else
echo "flatpak-sync: WARNING: $CONF not found, using embedded list"
fi
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
desired_apps=(
${lib.concatStringsSep " " (map (a: ''"${a}"'') flatpakApps)}
)
for app in $desired_apps; do
if ! flatpak info --system "$app" >/dev/null 2>&1; then
flatpak install --system -y --noninteractive flathub "$app"
fi
done
'';
in
{
options.mySystem.system.flatpaks.enable = lib.mkEnableOption "Enable automatic Flatpak installation";
config = lib.mkIf (config.mySystem.system.flatpaks.enable or false) {
services.flatpak.enable = true;
xdg.portal.enable = true;
# Deploy de conf voor runtime/debug
environment.etc."flatpak/flatpaks.conf".source = lib.mkForce flatpakConfPath;
# Systemd service voor automatische installatie
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 = syncFlatpaks;
};
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, ... }:
{
flake.nixosModules.fonts =
{
config,
pkgs,
lib,
...
}:
{
options.mySystem.desktop.fonts.enable = lib.mkEnableOption "Enable system fonts";
config = lib.mkIf (config.mySystem.desktop.fonts.enable or false) {
fonts.packages = with pkgs; [
nerd-fonts.iosevka
nerd-fonts.fira-code
];
};
};
}
generated/modules/desktop/eww.nix
This file installs and configures eww
{ lib, pkgs, flakeRoot, ... }:
let
# --- Define user locally ---
username = "henrov";
# --- Eww config directory in flake ---
ewwAssetsDir = "${flakeRoot}/assets/system/conf/eww";
# --- Read all files in ewwAssetsDir dynamically ---
ewwFiles = builtins.attrNames (builtins.readDir ewwAssetsDir);
# --- Generate xdg.configFile entries for all files ---
ewwConfigs = lib.genAttrs ewwFiles (name: {
text = builtins.readFile "${ewwAssetsDir}/${name}";
});
# --- Full config directory path in user's config home ---
ewwConfigDir = "/home/${username}/.config/eww";
in
{
flake.nixosModules.eww = { config, pkgs, lib, ... }:
{
options.mySystem.apps.eww.enable =
lib.mkEnableOption "Enable Eww widgets";
config = lib.mkIf (config.mySystem.apps.eww.enable or false) {
mySystem = {
apps.wallpaper = {
enable = true;
packages = [ "eww" ]; # symbolic, actual package below
};
};
# --- Home Manager user config ---
home-manager.users.${username} = {
home.stateVersion = "25.11";
home.username = username;
home.homeDirectory = "/home/${username}";
# Deploy eww configs
home.file."${ewwConfigDir}" = {
source = ewwAssetsDir;
recursive = true;
};
# Session variables
home.sessionVariables = {
EWW_BIN = "${pkgs.eww}/bin/eww";
};
# Wayland/Hyprland startup hooks
wayland.windowManager.hyprland.settings = lib.mkForce {
exec-once = [ "eww daemon" ];
exec = [ "eww open-many ${ewwConfigDir}/widgets" ];
};
};
};
};
}
generated/modules/desktop/waybar.nix
This file installs and configures waybar
{ lib, pkgs, config, flakeRoot, ... }:
let
username = "henrov";
waybar-config = pkgs.writeText "waybar-config" (builtins.readFile (flakeRoot + "/assets/system/conf/waybar/config"));
waybar-style = pkgs.writeText "waybar-style" (builtins.readFile (flakeRoot + "/assets/system/conf/waybar/style.css"));
in
{
programs.waybar = {
enable = true;
package = pkgs.waybar;
};
systemd.user.services.waybar = {
description = "Waybar (status bar for Wayland)";
wantedBy = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${config.programs.waybar.package}/bin/waybar -c ${waybar-config} -s ${waybar-style}";
Restart = "on-failure";
RestartSec = "5s";
};
};
# Create symlinks for config and style
system.activationScripts.waybarSetup = lib.mkAfter ''
mkdir -p /home/${username}/.config/waybar
ln -sf ${waybar-config} /home/${username}/.config/waybar/config
ln -sf ${waybar-style} /home/${username}/.config/waybar/style.css
chown -R ${username}:users /home/${username}/.config/waybar
'';
}
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, ... }:
{
flake.nixosModules.wayland = { config, pkgs, lib, ... }:
let
username = "henrov"; # <-- simpel en stabiel
in
{
options.mySystem.desktop.wayland.enable =
lib.mkEnableOption "Enable Wayland + portals";
config = lib.mkIf (config.mySystem.desktop.wayland.enable or false) {
home-manager.users.${username} = {
xdg.portal = {
enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-hyprland
];
config.hyprland = {
"org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
};
};
home.packages = with 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, ... }:
let
username = "henrov"; # vervang door je echte gebruikersnaam
in
{
flake.nixosModules.thunar = { config, pkgs, lib, ... }:
{
options.mySystem.apps.thunar.enable =
lib.mkEnableOption "Enable Thunar file manager";
config = lib.mkIf (config.mySystem.apps.thunar.enable or false) {
# --- Home Manager gebruiker ---
home-manager.users.${username} = {
home.stateVersion = "25.11";
home.username = username;
home.homeDirectory = "/home/${username}";
# --- Thunar en plugins ---
home.packages = with pkgs; [
thunar
thunar-volman
thunar-archive-plugin
thunar-media-tags-plugin
tumbler
ffmpegthumbnailer
gvfs
xdg-utils
];
# --- Default file manager ---
xdg.mimeApps = {
defaultApplications = {
"inode/directory" = "Thunar.desktop";
};
};
};
};
};
}
generated/modules/terminals/kitty.nix
This file sets up Kitty terminal
{ lib, ... }:
{
flake.nixosModules.kitty = { config, pkgs, lib, ... }:
let
kittyConf = ./assets/system/conf/kitty/kitty.conf;
kittyTheme = ./assets/system/conf/kitty/Catppuccin-Mocha.conf;
username = "henrov";
in
{
options.mySystem.terminals.kitty.enable =
lib.mkEnableOption "Enable Kitty terminal";
config = lib.mkIf (config.mySystem.terminals.kitty.enable or false) {
home-manager.users.${username} = {
programs.kitty.enable = true;
xdg.configFile."kitty/kitty.conf".source = kittyConf;
xdg.configFile."kitty/Catppuccin-Mocha.conf".source = kittyTheme;
};
};
};
}
generated/modules/terminals/starship.nix
This file sets up starship prompt
{
lib,
config,
pkgs,
flakeRoot,
...
}:
let
starshipConfig = lib.importTOML (flakeRoot + "/assets/system/conf/starship.toml");
in
{
programs.starship = {
enable = true;
settings = starshipConfig;
};
}
generated/modules/terminals/zsh.nix
This sets up the zsh in the terminal
# terminals/zsh.nix
{ lib, pkgs, ... }:
let
username = "henrov";
in
{
# Export as a flake module
zsh = { config, pkgs, lib, ... }: {
options.mySystem.terminals.zsh.enable =
lib.mkEnableOption "Enable Zsh terminal with Oh-My-Zsh";
config = lib.mkIf (config.mySystem.terminals.zsh.enable or false) {
home-manager.users.${username} = {
programs.zsh.enable = true;
programs.zsh.enableCompletion = true;
programs.zsh.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
];
};
programs.zsh.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 [ -f ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]; then
source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
fi
'';
};
};
};
}
generated/modules/apps/emacs/emacs.nix
This sets up the emacs terminal
{ 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";
};
};
};
};
}#+END_SRC
** =generated/modules/apps/emacs/early-init.el=
This helps set up the emacs terminal
#+BEGIN_SRC nix :tangle generated/modules/apps/emacs/early-init.el :noweb tangle :mkdirp yes :eval never-html
;;; 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, flakeRoot, ... }:
let
wofiAssets = "${flakeRoot}/assets/system/conf/wofi";
wofiFiles = builtins.readDir wofiAssets;
wofiConfs = lib.genAttrs (builtins.attrNames wofiFiles) (name: {
src = "${wofiAssets}/${name}";
});
in
{
mySystem = {
apps.wofi = {
enable = true;
# symbolic references to files
configFile = wofiConfs."wofi.conf".src;
styleFile = wofiConfs."theming.css".src;
};
};
}