sudo nixos-generate-config --root /mnt (Omit --root /mnt if already running NixOS.)
#+BEGIN_SRC nix :tangle generated/hosts/traveldroid/hardware-configuration.nix :noweb yes :mkdirp yes :eval never
{
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;
}
#+END_SRC
** =generated/hosts/traveldroid/host.nix=
#+BEGIN_SRC nix :tangle generated/hosts/traveldroid/host.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, import-tree, home-manager, ... }:
let
hostname = "traveldroid";
modulesPath = "${flakeRoot}/generated/modules/${hostname}";
hostModules = import-tree modulesPath;
allModules = hostModules.imports;
in
{
networking.hostName = hostname;
system.stateVersion = "26.05";
#################################
# Locale
#################################
i18n = {
defaultLocale = "nl_NL.UTF-8";
extraLocales = [
"nl_NL.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
];
consoleKeyMap = "us";
};
time.timeZone = "Europe/Amsterdam";
#################################
# Imports
#################################
imports =
[ ../../../generated/users/henrov.nix
./boot.nix
./hardware-configuration.nix
]
++ allModules
++ [ home-manager.nixosModules.home-manager ];
#################################
# Home Manager integration
#################################
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
environment.systemPackages = [
pkgs.dconf
];
programs.dconf.enable = true;
}
#+END_SRC
* generated/traveldroid/modules/apps
** =generated/modules/traveldroid/apps/2_b_installed.nix=
This installs a list of apps
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/2_b_installed.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
#################################
# FILE
#################################
confPath = "${flakeRoot}/generated/assets/2_b_installed.conf";
raw = builtins.readFile confPath;
lines = lib.splitString "\n" raw;
#################################
# CLEAN LINE
#################################
cleanLine = line:
let
noCR = lib.replaceStrings [ "\r" ] [ "" ] line;
noInlineComment = lib.head (lib.splitString "#" noCR);
in
lib.strings.trim noInlineComment;
#################################
# PARSE SECTION
#################################
parseSection = section:
let
result =
builtins.foldl'
(acc: line:
let
l = lib.strings.trim line;
in
if l == section then
acc // { active = true; }
else if lib.hasPrefix "#" l then
acc // { active = false; }
else if acc.active then
acc // { entries = acc.entries ++ [ l ]; }
else
acc
)
{ active = false; entries = []; }
lines;
in
builtins.filter (l: l != "") (map cleanLine result.entries);
#################################
# NIX PACKAGES
#################################
packageEntries = parseSection "#packages";
resolvePkg = name:
let
parts = lib.splitString "." name;
found = lib.attrByPath parts null pkgs;
in
if found == null then
throw ''
packages.nix: package not found
Token: ${name}
File : ${confPath}
''
else
found;
packages = map resolvePkg packageEntries;
#################################
# FLATPAKS
#################################
flatpakEntries = parseSection "#flatpaks";
in {
#################################
# Allow unfree
#################################
nixpkgs.config.allowUnfree = true;
#################################
# System packages (Nix)
#################################
environment.systemPackages = packages;
#################################
# Flatpak setup
#################################
services.flatpak.enable = true;
services.flatpak.remotes = [
{
name = "flathub";
location = "https://flathub.org/repo/flathub.flatpakrepo";
}
];
#################################
# Flatpak apps
#################################
services.flatpak.packages = flatpakEntries;
}
#+END_SRC
** =generated/modules/traveldroid/apps/emacs/emacs.nix=
This installs emacs
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/emacs/emacs.nix :noweb yes :mkdirp yes :eval never
{ config, pkgs, lib, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
assetPath = "${flakeRoot}/generated/.config/emacs";
# Emacs package with Tree-sitter support
emacsPkg = pkgs.emacs-pgtk.override { withTreeSitter = true; };
# Extra packages for Emacs via Home Manager
emacsExtraPackages = epkgs: [
epkgs.manualPackages.treesit-grammars.with-all-grammars
epkgs.nerd-icons
epkgs.doom-modeline
epkgs.diminish
epkgs.eldoc
epkgs.pulsar
epkgs.which-key
epkgs.expreg
epkgs.vundo
epkgs.puni
epkgs.avy
epkgs.consult
epkgs.vertico
epkgs.marginalia
epkgs.crux
epkgs.magit
epkgs.nerd-icons-corfu
epkgs.corfu
epkgs.cape
epkgs.orderless
epkgs.yasnippet
epkgs.yasnippet-snippets
epkgs.rg
epkgs.exec-path-from-shell
epkgs.eat
epkgs.rust-mode
epkgs.rustic
epkgs.nix-mode
epkgs.hcl-mode
epkgs.shell-pop
epkgs.envrc
epkgs.nixpkgs-fmt
epkgs.f
epkgs.gptel
epkgs.catppuccin-theme
epkgs.eldoc-box
epkgs.sideline
epkgs.sideline-flymake
epkgs.sideline-eglot
];
in
{
# System-wide installation
environment.systemPackages = [
emacsPkg
];
# Home Manager user-specific configuration for your default user
home-manager.users = {
${username} = {
home.sessionVariables = {
EDITOR = "emacs";
XDG_SCREENSHOTS_DIR = "~/screenshots";
};
programs.emacs = {
enable = true;
package = emacsPkg;
extraPackages = emacsExtraPackages;
};
home.file = {
".emacs.d/early-init.el" = {
source = "${assetPath}/early-init.el";
force = true; # <-- allow overwrite
};
".emacs.d/init.el" = {
source = "${assetPath}/init.el";
force = true; # <-- allow overwrite
};
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/apps/flameshot.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
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/flameshot.nix :noweb yes :mkdirp yes :eval never
{ pkgs, config, lib, ... }:
let
username = config.defaultUser or "henrov";
in
{
############################
# System-level packages
############################
environment.systemPackages = with pkgs; [
flameshot
];
############################
# Home Manager user-level configuration
############################
home-manager.users."${username}" = {
home.sessionVariables = {
SCREENSHOT_TOOL = "flameshot";
USERNAME = username;
};
# Create ~/Pictures/Screenshots by touching a dummy file
home.file."Pictures/Screenshots/.keep" = {
text = ""; # empty file
};
services.flameshot = {
enable = true;
settings = {
General = {
uiColor = "#97cbbe";
contrastUiColor = "#1e1e2e";
showDesktopNotification = true;
savePath = "/home/${username}/Pictures/Screenshots";
filenamePattern = "$Y-$m-$d_$H-$M-$S";
useGrimAdapter = true;
};
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/apps/kdeconnect.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
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/kdeconnect.nix :noweb yes :mkdirp yes :eval never
# --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. ---
{ config, pkgs, ... }:
let
username = config.defaultUser or "henrov";
in
{
environment.systemPackages = with pkgs; [
kdePackages.kdeconnect-kde
];
systemd.user.services.kdeconnect = {
enable = true;
description = "KDE Connect daemon";
wantedBy = ["default.target"];
serviceConfig = {
ExecStart = "${pkgs.kdePackages.kdeconnect-kde}/bin/kdeconnectd";
Restart = "on-failure";
};
};
}
#+END_SRC
** =generated/modules/traveldroid/apps/kitty.nix=
This file sets up Kitty terminal
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/kitty.nix :noweb yes :mkdirp yes :eval never
{ lib, pkgs, config, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
extraConfigFile = "${flakeRoot}/generated/.config/kitty/extra.conf";
extraConfig =
if builtins.pathExists extraConfigFile
then builtins.readFile extraConfigFile
else "";
in
{
#################################
# System-wide install
#################################
environment.systemPackages = [
pkgs.kitty
];
#################################
# Home Manager
#################################
home-manager.users = {
"${username}" = {
programs.kitty = {
enable = true;
settings = {
confirm_os_window_close = lib.mkForce 0;
dynamic_background_opacity = lib.mkForce true;
enable_audio_bell = lib.mkForce false;
mouse_hide_wait = lib.mkForce "-1.0";
window_padding_width = lib.mkForce 10;
background_opacity = lib.mkForce "0.5";
background_blur = lib.mkForce 5;
};
extraConfig = ''
${extraConfig}
# Theme
include themes/Catppuccin-Mocha.conf
'';
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/apps/starship.nix=
This file sets up starship prompt
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/starship.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
# Default username fallback
username = config.defaultUser or "henrov";
# Path to the starship config in assets
starshipConfSrc = "${flakeRoot}/generated/.config/starship.toml";
in
{
#################################
# Install Starship system-wide
#################################
environment.systemPackages = [ pkgs.starship ];
#################################
# Home Manager user configuration
#################################
home-manager.users = {
${username} = {
home.file = {
".config/starship.toml" = {
text = builtins.readFile "${starshipConfSrc}";
force = true;
};
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/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
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/thunar.nix :noweb yes :mkdirp yes :eval never
{ pkgs, config, lib, ... }:
let
# Resolve the default username from host config
username = config.defaultUser or "henrov";
in
{
############################
# System-level packages
############################
environment.systemPackages = with pkgs; [
thunar # main file manager
thunar-archive-plugin # zip, tar, rar, 7z support
thunar-volman # auto-mount removable drives
gvfs # support for external drives and network shares
xarchiver # optional GUI archive manager
tumbler # Showing thumbnails
libmtp
mtpfs
jmtpfs
];
############################
# Home Manager user-level configuration
############################
# Direct assignment to the user avoids recursiveUpdate issues
home-manager.users."${username}" = {
home.stateVersion = "26.05"; # required
home.sessionVariables = {
FILE_MANAGER = "thunar";
USERNAME = username;
};
};
# Enable gvfs as a service
services.gvfs.enable = true;
}
#+END_SRC
** =generated/modules/traveldroid/apps/wofi.nix=
This is the install for Wofi, the launcher
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/wofi.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
assetPath = "${flakeRoot}/generated/.config/wofi";
in
{
environment.systemPackages = [ pkgs.wofi ];
home-manager.users = {
${username} = {
home.file = {
".config/wofi/config" = {
text = builtins.readFile "${assetPath}/config";
force = true;
};
".config/wofi/style.css" = {
text = builtins.replaceStrings ["PLACEHOLDER_USERNAME"] [username] (builtins.readFile "${assetPath}/style.css");
force = true;
};
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/apps/zenbrowser.nix=
This installs zen browser
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/zenbrowser.nix :noweb yes :mkdirp yes :eval never
{ config, pkgs, lib, zen-browser, ... }:
let
# Grab the Zen Browser package for this host system
zenBrowser = zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
{
environment.systemPackages = [
zenBrowser
];
}
#+END_SRC
** =generated/modules/traveldroid/apps/zsh.nix=
This sets up the zsh in the terminal
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/apps/zsh.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
#################################
# User config
#################################
username = config.defaultUser or "henrov";
generatedZsh = "${flakeRoot}/generated/.config/zsh/.zshrc";
#################################
# Alias parsing
#################################
aliasFile = "${flakeRoot}/generated/assets/aliases.conf";
content = builtins.readFile aliasFile;
lines =
lib.filter (l: l != "")
(map (l:
let
noComment = builtins.head (lib.splitString "#" l);
in lib.trim noComment
) (lib.splitString "\n" content));
parseLine = line:
let
parts = lib.splitString "=" line;
in
if lib.length parts < 2 then null else {
name = lib.trim (lib.head parts);
value = lib.trim (lib.concatStringsSep "=" (lib.tail parts));
};
parsed =
lib.filter (x: x != null)
(map parseLine lines);
functions =
lib.concatStringsSep "\n"
(map (x: ''
${x.name}() {
${x.value} "$@"
}
'') parsed);
in
{
#################################
# Packages
#################################
environment.systemPackages = with pkgs; [
zsh
oh-my-zsh
starship
zsh-syntax-highlighting
];
#################################
# Zsh config location
#################################
environment.etc."zshenv".text = ''
export ZDOTDIR=$HOME/.config/zsh
'';
#################################
# Generated alias functions (system-wide)
#################################
environment.etc."profile.d/99-alias-functions.sh".text = ''
# system-wide functions generated from aliases.conf
${functions}
'';
#################################
# Global zshrc
#################################
environment.etc."zshrc".text = ''
export ZSH=${pkgs.oh-my-zsh}/share/oh-my-zsh
ZSH_THEME=""
plugins=(git sudo extract colored-man-pages command-not-found history docker kubectl)
source $ZSH/oh-my-zsh.sh
# Init starship FIRST (prompt)
eval "$(starship init zsh)"
# Load alias functions
if [ -f /etc/profile.d/99-alias-functions.sh ]; then
source /etc/profile.d/99-alias-functions.sh
fi
# Load optional generated user config
[ -f "${generatedZsh}" ] && source "${generatedZsh}"
# Syntax highlighting MUST be last
source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
'';
#################################
# Home Manager integration
#################################
home-manager.users.${username} = {
programs.zsh.enable = true;
home.file.".config/zsh/.zshrc".source = generatedZsh;
};
}
#+END_SRC
* generated/modules/traveldroid/desktop
** =generated/modules/traveldroid/desktop/fonts.nix=
This file installs and configures fonts
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/fonts.nix :noweb yes :mkdirp yes :eval never
{ lib, pkgs, config, ... }:
{
fonts.packages = with pkgs; [
nerd-fonts.iosevka
nerd-fonts.fira-code
nerd-fonts.jetbrains-mono
];
}
#+END_SRC
** =generated/modules/traveldroid/desktop/gtk.nix=
Setting up GTK
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/gtk.nix :noweb yes :mkdirp yes :eval never
{ pkgs, config, lib, ... }:
let
username = config.defaultUser or "henrov";
in
{
environment.systemPackages = with pkgs; [
gtk3
gtk4
];
home-manager.users."${username}" = {
gtk = {
enable = true;
};
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/hyprland.nix=
Setting up Hyprland
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/hyprland.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, home-manager, inputs, ... }:
let
username = config.defaultUser or "henrov";
assetPath = "${flakeRoot}/generated/.config/hypr";
hyprlandPkg =
pkgs.hyprland or
pkgs.hyprland-git or
inputs.hyprland.packages.${pkgs.system}.default;
in
{
# Install Hyprland systemwide
environment.systemPackages = [ hyprlandPkg ];
# Home Manager user configuration
home-manager.users = {
${username} = {
home.file = {
".config/hypr/animations.conf" = { source = "${assetPath}/animations.conf"; force = true; };
".config/hypr/behaviour.conf" = { source = "${assetPath}/behaviour.conf"; force = true; };
".config/hypr/bindings.conf" = { source = "${assetPath}/bindings.conf"; force = true; };
".config/hypr/exec-once.conf" = { source = "${assetPath}/exec-once.conf"; force = true; };
".config/hypr/hypridle.conf" = { source = "${assetPath}/hypridle.conf"; force = true; };
".config/hypr/hyprland.conf" = { source = "${assetPath}/hyprland.conf"; force = true; };
".config/hypr/hyprlock.conf" = { source = "${assetPath}/hyprlock.conf"; force = true; };
".config/hypr/layer-rules.conf" = { source = "${assetPath}/layer-rules.conf"; force = true; };
".config/hypr/layout.conf" = { source = "${assetPath}/layout.conf"; force = true; };
".config/hypr/monitor-rules.conf" = { source = "${assetPath}/monitor-rules.conf"; force = true; };
".config/hypr/theming.conf" = { source = "${assetPath}/theming.conf"; force = true; };
".config/hypr/window-rules.conf" = { source = "${assetPath}/window-rules.conf"; force = true; };
".config/hypr/workspace-rules.conf" = { source = "${assetPath}/workspace-rules.conf"; force = true; };
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/stylix.nix=
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/stylix.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, stylix, ... }:
let
username = config.defaultUser or "henrov";
moduleName = "stylix";
assetPath = "${flakeRoot}/generated/.config/${moduleName}";
stylixConfFile = "${assetPath}/stylix.conf";
stylixConf =
if builtins.pathExists stylixConfFile
then builtins.readFile stylixConfFile
else "";
cursorName = "phinger-cursors-light";
cursorSize = 24;
in
{
#################################
# Enable Stylix module
#################################
imports = [
stylix.nixosModules.stylix
];
#################################
# System packages
#################################
environment.systemPackages = [
pkgs.feh
pkgs.st
];
#################################
# Stylix system config
#################################
stylix = {
enable = true;
base16Scheme = "${flakeRoot}/assets/traveldroid/theming/stylix/catppuccin-mocha.yaml";
polarity = "dark";
targets = {
gtk.enable = true;
qt.enable = true;
};
cursor = {
name = cursorName;
package = pkgs.phinger-cursors;
size = cursorSize;
};
};
#################################
# Home Manager
#################################
home-manager.users = {
"${username}" = {
#################################
# ONLY custom file (safe)
#################################
home.file.".config/stylix/stylix.conf" = {
text = stylixConf;
force = true;
};
#################################
# Environment variables
#################################
home.sessionVariables = {
STYLIX_CONF = "$HOME/.config/stylix/stylix.conf";
XCURSOR_THEME = cursorName;
XCURSOR_SIZE = toString cursorSize;
HYPRCURSOR_THEME = cursorName;
HYPRCURSOR_SIZE = toString cursorSize;
};
};
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/wallpaper.nix=
Setting up wallpaper engine + wallpaper gui
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/wallpaper.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
homeDir = "/home/${username}";
wallpaperSrc = "${flakeRoot}/assets/traveldroid/Wallpapers";
wallpaperDst = "${homeDir}/Wallpapers";
randoScript = "${homeDir}/Wallpapers/scripts/randomizeWallpapers.sh";
in
{
# Make bash available
environment.systemPackages = [ pkgs.bash pkgs.rsync pkgs.jq pkgs.awww pkgs.waypaper pkgs.socat ];
# Create the copy script using Home Manager, following Waybar style
home-manager.users = {
${username} = {
home.file = {
"copy-wallpapers.sh" = {
text = ''
#!/run/current-system/sw/bin/bash
set -euo pipefail
echo "Running as $(whoami)"
echo "Copying wallpapers from ${wallpaperSrc} to ${wallpaperDst} ..."
if [ ! -d "${wallpaperSrc}" ]; then
echo "ERROR: ${wallpaperSrc} does not exist"
exit 1
fi
mkdir -p "${wallpaperDst}"
# Simple copy, overwrite everything
cp -r "${wallpaperSrc}/." "${wallpaperDst}/"
# Fix permissions
chmod -R u+rwx "${wallpaperDst}"
echo "Done copying wallpapers."
'';
executable = true;
force = true;
};
};
};
};
# User service to run the script that copies the Wallpaperstuff
systemd.user.services.copyWallpapers = {
description = "Copy wallpapers from repo to ~/Wallpapers";
serviceConfig = {
Type = "oneshot";
ExecStart = "${homeDir}/copy-wallpapers.sh";
Restart = "no";
WorkingDirectory = homeDir;
};
wantedBy = [ "default.target" ];
};
# User service to randomize wallpapers
systemd.user.services.randomizeWallpapers = {
description = "Randomize wallpapers in ~/Wallpapers/pictures";
serviceConfig = {
Type = "oneshot";
ExecStart = "${randoScript}";
Restart = "no";
WorkingDirectory = homeDir;
};
wantedBy = [ "default.target" ];
};
############################
# Random background per workspace at logon
############################
systemd.user.services.workspaceWallpapers = {
description = "Dynamic wallpapers per workspace for Hyprland";
after = [ "graphical-session.target" ];
wants = [ "graphical-session.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${homeDir}/Wallpapers/scripts/workspace-wallpapers.sh";
Restart = "on-failure";
RestartSec = 5;
WorkingDirectory = homeDir;
Environment = [
"HYPRLAND_INSTANCE_SIGNATURE=${builtins.getEnv "HYPRLAND_INSTANCE_SIGNATURE"}"
"WAYLAND_DISPLAY=wayland-1"
"PATH=/run/current-system/sw/bin:/usr/bin:/bin"
];
};
wantedBy = [ "default.target" ];
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/waybar.nix=
This file installs and configures waybar
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/waybar.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
# Use the config option defaultUser directly, fallback to "henrov"
username = config.defaultUser or "henrov";
basePath = "${flakeRoot}/generated/.config";
assetPath = "${flakeRoot}/generated/.config/waybar";
in
{
# Install Waybar system-wide
environment.systemPackages = [ pkgs.waybar ];
home-manager.users = {
${username} = {
home.file = {
".config/waybar/config.jsonc" = {
text = builtins.readFile "${assetPath}/config.jsonc";
force = true;
};
".config/waybar/style-dark.css" = {
text = builtins.replaceStrings ["henrov"] [username] (builtins.readFile "${assetPath}/style-dark.css");
force = true;
};
".config/scripts/bluetooth-status.sh" = {
text = builtins.readFile "${basePath}/scripts/bluetooth-status.sh";
force = true;
executable = true;
};
".config/scripts/hypr-workspaces.sh" = {
text = builtins.readFile "${basePath}/scripts/hypr-workspaces.sh";
force = true;
executable = true;
};
".config/scripts/hypr-workspacesmenu.sh" = {
text = builtins.readFile "${basePath}/scripts/hypr-workspacesmenu.sh";
force = true;
executable = true;
};
};
};
};
# Systemd user service for Waybar
systemd.user.services.waybar = {
description = "Waybar for Hyprland";
after = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.waybar}/bin/waybar";
Restart = "always";
Environment = ''
WAYLAND_DISPLAY=${config.environment.sessionVariables.WAYLAND_DISPLAY or "wayland-0"}
XDG_CURRENT_DESKTOP=Hyprland
'';
};
wantedBy = [ "default.target" ];
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/wayland.nix=
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/wayland.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, ... }:
{
#################################
# Core Wayland packages
#################################
environment.systemPackages = with pkgs; [
wayland
wl-clipboard # optional but commonly used for copy/paste
];
#################################
# enable graphics stack
#################################
hardware.graphics.enable = true;
#################################
# Optional session variables for Wayland
#################################
environment.sessionVariables = {
# Forces some apps to use Wayland
NIXOS_OZONE_WL = "1";
};
}
#+END_SRC
** =generated/modules/traveldroid/desktop/xdg.nix=
This sets the XDG implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/desktop/xdg.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
homeDir = "/home/${username}";
# Portal backends
basePortal = pkgs.xdg-desktop-portal-gtk;
hyprlandPortal = pkgs.xdg-desktop-portal-hyprland;
in
{
#################################
# XDG Desktop Portals (system)
#################################
xdg.portal.enable = true;
xdg.portal.extraPortals = [
basePortal
hyprlandPortal
];
xdg.portal.config = {
"org.freedesktop.impl.portal.Screencast".backend = "hyprland";
};
#################################
# System packages
#################################
environment.systemPackages = [
basePortal
hyprlandPortal
];
#################################
# Home Manager user config
#################################
home-manager.users.${username} = {
#################################
# User packages
#################################
home.packages = [
basePortal
hyprlandPortal
];
#################################
# XDG user directories (HOME ONLY)
#################################
xdg.userDirs = {
enable = true;
createDirectories = true;
desktop = null;
download = "${homeDir}/Downloads";
documents = "${homeDir}/Documents";
pictures = "${homeDir}/Pictures";
music = null;
publicShare = null;
templates = "${homeDir}/Experiments";
videos = "${homeDir}/Videos";
extraConfig = {
XDG_PROJECTS_DIR = "${homeDir}/Projects";
XDG_WORK_DIR = "${homeDir}/Work";
};
};
};
}
#+END_SRC
* generated/modules/traveldroid/system
** =generated/modules/traveldroid/system/audio.nix=
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/audio.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, ... }:
{
############################
# Audio system
############################
environment.systemPackages = with pkgs; [
pulseaudio # PulseAudio daemon
pavucontrol # GUI mixer
pamixer # CLI mixer
playerctl # Player controls
];
}
#+END_SRC
** =generated/modules/traveldroid/system/avahi.nix=
Avahi helps discovering services
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/avahi.nix :noweb yes :mkdirp yes :eval never
{ ... }:
{
services.avahi = {
enable = true;
nssmdns4 = true;
publish = {
enable = true;
addresses = true;
};
};
}
#+END_SRC
** =generated/modules/traveldroid/system/bluetooth.nix=
Installing Bluetooth services and supporting aps
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/bluetooth.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, home-manager, ... }:
let
username = config.defaultUser or "henrov";
in
{
############################
# Bluetooth daemon
############################
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
package = pkgs.bluez;
};
environment.systemPackages = with pkgs; [ blueman ];
}
#+END_SRC
** =generated/modules/traveldroid/system/copy_scripts.nix=
This copies any scripts from /generated/.config/scripts to ~/.config/scripts and makes any .sh files executable.
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/copy_scripts.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
configPath = flakeRoot + "/generated/.config/scripts";
allFiles = lib.filesystem.listFilesRecursive configPath;
toRelative = file:
let
base = toString flakeRoot + "/generated/";
relative = lib.removePrefix base (toString file);
in
builtins.unsafeDiscardStringContext relative;
isShellScript = file:
lib.hasSuffix ".sh" (toString file);
toFileEntry = file: {
name = toRelative file;
value = {
source = file;
executable = isShellScript file;
force = true;
};
};
in
{
home-manager.users = {
${username} = {
home.file = builtins.listToAttrs (map toFileEntry allFiles);
};
};
}
#+END_SRC
** =generated/modules/traveldroid/system/dbus.nix=
This sets the dbus implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/dbus.nix :noweb yes :mkdirp yes :eval never
{ config, pkgs, ... }:
{
# Enable classic D-Bus service
services.dbus.enable = true;
# Use default dbus package (classic D-Bus)
services.dbus.dbusPackage = pkgs.dbus;
# Include some essential system packages so shell and tools exist
environment.systemPackages = with pkgs; [
bashInteractive
coreutils
];
# Do not attempt to wrap dbus-daemon-launch-helper manually
# No extra security.wrappers needed
}
#+END_SRC
** =generated/modules/traveldroid/system/firewall.nix=
This sets the firewall.
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/firewall.nix :noweb yes :mkdirp yes :eval never
{ pkgs, ... }:
{
# Use nftables as the firewall backend
networking.nftables.enable = true;
networking.firewall = {
enable = true;
filterForward = false; # don't filter forwarded traffic
# outbound is allowed by default UNLESS you've set:
# LAN-only ports — Wi-Fi interface
interfaces."wlan0" = {
allowedTCPPorts = [
22 # SSH
80 # allow HTTP globally for outbound
443 # allow HTTPS globally for outbound
631 # CUPS / IPP network printing
9100 # AppSocket/JetDirect printing
6566 # SANE network scanner
57621 # Spotify Connect
57622 # Spotify local file sync
];
allowedTCPPortRanges = [
{ from = 1714; to = 1764; } # KDE Connect
];
allowedUDPPorts = [
5353 # mDNS / Avahi (printer + device discovery)
631 # CUPS / IPP
67 # DHCP
123 # NTP time sync
1900 # UPnP device discovery
57621 # Spotify Connect
];
allowedUDPPortRanges = [
{ from = 1714; to = 1764; } # KDE Connect
];
};
# LAN-only ports — ethernet (ready for when you plug in)
interfaces."enp0s31f6" = {
allowedTCPPorts = [
631 # CUPS / IPP network printing
9100 # AppSocket/JetDirect printing
6566 # SANE network scanner
57621 # Spotify Connect
57622 # Spotify local file sync
];
allowedTCPPortRanges = [
{ from = 1714; to = 1764; } # KDE Connect
];
allowedUDPPorts = [
5353 # mDNS / Avahi (printer + device discovery)
631 # CUPS / IPP
67 # DHCP
123 # NTP time sync
1900 # UPnP device discovery
57621 # Spotify Connect
];
allowedUDPPortRanges = [
{ from = 1714; to = 1764; } # KDE Connect
];
};
};
# CLI tool for temporary rule changes without rebuilding
# Usage: sudo nixos-firewall-tool open tcp 8080
environment.systemPackages = with pkgs; [
nixos-firewall-tool
];
}
#+END_SRC
** =generated/modules/traveldroid/system/hypridle.nix=
This installs hypridle
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/hypridle.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
basePath = "${flakeRoot}/generated/.config";
assetPath = "${flakeRoot}/generated/.config/hypr";
in
{
#################################
# Install hypridle system-wide
#################################
environment.systemPackages = [ pkgs.hypridle ];
#################################
# Deploy config
#################################
home-manager.users = {
${username} = {
home.file = {
".config/hypr/hypridle.conf" = {
text = builtins.readFile "${assetPath}/hypridle.conf";
force = true;
};
};
};
};
#################################
# Systemd user service
#################################
systemd.user.services.hypridle = {
description = "Hypridle (Hyprland idle daemon)";
after = [ "hyprland-session.target" ];
bindsTo = [ "hyprland-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.hypridle}/bin/hypridle";
Restart = "on-failure";
RestartSec = "5s";
Environment = [
"HOME=/home/${username}"
"WAYLAND_DISPLAY=wayland-1"
"XDG_RUNTIME_DIR=/run/user/1000"
];
};
wantedBy = [ "hyprland-session.target" ];
};
}
#+END_SRC
** =generated/modules/traveldroid/system/hyprlock.nix=
This installs hyprlock
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/hyprlock.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
basePath = "${flakeRoot}/generated/.config";
assetPath = "${flakeRoot}/generated/.config/hypr";
in
{
#################################
# Install hyprlock system-wide
#################################
environment.systemPackages = [
pkgs.hyprlock
];
#################################
# Deploy configuration file
#################################
home-manager.users = {
${username} = {
home.file = {
".config/hypr/hyprlock.conf" = {
text = builtins.readFile "${assetPath}/hyprlock.conf";
force = true;
};
};
};
};
#################################
# Optional: helper systemd user service (manual start use)
#################################
systemd.user.services.hyprlock = {
description = "Hyprlock (manual lock session)";
after = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.hyprlock}/bin/hyprlock";
Restart = "no";
Environment = ''
WAYLAND_DISPLAY=${config.environment.sessionVariables.WAYLAND_DISPLAY or "wayland-0"}
XDG_CURRENT_DESKTOP=Hyprland
'';
};
wantedBy = [ ];
};
}
#+END_SRC
** =generated/modules/traveldroid/system/gnome-keyring.nix=
This sets the dbus implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/gnome-keyring.nix :noweb yes :mkdirp yes :eval never
{ config, pkgs, ... }:
{
##################################################
# Core services
##################################################
# Enable GNOME Keyring
services.gnome.gnome-keyring.enable = true;
##################################################
# PAM (auto unlock keyring on login)
##################################################
security.pam.services = {
login.enableGnomeKeyring = true;
greetd.enableGnomeKeyring = true;
sddm.enableGnomeKeyring = true;
gdm.enableGnomeKeyring = true;
};
##################################################
# Environment packages
##################################################
environment.systemPackages = with pkgs; [
polkit_gnome
seahorse
libsecret
];
##################################################
# Security / Polkit
##################################################
security.polkit.enable = true;
}
#+END_SRC
** =generated/modules/traveldroid/system/login-tuigreet.nix=
This sets up tuigreeter which is not fancy but imo fits the aesthetic I am aiming for
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/login-tuigreet.nix :noweb yes :mkdirp yes :eval never
{ config, pkgs, lib, ... }:
let
tuigreetBin = "${pkgs.tuigreet}/bin/tuigreet";
sessionsDir = "${pkgs.hyprland}/share/wayland-sessions";
in
{
#################################
# Greetd (tuigreet)
#################################
services.greetd = {
enable = true;
settings = {
default_session = {
command = ''
${tuigreetBin} \
--time \
--remember \
--remember-session \
--sessions ${sessionsDir} \
--cmd "start-hyprland"
'';
user = "greeter";
};
};
};
#################################
# Fix TTY / boot noise issues
#################################
systemd.services.greetd.serviceConfig = {
Type = "idle";
StandardInput = "tty";
StandardOutput = "tty";
StandardError = "journal";
# Prevent boot log spam on tty
TTYReset = true;
TTYVHangup = true;
TTYVTDisallocate = true;
};
}
#+END_SRC
** =generated/modules/traveldroid/system/networking.nix=
This sets the networking.
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/networking.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, ... }:
{
#################################
# Networking core
#################################
networking = {
# Let DHCP be default unless overridden elsewhere
useDHCP = lib.mkDefault true;
#################################
# NetworkManager (primary stack)
#################################
networkmanager = {
enable = true;
# Use iwd backend for WiFi
wifi.backend = "iwd";
};
#################################
# iwd (WiFi daemon)
#################################
wireless.iwd = {
enable = true;
# Allow user control via NM / CLI
settings.General.EnableNetworkConfiguration = true;
};
};
#################################
# System packages
#################################
environment.systemPackages = [
pkgs.networkmanager
pkgs.linux-firmware
pkgs.networkmanagerapplet
pkgs.networkmanager_dmenu
pkgs.iwgtk
];
}
#+END_SRC
** =generated/modules/traveldroid/system/nix.nix=
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/nix.nix :noweb yes :mkdirp yes :eval never
{ lib, config, ... }:
{
nix.settings = {
experimental-features = [ "nix-command" "flakes" ];
download-buffer-size = 536870912; # 512 MB
cores = 2;
max-jobs = 1;
};
}
#+END_SRC
** =generated/modules/traveldroid/system/printing.nix=
This sets the dbus implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/printing.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, ... }:
{
############################
# Printing system
############################
services.printing.enable = true; # enable CUPS printing service
############################
# System packages for GUI management
############################
environment.systemPackages = with pkgs; [
system-config-printer # GUI to manage printers
];
}
#+END_SRC
** =generated/modules/traveldroid/system/quickshell.nix=
This sets the dbus implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/quickshell.nix :noweb yes :mkdirp yes :eval never
{ pkgs, lib, config, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
quickshellPath = flakeRoot + "/generated/.config/quickshell";
allFiles = lib.filesystem.listFilesRecursive quickshellPath;
toRelative = file:
let
base = toString flakeRoot + "/generated/";
relative = lib.removePrefix base (toString file);
in
builtins.unsafeDiscardStringContext relative;
toFileEntry = file: {
name = toRelative file;
value = {
source = file;
force = true;
};
};
in
{
environment.systemPackages = with pkgs; [
quickshell
qt6.qtdeclarative
qt6.qttools
qt6.qtsvg
qt6.qtimageformats
qt6.qtmultimedia
qt6.qt5compat
];
qt = {
enable = true;
platformTheme = "qt5ct";
};
home-manager.users = {
${username} = {
home.file = builtins.listToAttrs (map toFileEntry allFiles);
};
};
}
#+END_SRC
** =generated/modules/traveldroid/system/swaync.nix=
This sets the dbus implementation
#+BEGIN_SRC nix :tangle generated/modules/traveldroid/system/swaync.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, flakeRoot, ... }:
let
username = config.defaultUser or "henrov";
assetPath = "${flakeRoot}/generated/.config/swaync";
in
{
environment.systemPackages = [ pkgs.swaynotificationcenter ];
home-manager.users.${username} = {
# Do NOT enable services.swaync — it would claim the config files
# and conflict with our home.file entries below.
home.file = {
".config/swaync/config.jsonc" = {
text = builtins.readFile "${assetPath}/config.jsonc";
force = true;
};
".config/swaync/style.css" = {
text = builtins.replaceStrings ["henrov"] [username] (builtins.readFile "${assetPath}/style.css");
force = true;
};
};
};
# Autostart swaync as a systemd user service instead
systemd.user.services.swaync = {
description = "SwayNotificationCenter";
after = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.swaynotificationcenter}/bin/swaync";
Restart = "always";
Environment = [
"WAYLAND_DISPLAY=${config.environment.sessionVariables.WAYLAND_DISPLAY or "wayland-1"}"
"XDG_CURRENT_DESKTOP=Hyprland"
];
};
wantedBy = [ "default.target" ];
};
}
#+END_SRC
* generated/users
** =generated/users/=
This is the default user, just search and replace henrov another name if you want to change
#+BEGIN_SRC nix :tangle generated/users/henrov.nix :noweb yes :mkdirp yes :eval never
{ lib, config, pkgs, ... }:
let
username = "henrov";
in
{
#################################
# NixOS system user
#################################
users.users.${username} = {
isNormalUser = true;
home = "/home/${username}";
hashedPassword = "$6$S7iShgBxB.77CwmP$i0njK.2r3OL5UEvgZbmwZ0rnpZ4QyJcv8p9uCmJ4AiVPSMXkQkIwMLzyAOnJ0q8.tPLIp/7EquEIZeK8qbmgw/";
extraGroups = [ "wheel" "networkmanager" "bluetooth" "input" ];
ignoreShellProgramCheck = true; # <-- avoids the assertion
shell = pkgs.zsh;
};
#################################
# Home Manager user definition
#################################
home-manager.users = {
${username} = {
home.username = username;
home.homeDirectory = "/home/${username}";
home.stateVersion = "26.05";
programs.zsh.enable = true;
home.packages = [
# add packages here
];
# Activation to ensure the directory is writable
home.activation.fixStylixPermissions = ''
mkdir -p $HOME/.config
chmod -R u+rwx $HOME/.config
'';
# Locale and timezone settings
home.sessionVariables = {
LANG = "nl_NL.UTF-8";
LC_ALL = "nl_NL.UTF-8";
TZ = "Europe/Amsterdam";
};
};
};
}
#+END_SRC
* These are all the prepared config files
:PROPERTIES:
:CUSTOM_ID: the-config-files
:END:
** =generated/.config/emacs/early-init.el=
This contaions emacs
#+BEGIN_SRC el :tangle generated/.config/emacs/early-init.el :noweb yes :mkdirp yes :eval never
;;; 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
#+END_SRC
** =generated/.config/emacs/init.el=
This contaions emacs
#+BEGIN_SRC el :tangle generated/.config/emacs/init.el :noweb yes :mkdirp yes :eval never
;;; 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-Each color should be used as described in this table.
See the Stylix documentation for how to apply these colors on NixOS.
#+END_SRC ** =generated/.config/swaync/config.jsonc= These are config files for waybar #+BEGIN_SRC jsonc :tangle generated/.config/swaync/config.jsonc :noweb yes :mkdirp yes :eval never { "positionX": "right", "positionY": "top", "layer": "overlay", "control-center-layer": "top", "layer-shell": true, "cssPriority": "application", "control-center-margin-top": 8, "control-center-margin-bottom": 8, "control-center-margin-right": 8, "control-center-margin-left": 0, "notification-2fa-action": true, "notification-inline-replies": false, "notification-icon-size": 48, "notification-body-image-height": 100, "notification-body-image-width": 200, "timeout": 10, "timeout-low": 5, "timeout-critical": 0, "fit-to-screen": true, "control-center-width": 500, "control-center-height": 600, "notification-window-width": 400, "keyboard-shortcuts": true, "image-visibility": "when-available", "transition-time": 200, "hide-on-clear": false, "hide-on-action": true, "script-fail-notify": true, "widgets": [ "inhibitors", "title", "dnd", "notifications" ], "widget-config": { "inhibitors": { "text": "Inhibitors", "button-text": "Clear All", "clear-all-button": true }, "title": { "text": "Notifications", "clear-all-button": true, "button-text": "Clear All" }, "dnd": { "text": "Do Not Disturb" }, "notifications": {} } } #+END_SRC ** =generated/.config/swaync/style.css= These are config files for waybar #+BEGIN_SRC css :tangle generated/.config/swaync/style.css :noweb yes :mkdirp yes :eval never @import url("/home/henrov/.config/shared/Colors.css"); * { all: unset; font-size: 13px; font-family: sans-serif; transition: 200ms; } /* ── Notification rows ─────────────────────────────────────────────────── */ .notification-row { outline: none; margin: 4px 0; } .notification-row:focus, .notification-row:hover { opacity: 0.85; } /* ── Individual notification ───────────────────────────────────────────── */ .notification { border-radius: 12px; padding: 8px; margin: 4px 8px; color: @text; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); /* gradient border */ border: 1px solid transparent; background-image: linear-gradient(@base-alpha, @base-alpha), linear-gradient(45deg, @blue, @green); background-clip: padding-box, border-box; background-origin: padding-box, border-box; } .notification-content { padding: 4px; } .notification-default-action { border-radius: 12px; } .notification-default-action:hover { background: alpha(@blue, 0.1); } /* ── Text elements ─────────────────────────────────────────────────────── */ .summary { font-size: 13px; font-weight: bold; color: @text; } .time { font-size: 11px; color: @overlay0; } .body { font-size: 12px; color: @subtext1; } /* ── Control center ────────────────────────────────────────────────────── */ .control-center { border-radius: 16px; padding: 8px; margin: 8px; color: @text; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5); /* gradient border */ border: 1px solid transparent; background-image: linear-gradient(@base, @base), /* ← was @mantle, @mantle */ linear-gradient(45deg, @blue, @green); background-clip: padding-box, border-box; background-origin: padding-box, border-box; } .control-center-list { background: transparent; } .control-center-list-placeholder { opacity: 0.4; font-size: 14px; } /* ── Misc windows ──────────────────────────────────────────────────────── */ .floating-notifications { background: transparent; } .blank-window { background: transparent; } /* ── Widget: title ─────────────────────────────────────────────────────── */ .widget-title { font-size: 14px; font-weight: bold; color: @blue; padding: 8px 4px 4px 4px; } .widget-title > button { font-size: 12px; color: @overlay0; background: alpha(@blue, 0.1); border-radius: 8px; padding: 2px 8px; } .widget-title > button:hover { background: alpha(@blue, 0.2); color: @text; } /* ── Widget: Do Not Disturb ────────────────────────────────────────────── */ .widget-dnd { padding: 4px; } .widget-dnd > switch { border-radius: 20px; background: alpha(@surface1, 0.3); /* gradient border */ border: 1px solid transparent; background-image: linear-gradient(alpha(@surface1, 0.3), alpha(@surface1, 0.3)), linear-gradient(45deg, @blue, @green); background-clip: padding-box, border-box; background-origin: padding-box, border-box; } .widget-dnd > switch:checked { background-image: linear-gradient(alpha(@blue, 0.5), alpha(@blue, 0.5)), linear-gradient(45deg, @blue, @green); background-clip: padding-box, border-box; background-origin: padding-box, border-box; } .widget-dnd > switch slider { border-radius: 20px; background: @text; min-width: 20px; min-height: 20px; } /* ── Widget: inhibitors ────────────────────────────────────────────────── */ .widget-inhibitors { padding: 4px; color: @red; font-size: 12px; } /* ── Close button ──────────────────────────────────────────────────────── */ .close-button { background: alpha(@red, 0.15); border-radius: 6px; color: @red; padding: 2px 6px; font-size: 11px; } .close-button:hover { background: alpha(@red, 0.3); } #+END_SRC ** =generated/.config/waybar/config.jsonc= These are config files for waybar #+BEGIN_SRC json :tangle generated/.config/waybar/config.jsonc :noweb yes :mkdirp yes :eval never { "layer": "top", "position": "top", "autohide": true, "autohide-blocked": false, "exclusive": true, "passthrough": false, "gtk-layer-shell": true, /*******************************************************************/ "modules-left": [ "group/connections" ,"group/hardware" ], "modules-center": [ "group/workspaces" ,"custom/power" ,"custom/media" ,"custom/batterywarn" /* ,"custom/kdeconnect" */ ], "modules-right": [ "group/audio" ,"tray" ,"clock" ,"idle_inhibitor" ,"custom/notifications" ], /*******************************************************************/ "group/workspaces": { "orientation": "horizontal", "modules": [ "hyprland/workspaces", "custom/windows" ] }, /*******************************************************************/ "group/hardware": { "orientation": "horizontal", "drawer": { "transition-duration": 500, "transition-left-to-right": true }, "modules": [ "custom/hardware-anchor", "battery", "cpu", "memory", "temperature" ] }, "custom/hardware-anchor": { "format": " ", "tooltip": false }, /*************************/ "group/connections": { "orientation": "horizontal", "drawer": { "transition-duration": 500, "transition-left-to-right": true }, "modules": [ "custom/connections-anchor", "custom/bluetooth", "network" ] }, "custom/connections-anchor": { "format": " ", "tooltip": false }, /*************************/ "group/audio": { "orientation": "horizontal", "modules": [ /* "custom/media", */ "pulseaudio", "pulseaudio/slider", ] }, /*******************************************************************/ "hyprland/workspaces": { "align": 1, "format": "{name}", "interval": 2, }, "custom/windows": { "align": 0, "format": "{text}", "exec": "~/.config/scripts/hypr-workspaces.sh", "interval": 2, "return-type": "json", "on-click": "~/.config/scripts/hypr-workspacesmenu.sh", "tooltip": true }, "custom/media": { "exec": "~/.config/scripts/media.sh", "interval": 1, "return-type": "json", "format": "{}", "on-click": "qs -c media", "max-length": 20, "scroll-step": 1, "tooltip": true }, "custom/bluetooth": { "exec": "~/.config/scripts/bluetooth-status.sh", "interval": 5, "return-type": "json", "on-click": "blueman-manager", "format": "{}" }, "custom/batterywarn": { "exec": "~/.config/scripts/batterywarn.sh", "interval": 60, "format": "{}" }, "custom/kdeconnect": { "format": "{name} {battery}% ", "interval": 10, "exec": "~/.config/scripts/kdeconnect-status.sh", "tooltip": true }, "custom/notifications": { "tooltip": false, "return-type": "json", "exec-if": "which swaync-client", "exec": "swaync-client -swb", "format": "{icon}", "format-icons": { "notification": "", "none": "", "dnd-notification": "", "dnd-none": "", }, "on-click": "swaync-client -t", "on-click-right": "swaync-client -d", "on-click-middle": "swaync-client -dn", }, "custom/power": { "format": "", "on-click": "qs -c powermenu", "tooltip-format": "Power Menu" }, "pulseaudio": { "format": "{volume}% {icon}", "format-bluetooth": "{volume}% {icon}", "format-muted": "", "format-icons": { "headphones": "", "headset": "", "phone": "", "portable": "", "default": ["", ""] }, "on-click": "pavucontrol" }, "pulseaudio/slider": { "min": 0, "max": 100, "orientation": "horizontal" }, "idle_inhibitor": { "tooltip": true, "format": "{icon}", "format-icons": { "activated": " ", "deactivated": " " }, "tooltip-format-activated": "Staying awake", "tooltip-format-deactivated": "Might sleep...." }, "network": { "format-wifi": " ({bandwidthDownBits})", "format-ethernet": " ({bandwidthDownBits})", "format-disconnected": "Disconnected ⚠", "tooltip-format-wifi": "{essid} ({signalStrength}%)", "tooltip-format-ethernet": "{ifname}: {ipaddr}/{cidr}", "on-click": "networkmanager_dmenu --dmenu --style ~/.config/wofi/style.css --allow-images=false", "on-click-right": "nm-connection-editor" }, "cpu": { "format": "{usage}% ", "tooltip": false }, "memory": { "format": "{percentage}% " }, "temperature": { "format": "{temperatureC}°C ", "tooltip": false }, "tray": { "spacing": 10, "icon-size": 14 }, "battery": { "bat": "BAT0", "states": { "good": 95, "warning": 30, "critical": 15 }, "format": "{capacity}% {icon}", "format-charging": "{capacity}% ", "format-plugged": "{capacity}% ", "format-icons": ["", "", "", "", " "] } } #+END_SRC ** =generated/.config/waybar/style-dark.css= This file contains all css for waybar #+BEGIN_SRC css :tangle generated/.config/waybar/style-dark.css :noweb yes :mkdirp yes :eval never @import url("file:///home/henrov/.config/shared/Colors.css"); /* --- Global --- */ * { font-family: Aporetic Sans Mono, Iosevka Nerd Font, Roboto, Helvetica, Arial, sans-serif; font-size: 13px; } window#waybar { background-color: transparent; color: @text; } /* --------------------------------------------------------- */ /* --- Group anchors default visible --- */ #custom-hardware-anchor, #custom-connections-anchor { min-width: 80px; padding: 0 5px; margin: 0 2px; opacity: 1; transition: opacity 0.2s ease, min-width 0.2s ease, padding 0.2s ease; } /* --- Hide anchors on hover of the group --- */ #hardware:hover #custom-hardware-anchor, #connections:hover #custom-connections-anchor { opacity: 0; min-width: 0; padding: 0; margin: 0; } #hardware:hover, #connections:hover { min-width: 80px; } /* MODULES */ .modules-left > widget, .modules-center > widget, .modules-right > widget { min-width: 80px; color: @text; font-weight: bold; border-radius: 30px; background: linear-gradient(@base-alpha, @base-alpha) padding-box, linear-gradient(45deg, @blue, @green) border-box; border: 2px solid transparent; } .modules-left > box + box, .modules-center > box + box, .modules-right > box + box { margin-left: 5px; } .modules-left > widget label, .modules-left > label , .modules-center > widget label, .modules-center > label, .modules-right > widget label, .modules-right > label { padding: 0px 5px; transition: padding 0.2s ease; } /* ----------------------------- WORKSPACES / WINDOWS MODULE ----------------------------- */ /* Disable hover effects completely */ #workspaces button, #workspaces button:hover { border: 2px solid transparent; padding: 0 6px; margin: 0; border-radius: 30px; transition: none; /* disable hover animation */ } /* Active vs inactive workspace colors */ #workspaces button.active { background: linear-gradient(45deg, @blue, @green); color: @base; } activeworkspaces:not(.active) { background: linear-gradient(@base-alpha, @base-alpha); border: 2px solid transparent; color: @text-muted; /* inactive text color */ } label#custom-windows.module { font-size: 14px; color: @base; padding: 0 8px; border-radius: 30px; transition: all 0.3s ease; } label#custom-windows.active { background: linear-gradient(45deg, alpha(@blue, 0.5), alpha(@green, 0.5)); } label#custom-windows:not(.active) { background: transparent; color: transparent; } /* ---- Media ---*/ #custom-media { padding: 0 8px; color: @text; } #custom-media.inactive { background: transparent; color: transparent; opacity: 0; padding: 0; margin: 0; min-width: 0; } /* ---- Pulseaudio ---*/ #pulseaudio-slider { padding: 0; margin: 0; } #pulseaudio-slider slider { min-height: 0px; min-width: 0px; opacity: 0; border-radius: 30px; background: linear-gradient(45deg, @blue, @green); border: none; box-shadow: none; } #pulseaudio-slider trough { min-height: 10px; min-width: 80px; border-radius: 30px; background: transparent; } #pulseaudio-slider highlight { min-width: 10px; border-radius: 30px; background: linear-gradient(45deg, @blue, @green); border: 2px solid transparent; } /* --------------------------------------------------------- */ /* STATES / SPECIALS */ #idle_inhibitor.activated { background: linear-gradient(45deg, @blue, @green); border: 2px solid transparent; color: @base; border-radius: 30px; } #battery.charging { color: @green; } #battery.warning:not(.charging) { color: white; animation: blink 0.5s linear infinite alternate; border-radius: 30px; border: 2px solid transparent; } #custom-battery-warn { margin: 0 5px; padding: 0 10px; color: white; animation: blink 0.5s linear infinite alternate; } @keyframes blink { to { background-color: #ffffff; color: black; border-radius: 30px; border: 2px solid transparent; } } #network.disconnected { background-color: @red; border-radius: 30px; border: 2px solid transparent; } #temperature.critical { background-color: @red; border-radius: 30px; border: 2px solid transparent; } /* --------------------------------------------------------- */ /* GLOBAL MODULE SPACING */ #clock, #idle_inhibitor, #battery:not(.warn), #cpu, #memory, #temperature, #network, #pulseaudio, #tray { margin: 0 5px; padding: 0 10px; } #+END_SRC ** =generated/.config/scripts/bluetooth-status.sh= These are config files for waybar #+BEGIN_SRC sh :tangle generated/.config/scripts/bluetooth-status.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never bt_connected="" while read -r _ mac name_rest; do if [ "$(bluetoothctl info "$mac" | awk '/Connected:/ {print $2}')" = "yes" ]; then bt_connected+="$name_rest\n" fi done < <(bluetoothctl devices) # icon if [ -n "$bt_connected" ]; then icon="" tooltip=$(printf "%b" "$bt_connected") else icon="" tooltip="No devices connected" fi # ALWAYS produce valid JSON printf '{"text": "%s", "tooltip": "%s"}\n' "$icon" "$tooltip" #+END_SRC ** =generated/.config/scripts/hypr-workspaces.sh= These are config files for waybar #+BEGIN_SRC sh :tangle generated/.config/scripts/hypr-workspaces.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never # Get focused monitor name focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused==true) | .name') monitor="${WAYBAR_OUTPUT_NAME:-$focused_monitor}" # Hide if not focused monitor if [ "$monitor" != "$focused_monitor" ]; then jq -c -n '{text:"", class:"hidden"}' exit 0 fi # Get active workspace on this monitor active_ws=$(hyprctl monitors -j | jq -r \ ".[] | select(.name==\"$monitor\") | .activeWorkspace.id") # Get clients clients=$(hyprctl clients -j | jq -r \ ".[] | select(.workspace.id==$active_ws) | \"\(.title)\"") count=$(echo "$clients" | grep -c '\S') # Hide if 0 or 1 clients — no point showing window switcher if [ "$count" -le 1 ]; then jq -c -n '{text:"", class:"hidden"}' exit 0 fi tooltip=$(echo "$clients" | sed 's/^/• /' | paste -sd '\n' -) jq -c -n \ --arg text "$count" \ --arg tooltip "$tooltip" \ --arg class "active" \ '{text:$text, tooltip:$tooltip, class:$class}' #+END_SRC ** =generated/.config/scripts/hypr-workspacesmenu.sh= These are config files for waybar #+BEGIN_SRC sh :tangle generated/.config/scripts/hypr-workspacesmenu.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never active_ws=$(hyprctl activeworkspace -j | jq -r '.id') clients=$(hyprctl clients -j | jq -r \ ".[] | select(.workspace.id==$active_ws) | \"\(.address)|\(.title)\"") choice=$(echo "$clients" | cut -d'|' -f2 \ | wofi --dmenu \ --style ~/.config/wofi/style.css \ --allow-images=false \ --prompt "Active windows ...") [ -z "$choice" ] && exit 0 addr=$(echo "$clients" | grep "|$choice" | head -n1 | cut -d'|' -f1) hyprctl dispatch focuswindow address:"$addr" #+END_SRC ** =generated/.config/scripts/kdeconnect-status.sh= These are config files for waybar #+BEGIN_SRC sh :tangle generated/.config/scripts/kdeconnect-status.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never DEVICE=$(kdeconnect-cli --list-devices | grep -oP '(?<=\().*?(?=\))' | head -n 1) if [ -z "$DEVICE" ]; then echo "No phone" exit 0 fi NAME=$(kdeconnect-cli -d "$DEVICE" --name 2>/dev/null) BATTERY=$(kdeconnect-cli -d "$DEVICE" --battery 2>/dev/null | grep -o '[0-9]\+' | head -n 1) if [ -z "$BATTERY" ]; then echo "$NAME" else echo "$NAME $BATTERY%" fi #+END_SRC ** =generated/.config/waypaper/config.ini= These are config files for waypaper #+BEGIN_SRC conf :tangle generated/.config/waypaper/config.ini :noweb yes :mkdirp yes :eval never [Settings] language = en backend = awww folder = ~/Wallpapers/pictures monitors = All wallpaper = ~/Wallpapers/pictures/13.jpg show_path_in_tooltip = True fill = fill sort = name color = #ffffff subfolders = False all_subfolders = False show_hidden = False show_gifs_only = False zen_mode = False post_command = number_of_columns = 3 awww_transition_type = any awww_transition_step = 63 awww_transition_angle = 0 awww_transition_duration = 2 awww_transition_fps = 60 mpvpaper_sound = False mpvpaper_options = use_xdg_state = False stylesheet = /home/henrov/.config/waypaper/style.css keybindings = ~/.config/waypaper/keybindings.ini #+END_SRC ** =generated/.config/waypaper/config.ini= These are config files for .config/waypaper #+BEGIN_SRC ini :tangle generated/.config/waypaper/config.ini :noweb yes :mkdirp yes :eval never [Settings] language = en backend = awww folder = ~/Wallpapers/pictures monitors = All wallpaper = ~/Wallpapers/pictures/13.jpg show_path_in_tooltip = True fill = fill sort = name color = #ffffff subfolders = False all_subfolders = False show_hidden = False show_gifs_only = False zen_mode = False post_command = number_of_columns = 3 awww_transition_type = any awww_transition_step = 63 awww_transition_angle = 0 awww_transition_duration = 2 awww_transition_fps = 60 mpvpaper_sound = False mpvpaper_options = use_xdg_state = False stylesheet = /home/henrov/.config/waypaper/style.css keybindings = ~/.config/waypaper/keybindings.ini #+END_SRC ** =generated/.config/wofi/config= These are config files for .config/wofi #+BEGIN_SRC toml :tangle generated/.config/wofi/config :noweb yes :mkdirp yes :eval never [global] allow_markup = true location = center anchor = center lines = 10 columns = 1 sort_order = last-used sort_method = fuzzy allow_scrolling = true scroll_wrap = true scroll_step = 10 cycle = true hide_scroll = false hide_search = false prompt = > ... #+END_SRC ** =generated/.config/wofi/style.css= This is the default layout for wofi #+BEGIN_SRC css :tangle generated/.config/wofi/style.css :noweb yes :mkdirp yes :eval never @import "~/.config/shared/Colors.css"; * { background-color: transparent; color: @text; font-family: "JetBrainsMono Nerd Font", monospace; font-size: 12pt; } #window { background: linear-gradient(45deg, #89b4fa, #a6e3a1); border-radius: 28px; padding: 2px; } #outer-box { background-color: rgba(30, 30, 46, 0.98); /* almost solid */ border-radius: 26px; padding: 12px; } #inner-box { background: transparent; padding: 0; } #input { background-color: @surface1; /* stronger than surface0 */ color: @text; border: 1px solid @surface2; border-radius: 18px; padding: 10px 14px; margin-bottom: 10px; } #input:focus { border: 1px solid @blue; background-color: @surface2; } #entry { background-color: rgba(0, 0, 0, 0.35); color: @subtext1; border-radius: 18px; padding: 10px 14px; margin: 2px 0; transition: all 0.15s ease; } #entry:hover { background-color: rgba(0, 0, 0, 0.5); color: @text; } #entry:focus { background: linear-gradient(45deg, #89b4fa, #89b4fa); color: @lavender; border-radius: 18px; } #entry:selected { background: linear-gradient(45deg, #89b4fa, #a6e3a1); border-radius: 18px; font-weight: bold; } #entry image { margin-right: 10px; opacity: 0.9; } #scrollbar { background-color: @surface1; border-radius: 20px; width: 6px; } #scrollbar handle { background: linear-gradient(45deg, #89b4fa, #a6e3a1); border-radius: 20px; } #prompt { color: @subtext0; margin-right: 6px; } #+END_SRC ** =generated/.config/zed/settings.json= These are config files for Zed editor #+BEGIN_SRC json :tangle generated/.config/zed/settings.json :noweb yes :mkdirp yes :eval never // Zed settings // // For information on how to configure Zed, see the Zed // documentation: https://zed.dev/docs/configuring-zed // // To see all of Zed's default settings without changing your // custom settings, run `zed: open default settings` from the // command palette (cmd-shift-p / ctrl-shift-p) { "icon_theme": "Catppuccin Mocha", "agent": { "default_model": { "provider": "ollama", "model": "codellama:34b", "enable_thinking": false }, "favorite_models": [], "model_parameters": [] }, "ui_font_size": 16, "buffer_font_size": 15, "theme": { "mode": "dark", "light": "One Light", "dark": "Catppuccin Mocha", }, } #+END_SRC ** =generated/.config/zsh/.zshrc= This sets up the zsh in the terminal #+BEGIN_SRC bash :tangle generated/.config/zsh/.zshrc :noweb yes :mkdirp yes :eval never # Path to syntax highlighting installed by Nix ZSH_SYNTAX_HIGHLIGHTING="${HOME}/.nix-profile/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" # Load syntax highlighting if available if [ -f "$ZSH_SYNTAX_HIGHLIGHTING" ]; then source "$ZSH_SYNTAX_HIGHLIGHTING" fi # Initialize Starship prompt if command -v starship >/dev/null 2>&1; then eval "$(starship init zsh)" fi source /etc/profile.d/99-alias-functions.sh eval "$(/run/current-system/sw/bin/z.lua --init zsh)" cd() { if [ "$#" -eq 0 ]; then builtin cd ~ else builtin cd "$@" || return fi command z "$PWD" } #+END_SRC