Added lib.mkForce + backup = false

This commit is contained in:
2026-03-01 17:23:50 +01:00
parent 9e8c030646
commit 72006f36ea
47 changed files with 5121 additions and 5058 deletions
+1 -1
View File
@@ -2,5 +2,5 @@ use flake
watch_file .envrc.private watch_file .envrc.private
if [[ -f .envrc.private ]]; then if [[ -f .envrc.private ]]; then
source_env .envrc.private source_env .envrc.private
fi fi
+1901 -1880
View File
File diff suppressed because it is too large Load Diff
+1652 -1631
View File
File diff suppressed because it is too large Load Diff
@@ -8,98 +8,98 @@ let
# Guard: if we accidentally split into characters, rawLines length ~= stringLength raw # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
_guard = assert !( _guard = assert !(
builtins.stringLength raw > 1 && builtins.stringLength raw > 1 &&
builtins.length rawLines == builtins.stringLength raw builtins.length rawLines == builtins.stringLength raw
); true; ); true;
cleanLine = l: cleanLine = l:
let let
noCR = lib.replaceStrings [ "\r" ] [ "" ] l; noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
noInlineComment = lib.head (lib.splitString "#" noCR); noInlineComment = lib.head (lib.splitString "#" noCR);
in in
lib.strings.trim noInlineComment; lib.strings.trim noInlineComment;
entries = entries =
builtins.filter (l: l != "") builtins.filter (l: l != "")
(map cleanLine rawLines); (map cleanLine rawLines);
# Flatpak app IDs are reverse-DNS style like org.example.App (at least 2 dots). # Flatpak app IDs are reverse-DNS style like org.example.App (at least 2 dots).
# We'll validate and fail early with a clear message. # We'll validate and fail early with a clear message.
dotCount = s: builtins.length (lib.splitString "." s) - 1; dotCount = s: builtins.length (lib.splitString "." s) - 1;
isValidId = s: isValidId = s:
(dotCount s) >= 2; # matches the error you're seeing: "at least 2 periods" (dotCount s) >= 2; # matches the error you're seeing: "at least 2 periods"
_validate = _validate =
builtins.seq _guard ( builtins.seq _guard (
builtins.map (id: builtins.map (id:
if isValidId id then true else if isValidId id then true else
throw '' throw ''
${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots) ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots)
Token : ${builtins.toJSON id} Token : ${builtins.toJSON id}
flatpaks.conf : ${toString flatpakConfPath} flatpaks.conf : ${toString flatpakConfPath}
Fix: remove stray tokens/headers, or comment them out with '#'. Fix: remove stray tokens/headers, or comment them out with '#'.
'' ''
) entries ) entries
); );
# Use validated entries # Use validated entries
flatpakApps = builtins.seq _validate entries; flatpakApps = builtins.seq _validate entries;
syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" '' syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" ''
set -euo pipefail set -euo pipefail
# Use the deployed config path (matches environment.etc below) # Use the deployed config path (matches environment.etc below)
CONF="/etc/flatpak/flatpaks.conf" CONF="/etc/flatpak/flatpaks.conf"
if [[ -f "$CONF" ]]; then if [[ -f "$CONF" ]]; then
echo "flatpak-sync: using $CONF" echo "flatpak-sync: using $CONF"
else else
echo "flatpak-sync: WARNING: $CONF not found, using embedded list" echo "flatpak-sync: WARNING: $CONF not found, using embedded list"
fi fi
if ! flatpak remotes --system --columns=name | grep -qx flathub; then 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 flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
fi fi
desired_apps=( desired_apps=(
${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)} ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)}
) )
for app in "''${desired_apps[@]}"; do for app in "''${desired_apps[@]}"; do
if ! flatpak info --system "$app" >/dev/null 2>&1; then if ! flatpak info --system "$app" >/dev/null 2>&1; then
flatpak install --system -y --noninteractive flathub "$app" flatpak install --system -y --noninteractive flathub "$app"
fi fi
done done
''; '';
in in
{ {
services.flatpak.enable = true; services.flatpak.enable = true;
xdg.portal = { xdg.portal = {
enable = true; enable = true;
extraPortals = with pkgs; [ extraPortals = with pkgs; [
xdg-desktop-portal-hyprland xdg-desktop-portal-hyprland
xdg-desktop-portal-gtk xdg-desktop-portal-gtk
]; ];
}; };
# Deploy the config file for runtime visibility/debugging # Deploy the config file for runtime visibility/debugging
environment.etc."flatpak/flatpaks.conf".source = flatpakConfPath; environment.etc."flatpak/flatpaks.conf".source = lib.mkForce flatpakConfPath;
systemd.services.flatpak-sync = { systemd.services.flatpak-sync = {
description = "Install Flatpak apps listed in flatpaks.conf"; description = "Install Flatpak apps listed in flatpaks.conf";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
after = [ "network-online.target" ]; after = [ "network-online.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
ExecStart = syncFlatpaks; ExecStart = syncFlatpaks;
}; };
restartTriggers = [ flatpakConfPath ]; restartTriggers = [ flatpakConfPath ];
path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
}; };
} }
@@ -6,38 +6,38 @@ let
rawLines = lib.splitString "\n" raw; rawLines = lib.splitString "\n" raw;
# Guard: if we accidentally split into characters, rawLines length ~= stringLength raw # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
_guard = assert !( _guard = assert !(
builtins.stringLength raw > 1 && builtins.stringLength raw > 1 &&
builtins.length rawLines == builtins.stringLength raw builtins.length rawLines == builtins.stringLength raw
); true; ); true;
cleanLine = l: cleanLine = l:
let let
noCR = lib.replaceStrings [ "\r" ] [ "" ] l; noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
noInlineComment = lib.head (lib.splitString "#" noCR); noInlineComment = lib.head (lib.splitString "#" noCR);
in in
lib.strings.trim noInlineComment; lib.strings.trim noInlineComment;
entries = entries =
builtins.filter (l: l != "") builtins.filter (l: l != "")
(map cleanLine rawLines); (map cleanLine rawLines);
resolvePkg = name: resolvePkg = name:
let let
parts = lib.splitString "." name; parts = lib.splitString "." name;
found = lib.attrByPath parts null pkgs; found = lib.attrByPath parts null pkgs;
in in
if found == null then if found == null then
throw '' throw ''
install_packages.nix: package not found in pkgs install_packages.nix: package not found in pkgs
Token : ${builtins.toJSON name} Token : ${builtins.toJSON name}
packages.conf : ${toString packagesConfPath} packages.conf : ${toString packagesConfPath}
Hint : check the attribute name on search.nixos.org/packages Hint : check the attribute name on search.nixos.org/packages
'' ''
else else
found; found;
packages = builtins.seq _guard (map resolvePkg entries); packages = builtins.seq _guard (map resolvePkg entries);
zenBrowser = zenBrowser =
inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default; inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
in in
{ {
environment.systemPackages = environment.systemPackages =
packages packages
++ [ zenBrowser ]; ++ [ zenBrowser ];
} }
+16 -16
View File
@@ -1,27 +1,27 @@
{ pkgs, ... } : { pkgs, ... } :
{ {
boot = { boot = {
initrd = { initrd = {
verbose = false; # its a lot of logs. dont need it, unless we do. verbose = false; # its a lot of logs. dont need it, unless we do.
kernelModules = [ ]; # no kernel modules on boot kernelModules = [ ]; # no kernel modules on boot
}; };
extraModulePackages = [ ]; # no extra packages on boot either extraModulePackages = [ ]; # no extra packages on boot either
kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel
kernelParams = [ "silent" ]; # quiet those logs kernelParams = [ "silent" ]; # quiet those logs
consoleLogLevel = 0; # quiten more logs consoleLogLevel = 0; # quiten more logs
plymouth.enable = true; # graphical boot animation instead plymouth.enable = true; # graphical boot animation instead
supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows) supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows)
loader = { loader = {
systemd-boot.enable = true; # systemd-boot systemd-boot.enable = true; # systemd-boot
systemd-boot.configurationLimit = 10; systemd-boot.configurationLimit = 10;
efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader
timeout = 5; # grub timeout to make a selection timeout = 5; # grub timeout to make a selection
}; };
}; };
} }
+16 -16
View File
@@ -1,29 +1,29 @@
{ pkgs, user, config, ... }: { pkgs, user, config, ... }:
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
zip zip
unzip unzip
p7zip p7zip
usbutils usbutils
udiskie udiskie
file-roller file-roller
]; ];
programs.thunar = { programs.thunar = {
enable = true; enable = true;
plugins = with pkgs; [ plugins = with pkgs; [
thunar-archive-plugin thunar-archive-plugin
thunar-media-tags-plugin thunar-media-tags-plugin
thunar-volman thunar-volman
thunar-vcs-plugin thunar-vcs-plugin
]; ];
}; };
programs.xfconf.enable = true; # to save thunar settings programs.xfconf.enable = true; # to save thunar settings
services = { services = {
gvfs.enable = true; # Mount, trash, and other functionalities gvfs.enable = true; # Mount, trash, and other functionalities
tumbler.enable = true; # Thumbnail support for images tumbler.enable = true; # Thumbnail support for images
udisks2.enable = true; # Auto mount usb drives udisks2.enable = true; # Auto mount usb drives
}; };
} }
+17 -17
View File
@@ -1,24 +1,24 @@
{ user, ... } : { user, ... } :
let let
locale = user.locale; locale = user.locale;
defaultLocale = "nl_NL.UTF-8"; defaultLocale = "nl_NL.UTF-8";
in in
{ {
# Set your time zone. # Set your time zone.
time.timeZone = "Europe/Amsterdam"; time.timeZone = "Europe/Amsterdam";
# Select internationalisation properties. # Select internationalisation properties.
i18n.defaultLocale = defaultLocale; i18n.defaultLocale = defaultLocale;
i18n.extraLocaleSettings = { i18n.extraLocaleSettings = {
LC_ADDRESS = locale; LC_ADDRESS = locale;
LC_IDENTIFICATION = locale; LC_IDENTIFICATION = locale;
LC_MEASUREMENT = locale; LC_MEASUREMENT = locale;
LC_MONETARY = locale; LC_MONETARY = locale;
LC_NAME = locale; LC_NAME = locale;
LC_NUMERIC = locale; LC_NUMERIC = locale;
LC_PAPER = locale; LC_PAPER = locale;
LC_TELEPHONE = locale; LC_TELEPHONE = locale;
LC_TIME = defaultLocale; LC_TIME = defaultLocale;
}; };
} }
@@ -2,40 +2,40 @@
let let
lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf; lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf;
lockPng = ../../assets/lock.png; lockPng = ../../assets/lock.png;
greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf; greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf;
greeterRaw = builtins.readFile greeterConfPath; greeterRaw = builtins.readFile greeterConfPath;
# Extract "key = value" from the greeter conf. # Extract "key = value" from the greeter conf.
# Returns null if not found. # Returns null if not found.
getIniValue = key: getIniValue = key:
let let
lines = lib.splitString "\n" greeterRaw; lines = lib.splitString "\n" greeterRaw;
# Captures the value part (group 0) from a single line. # Captures the value part (group 0) from a single line.
# We match line-by-line because Nix regex does NOT support PCRE flags like (?s). # We match line-by-line because Nix regex does NOT support PCRE flags like (?s).
m = m =
let let
ms = builtins.filter (x: x != null) (map (line: ms = builtins.filter (x: x != null) (map (line:
builtins.match builtins.match
("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$")
line line
) lines); ) lines);
in
if ms == [] then null else builtins.elemAt ms 0;
in in
if m == null then null else lib.strings.trim (builtins.elemAt m 0); if ms == [] then null else builtins.elemAt ms 0;
in
if m == null then null else lib.strings.trim (builtins.elemAt m 0);
# In your greeter.conf these are *package keys*, not theme names. # In your greeter.conf these are *package keys*, not theme names.
themePkgKey = getIniValue "theme-name"; themePkgKey = getIniValue "theme-name";
iconPkgKey = getIniValue "icon-theme-name"; iconPkgKey = getIniValue "icon-theme-name";
cursorPkgKey = getIniValue "cursor-theme-name"; cursorPkgKey = getIniValue "cursor-theme-name";
cursorSizeStr = getIniValue "cursor-theme-size"; cursorSizeStr = getIniValue "cursor-theme-size";
cursorSize = cursorSize =
if cursorSizeStr == null then null if cursorSizeStr == null then null
else lib.toInt (lib.strings.trim cursorSizeStr); else lib.toInt (lib.strings.trim cursorSizeStr);
# Map package-keys (from greeter.conf) -> { package, name } # Map package-keys (from greeter.conf) -> { package, name }
# #
@@ -43,97 +43,97 @@ let
# - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons. # - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons.
# - "package" is the Nixpkgs derivation providing it. # - "package" is the Nixpkgs derivation providing it.
pkgMap = { pkgMap = {
catppuccinThemePkg = { catppuccinThemePkg = {
package = pkgs.catppuccin-gtk.override { package = pkgs.catppuccin-gtk.override {
accents = [ "blue" ]; accents = [ "blue" ];
variant = "mocha"; variant = "mocha";
size = "standard"; size = "standard";
tweaks = [ ]; tweaks = [ ];
}; };
name = "Catppuccin-Mocha-Standard-Blue-Dark"; name = "Catppuccin-Mocha-Standard-Blue-Dark";
}; };
papirus-icon-theme = { papirus-icon-theme = {
package = pkgs.papirus-icon-theme; package = pkgs.papirus-icon-theme;
name = "Papirus-Dark"; name = "Papirus-Dark";
}; };
bibata-cursors = { bibata-cursors = {
package = pkgs.bibata-cursors; package = pkgs.bibata-cursors;
name = "Bibata-Modern-Ice"; name = "Bibata-Modern-Ice";
}; };
}; };
pick = key: pick = key:
if key == null then if key == null then
throw "lightdm: missing required key in ${toString greeterConfPath}" throw "lightdm: missing required key in ${toString greeterConfPath}"
else if !(pkgMap ? "${key}") then else if !(pkgMap ? "${key}") then
throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}"
else else
pkgMap."${key}"; pkgMap."${key}";
themeSel = pick themePkgKey; themeSel = pick themePkgKey;
iconSel = pick iconPkgKey; iconSel = pick iconPkgKey;
cursorSel = pick cursorPkgKey; cursorSel = pick cursorPkgKey;
# Rewrite greeter.conf so LightDM sees REAL names, not package keys. # Rewrite greeter.conf so LightDM sees REAL names, not package keys.
# Also force background to lockPng. # Also force background to lockPng.
greeterFixed = greeterFixed =
'' ''
[greeter] [greeter]
theme-name = ${themeSel.name} theme-name = ${themeSel.name}
icon-theme-name = ${iconSel.name} icon-theme-name = ${iconSel.name}
cursor-theme-name = ${cursorSel.name} cursor-theme-name = ${cursorSel.name}
${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"}
'' ''
+ "\n" + "\n"
+ greeterRaw; + greeterRaw;
in in
{ {
services.greetd.enable = false; services.greetd.enable = false;
services.xserver = { services.xserver = {
enable = true;
desktopManager.xterm.enable = false;
displayManager.lightdm = {
enable = true;
background = lockPng;
greeters.gtk = {
enable = true; enable = true;
desktopManager.xterm.enable = false;
displayManager.lightdm = { theme = {
enable = true; name = themeSel.name;
background = lockPng; package = themeSel.package;
greeters.gtk = {
enable = true;
theme = {
name = themeSel.name;
package = themeSel.package;
};
iconTheme = {
name = iconSel.name;
package = iconSel.package;
};
cursorTheme = {
name = cursorSel.name;
package = cursorSel.package;
} // lib.optionalAttrs (cursorSize != null) {
size = cursorSize;
};
# This includes your (rewritten) greeter config.
extraConfig = greeterFixed;
};
extraConfig = lightdmConf;
}; };
iconTheme = {
name = iconSel.name;
package = iconSel.package;
};
cursorTheme = {
name = cursorSel.name;
package = cursorSel.package;
} // lib.optionalAttrs (cursorSize != null) {
size = cursorSize;
};
# This includes your (rewritten) greeter config.
extraConfig = greeterFixed;
};
extraConfig = lightdmConf;
};
}; };
programs.hyprland.enable = true; programs.hyprland.enable = true;
# Optional: make them available system-wide as well # Optional: make them available system-wide as well
environment.systemPackages = [ environment.systemPackages = [
themeSel.package themeSel.package
iconSel.package iconSel.package
cursorSel.package cursorSel.package
]; ];
} }
@@ -1,14 +1,14 @@
{ pkgs, user, ... } : { pkgs, user, ... } :
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
tuigreet tuigreet
]; ];
services.greetd = { services.greetd = {
enable = true; enable = true;
settings = { settings = {
default_session = { default_session = {
command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a %h | %F'"; command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a %h | %F'";
};
};
}; };
};
};
} }
+15 -15
View File
@@ -1,21 +1,21 @@
{ pkgs, lib, ... }: { pkgs, lib, ... }:
{ {
networking = { networking = {
useDHCP = lib.mkDefault true; useDHCP = lib.mkDefault true;
networkmanager.enable = true; networkmanager.enable = true;
networkmanager.wifi.backend = "iwd"; networkmanager.wifi.backend = "iwd";
wireless.iwd.enable = true; wireless.iwd.enable = true;
wireless.userControlled.enable = true; wireless.userControlled.enable = true;
firewall = { firewall = {
enable = true; enable = true;
# KDE Connect: discovery + encrypted connections # KDE Connect: discovery + encrypted connections
allowedTCPPortRanges = [ allowedTCPPortRanges = [
{ from = 1714; to = 1764; } { from = 1714; to = 1764; }
]; ];
allowedUDPPortRanges = [ allowedUDPPortRanges = [
{ from = 1714; to = 1764; } { from = 1714; to = 1764; }
]; ];
}; };
}; };
environment.systemPackages = with pkgs; [ impala ]; environment.systemPackages = with pkgs; [ impala ];
} }
@@ -1,38 +1,38 @@
{ pkgs, user, ... } : { pkgs, user, ... } :
{ {
nix.settings = { nix.settings = {
# enable flakes # enable flakes
experimental-features = ["nix-command" "flakes"]; experimental-features = ["nix-command" "flakes"];
# add a cache that speed up new applications by downloading binaries # add a cache that speed up new applications by downloading binaries
# from the trusted cache instead of compiling from sourcer # from the trusted cache instead of compiling from sourcer
substituters = [ substituters = [
"https://nix-community.cachix.org" "https://nix-community.cachix.org"
]; ];
# trust the cache public key # trust the cache public key
trusted-public-keys = [ trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
]; ];
}; };
# allow proprietary software on this machine. I'm not a purist. # allow proprietary software on this machine. I'm not a purist.
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
# unityhub depends on this... for now # unityhub depends on this... for now
nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ]; nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ];
# this declares how often old configurations are cleared up. # this declares how often old configurations are cleared up.
# i cleanup anything older than a week, every week. # i cleanup anything older than a week, every week.
nix.gc = { nix.gc = {
automatic = true; automatic = true;
options = "--delete-older-than 7d"; options = "--delete-older-than 7d";
dates = "weekly"; dates = "weekly";
}; };
programs = { programs = {
# command line utility that makes applying changes easy and pretty # command line utility that makes applying changes easy and pretty
nh = { nh = {
enable = true; enable = true;
flake = "/home/${user.username}/system"; flake = "/home/${user.username}/system";
}; };
}; };
} }
+33 -33
View File
@@ -1,45 +1,45 @@
{ pkgs, user, ... } : { pkgs, user, ... } :
{ {
imports = [ imports = [
./apps/install_flatpaks.nix ./apps/install_flatpaks.nix
./apps/install_packages.nix ./apps/install_packages.nix
./core/files.nix ./core/files.nix
./core/locale.nix ./core/locale.nix
./core/networking.nix ./core/networking.nix
./core/nix-settings.nix ./core/nix-settings.nix
#./core/login-tuigreeter.nix #./core/login-tuigreeter.nix
./core/login-lightdm.nix ./core/login-lightdm.nix
./desktop/audio.nix ./desktop/audio.nix
./desktop/hyprland.nix ./desktop/hyprland.nix
./dev/terminal.nix ./dev/terminal.nix
./core/boot.nix ./core/boot.nix
./services/services.nix ./services/services.nix
]; ];
users.users.${user.username} = { users.users.${user.username} = {
isNormalUser = true; isNormalUser = true;
description = "henrov"; description = "henrov";
extraGroups = [ extraGroups = [
"networkmanager" # allow editing network connections "networkmanager" # allow editing network connections
"wheel" # can do sudo "wheel" # can do sudo
"scanner" # access to the network scanner "scanner" # access to the network scanner
"lp" # access to the printer "lp" # access to the printer
]; ];
}; };
fonts.packages = with pkgs; [ fonts.packages = with pkgs; [
aporetic aporetic
nerd-fonts.iosevka nerd-fonts.iosevka
]; ];
# enable the catppuccin theme for everything with mocha + blue accents # enable the catppuccin theme for everything with mocha + blue accents
catppuccin.enable = true; catppuccin.enable = true;
catppuccin.flavor = "mocha"; catppuccin.flavor = "mocha";
catppuccin.accent = "blue"; catppuccin.accent = "blue";
system.stateVersion = user.stateVersion; system.stateVersion = user.stateVersion;
} }
+45 -45
View File
@@ -2,21 +2,21 @@
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
pipewire pipewire
wireplumber wireplumber
alsa-utils alsa-utils
pulseaudio pulseaudio
pamixer pamixer
pavucontrol pavucontrol
]; ];
services.pipewire = { services.pipewire = {
enable = true; enable = true;
alsa.enable = true; alsa.enable = true;
alsa.support32Bit = true; alsa.support32Bit = true;
pulse.enable = true; pulse.enable = true;
jack.enable = true; jack.enable = true;
wireplumber.enable = true; wireplumber.enable = true;
}; };
security.rtkit.enable = true; security.rtkit.enable = true;
@@ -26,45 +26,45 @@
# Prefer analog over HDMI/DP in a machine-agnostic way # Prefer analog over HDMI/DP in a machine-agnostic way
services.pipewire.wireplumber.extraConfig."51-audio-priorities" = { services.pipewire.wireplumber.extraConfig."51-audio-priorities" = {
"monitor.alsa.rules" = [ "monitor.alsa.rules" = [
# De-prioritize HDMI / DisplayPort sinks # De-prioritize HDMI / DisplayPort sinks
{ {
matches = [ matches = [
{ "node.name" = "~alsa_output\\..*HDMI.*"; } { "node.name" = "~alsa_output\\..*HDMI.*"; }
{ "node.name" = "~alsa_output\\..*DisplayPort.*"; } { "node.name" = "~alsa_output\\..*DisplayPort.*"; }
];
actions.update-props = {
"priority.session" = 100;
"priority.driver" = 100;
};
}
# Prefer analog sinks (speakers/headphones)
{
matches = [
{ "node.name" = "~alsa_output\\..*analog.*"; }
{ "node.name" = "~alsa_output\\..*Headphones.*"; }
{ "node.name" = "~alsa_output\\..*Speaker.*"; }
];
actions.update-props = {
"priority.session" = 2000;
"priority.driver" = 2000;
};
}
]; ];
actions.update-props = {
"priority.session" = 100;
"priority.driver" = 100;
};
}
# Prefer analog sinks (speakers/headphones)
{
matches = [
{ "node.name" = "~alsa_output\\..*analog.*"; }
{ "node.name" = "~alsa_output\\..*Headphones.*"; }
{ "node.name" = "~alsa_output\\..*Speaker.*"; }
];
actions.update-props = {
"priority.session" = 2000;
"priority.driver" = 2000;
};
}
];
}; };
# Optional: clear "sticky" user-selected defaults so priority rules win # Optional: clear "sticky" user-selected defaults so priority rules win
systemd.user.services.wireplumber-clear-default-nodes = { systemd.user.services.wireplumber-clear-default-nodes = {
description = "Clear WirePlumber saved default nodes (avoid HDMI becoming sticky)"; description = "Clear WirePlumber saved default nodes (avoid HDMI becoming sticky)";
after = [ "wireplumber.service" ]; after = [ "wireplumber.service" ];
partOf = [ "wireplumber.service" ]; partOf = [ "wireplumber.service" ];
wantedBy = [ "default.target" ]; wantedBy = [ "default.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes"; ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes";
}; };
}; };
} }
+36 -36
View File
@@ -1,56 +1,56 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
nix.settings = { nix.settings = {
substituters = [ "https://hyprland.cachix.org" ]; substituters = [ "https://hyprland.cachix.org" ];
trusted-public-keys = [ trusted-public-keys = [
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
]; ];
}; };
services.dbus.enable = true; services.dbus.enable = true;
security.polkit.enable = true; security.polkit.enable = true;
services.flatpak.enable = true; services.flatpak.enable = true;
services.pipewire = { services.pipewire = {
enable = true; enable = true;
alsa.enable = true; alsa.enable = true;
alsa.support32Bit = true; alsa.support32Bit = true;
pulse.enable = true; pulse.enable = true;
wireplumber.enable = true; wireplumber.enable = true;
}; };
services.gvfs.enable = true; services.gvfs.enable = true;
xdg.portal = { xdg.portal = {
enable = true; enable = true;
extraPortals = with pkgs; [ extraPortals = with pkgs; [
xdg-desktop-portal-hyprland xdg-desktop-portal-hyprland
xdg-desktop-portal-gtk xdg-desktop-portal-gtk
]; ];
config.common.default = [ "hyprland" "gtk" ]; config.common.default = [ "hyprland" "gtk" ];
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
walker walker
uwsm uwsm
hyprland-qtutils hyprland-qtutils
hyprpolkitagent hyprpolkitagent
grimblast grimblast
]; ];
programs = { programs = {
uwsm.enable = true; uwsm.enable = true;
uwsm.waylandCompositors.hyprland = { uwsm.waylandCompositors.hyprland = {
prettyName = "Hyprland"; prettyName = "Hyprland";
comment = "Hyprland compositor managed by UWSM"; comment = "Hyprland compositor managed by UWSM";
binPath = "/run/current-system/sw/bin/Hyprland"; binPath = "/run/current-system/sw/bin/Hyprland";
}; };
hyprland = { hyprland = {
withUWSM = true; withUWSM = true;
enable = true; enable = true;
xwayland.enable = true; xwayland.enable = true;
}; };
}; };
environment.sessionVariables = { environment.sessionVariables = {
XDG_SESSION_TYPE = "wayland"; XDG_SESSION_TYPE = "wayland";
XDG_CURRENT_DESKTOP = "Hyprland"; XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_DESKTOP = "Hyprland"; XDG_SESSION_DESKTOP = "Hyprland";
NIXOS_OZONE_WL = "1"; NIXOS_OZONE_WL = "1";
XCURSOR_SIZE = "24"; XCURSOR_SIZE = "24";
}; };
security.pam.services.hyprlock = { }; security.pam.services.hyprlock = { };
# Optional; GNOME-specific (keep only if you really use gnome-keyring integration) # Optional; GNOME-specific (keep only if you really use gnome-keyring integration)
@@ -1,23 +1,23 @@
{ user, ...} : { user, ...} :
{ {
services = { services = {
blueman.enable = true; # bluetooth manager blueman.enable = true; # bluetooth manager
fwupd.enable = true; # firmware updating service fwupd.enable = true; # firmware updating service
fstrim.enable = true; # ssd maintenance service fstrim.enable = true; # ssd maintenance service
thermald.enable = true; # thermal regulation service thermald.enable = true; # thermal regulation service
printing.enable = true; # printing services, cups printing.enable = true; # printing services, cups
gnome.gnome-keyring.enable = true; # keyring gnome.gnome-keyring.enable = true; # keyring
flatpak.enable = true; # allow installing things from flatpaks flatpak.enable = true; # allow installing things from flatpaks
#flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo #flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# printer discovery # printer discovery
avahi = { avahi = {
enable = true; enable = true;
nssmdns4 = true; nssmdns4 = true;
openFirewall = true; openFirewall = true;
}; };
}; };
virtualisation.docker.enable = true; # enable docker virtualisation.docker.enable = true; # enable docker
users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group
} }
+81 -81
View File
@@ -1,89 +1,89 @@
{ {
description = "Henrov's nixos configuration"; description = "Henrov's nixos configuration";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = { home-manager = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
};
emacs-overlay = {
url = "github:nix-community/emacs-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
catppuccin = {
url = "github:catppuccin/nix";
inputs.nixpkgs.follows = "nixpkgs";
};
zen-browser = {
url = "github:youwen5/zen-browser-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs@{
nixpkgs,
home-manager,
emacs-overlay,
catppuccin,
...
}:
let
user = import ./user.nix;
lib = nixpkgs.lib;
machines = [
"traveldroid"
];
pkgs = import nixpkgs {
inherit (user) system;
};
in
{
nixosConfigurations = builtins.listToAttrs (
builtins.map (machine: {
name = machine;
value = lib.nixosSystem {
modules = [
({ ... }: {
nixpkgs.overlays = [ emacs-overlay.overlays.default ];
})
./machines/${machine}/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = {
inherit user inputs;
flakeRoot = inputs.self;
}; };
emacs-overlay = {
url = "github:nix-community/emacs-overlay"; home-manager.backupFileExtension = "backup";
inputs.nixpkgs.follows = "nixpkgs"; home-manager.users.${user.username} = {
}; imports = [
catppuccin = { ./machines/${machine}/home.nix
url = "github:catppuccin/nix"; catppuccin.homeModules.catppuccin
inputs.nixpkgs.follows = "nixpkgs"; ];
}; };
zen-browser = { }
url = "github:youwen5/zen-browser-flake";
inputs.nixpkgs.follows = "nixpkgs"; catppuccin.nixosModules.catppuccin # theme
];
specialArgs = {
hostname = machine;
inherit user;
inherit inputs;
flakeRoot = inputs.self;
}; };
}; };
outputs = inputs@{ }) machines
nixpkgs, );
home-manager,
emacs-overlay,
catppuccin,
...
}:
let
user = import ./user.nix;
lib = nixpkgs.lib;
machines = [
"traveldroid"
];
pkgs = import nixpkgs {
inherit (user) system;
};
in
{
nixosConfigurations = builtins.listToAttrs (
builtins.map (machine: {
name = machine;
value = lib.nixosSystem {
modules = [
({ ... }: {
nixpkgs.overlays = [ emacs-overlay.overlays.default ];
})
./machines/${machine}/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { devShells.${user.system}.default = pkgs.mkShell {
inherit user inputs; buildInputs = with pkgs; [
flakeRoot = inputs.self; nil
}; nixfmt-rfc-style
];
home-manager.backupFileExtension = "backup"; };
home-manager.users.${user.username} = { };
imports = [
./machines/${machine}/home.nix
catppuccin.homeModules.catppuccin
];
};
}
catppuccin.nixosModules.catppuccin # theme
];
specialArgs = {
hostname = machine;
inherit user;
inherit inputs;
flakeRoot = inputs.self;
};
};
}) machines
);
devShells.${user.system}.default = pkgs.mkShell {
buildInputs = with pkgs; [
nil
nixfmt-rfc-style
];
};
};
} }
+16 -16
View File
@@ -1,23 +1,23 @@
{ pkgs, lib, user, config, ...} : { pkgs, lib, user, config, ...} :
{ {
nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu
# update cpu microcode with firmware that allows redistribution # update cpu microcode with firmware that allows redistribution
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware = { hardware = {
# always enable bluetooth # always enable bluetooth
bluetooth.enable = true; bluetooth.enable = true;
# always enable graphics drivers and enable a bunch of layers for it (including vulkan validation) # always enable graphics drivers and enable a bunch of layers for it (including vulkan validation)
graphics = { graphics = {
enable = true; enable = true;
extraPackages = with pkgs; [ extraPackages = with pkgs; [
vulkan-validation-layers # helps catch and debug vulkan crashes vulkan-validation-layers # helps catch and debug vulkan crashes
]; ];
}; };
}; };
hardware.enableAllFirmware = true; # enable all firmware regardless of license hardware.enableAllFirmware = true; # enable all firmware regardless of license
} }
+3 -3
View File
@@ -2,8 +2,8 @@
{ {
xdg.mimeApps.enable = true; xdg.mimeApps.enable = true;
xdg.mimeApps.defaultApplications = { xdg.mimeApps.defaultApplications = {
"x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ];
"x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ];
"text/html" = [ "app.zen_browser.zen.desktop" ]; "text/html" = [ "app.zen_browser.zen.desktop" ];
}; };
} }
+3 -3
View File
@@ -7,8 +7,8 @@ in
{ {
services.ollama = { services.ollama = {
enable = true; enable = true;
package = pkgs.ollama; package = pkgs.ollama;
environmentVariables = envVars; environmentVariables = envVars;
}; };
} }
+19 -19
View File
@@ -1,22 +1,22 @@
{ pkgs, ...}: { pkgs, ...}:
{ {
gtk = { gtk = {
enable = true; enable = true;
colorScheme = "dark"; colorScheme = "dark";
theme = { theme = {
name = "Catppuccin-GTK-Grey-Dark-Compact"; name = "Catppuccin-GTK-Grey-Dark-Compact";
package = (pkgs.magnetic-catppuccin-gtk.override { package = (pkgs.magnetic-catppuccin-gtk.override {
accent = [ "grey" ]; accent = [ "grey" ];
shade = "dark"; shade = "dark";
tweaks = [ "black" ]; tweaks = [ "black" ];
size = "compact"; size = "compact";
}); });
}; };
iconTheme.name = "Papirus-Dark"; iconTheme.name = "Papirus-Dark";
}; };
catppuccin.enable = true; catppuccin.enable = true;
catppuccin.flavor = "mocha"; catppuccin.flavor = "mocha";
catppuccin.accent = "blue"; catppuccin.accent = "blue";
catppuccin.gtk.icon.enable = true; catppuccin.gtk.icon.enable = true;
catppuccin.cursors.enable = true; catppuccin.cursors.enable = true;
} }
+28 -28
View File
@@ -1,35 +1,35 @@
{ pkgs, user, ... } : { pkgs, user, ... } :
{ {
imports = [ imports = [
./apps/ollama.nix ./apps/ollama.nix
#./apps/default-apps.nix #./apps/default-apps.nix
./apps/theme.nix ./apps/theme.nix
./desktop/hypridle.nix ./desktop/hypridle.nix
./desktop/hyprland.nix ./desktop/hyprland.nix
./desktop/hyprexpo.nix ./desktop/hyprexpo.nix
./desktop/hyprlock.nix ./desktop/hyprlock.nix
./desktop/hyprscrolling.nix ./desktop/hyprscrolling.nix
./desktop/hyprshell.nix ./desktop/hyprshell.nix
./desktop/ncsway.nix ./desktop/ncsway.nix
./desktop/powermenu.nix ./desktop/powermenu.nix
#./desktop/animated_wallpaper.nix #./desktop/animated_wallpaper.nix
#./desktop/rotating_wallpaper.nix #./desktop/rotating_wallpaper.nix
./desktop/workspace_wallpaper.nix ./desktop/workspace_wallpaper.nix
./desktop/waybar.nix ./desktop/waybar.nix
./desktop/walker.nix ./desktop/walker.nix
./dev/dev.nix ./dev/dev.nix
./dev/kitty.nix ./dev/kitty.nix
./dev/shells.nix ./dev/shells.nix
./dev/starship.nix ./dev/starship.nix
./dev/zsh.nix ./dev/zsh.nix
./dev/emacs ./dev/emacs
]; ];
home.username = "${user.username}"; home.username = "${user.username}";
home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}"; home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}";
home.stateVersion = user.stateVersion; home.stateVersion = user.stateVersion;
programs.home-manager.enable = true; programs.home-manager.enable = true;
} }
@@ -7,44 +7,44 @@ let
userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4"; userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4";
# (keep your existing approach: sync the repo wallpaper dir to the user dir) # (keep your existing approach: sync the repo wallpaper dir to the user dir)
repoWallpapersOnly = lib.cleanSourceWith { repoWallpapersOnly = lib.cleanSourceWith {
src = repoWallpaperDir; src = repoWallpaperDir;
filter = path: type: true; filter = path: type: true;
}; };
in in
{ {
home.packages = [ home.packages = [
pkgs.mpvpaper pkgs.mpvpaper
pkgs.mpv pkgs.mpv
]; ];
# Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff # Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff
home.file."${userRelRoot}" = { home.file."${userRelRoot}" = {
source = repoWallpapersOnly; source = repoWallpapersOnly;
recursive = true; recursive = true;
}; };
systemd.user.services.mpvpaper-wallpaper = { systemd.user.services.mpvpaper-wallpaper = {
Unit = { Unit = {
Description = "Video wallpaper (mpvpaper)"; Description = "Video wallpaper (mpvpaper)";
After = [ "graphical-session.target" ]; After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Service = { Service = {
Type = "simple"; Type = "simple";
# -p auto-pause saves resources when the wallpaper surface is hidden. # -p auto-pause saves resources when the wallpaper surface is hidden.
# '*' applies to all outputs. # '*' applies to all outputs.
# Stretch-to-fill (cover) behavior: # Stretch-to-fill (cover) behavior:
# --panscan=1.0 fills the entire output by cropping (no letterboxing). # --panscan=1.0 fills the entire output by cropping (no letterboxing).
# If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead.
ExecStart = '' ExecStart = ''
${pkgs.mpvpaper}/bin/mpvpaper \ ${pkgs.mpvpaper}/bin/mpvpaper \
-p \ -p \
-o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \
'*' "${userVideoPath}" '*' "${userVideoPath}"
''; '';
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install = { Install = {
WantedBy = [ "graphical-session.target" ]; WantedBy = [ "graphical-session.target" ];
}; };
}; };
} }
+20 -20
View File
@@ -1,28 +1,28 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
# Load the Hyprexpo plugin (from nixpkgs) # Load the Hyprexpo plugin (from nixpkgs)
plugins = [ plugins = [
pkgs.hyprlandPlugins.hyprexpo pkgs.hyprlandPlugins.hyprexpo
]; ];
# Append plugin config + keybind after your existing hyprland.conf # Append plugin config + keybind after your existing hyprland.conf
extraConfig = lib.mkAfter '' extraConfig = lib.mkAfter ''
############################ ############################
# Hyprexpo (workspace/window overview) # Hyprexpo (workspace/window overview)
############################ ############################
# Basic plugin config (tweak as you like) # Basic plugin config (tweak as you like)
plugin { plugin {
hyprexpo { hyprexpo {
columns = 3 columns = 3
gaps_in = 5 gaps_in = 5
gaps_out = 20 gaps_out = 20
# Optional; comment out if you don't want it # Optional; comment out if you don't want it
# workspace_method = center current # workspace_method = center current
} }
} }
''; '';
}; };
} }
+2 -1
View File
@@ -4,5 +4,6 @@ let
in in
{ {
home.packages = [ pkgs.hypridle ]; home.packages = [ pkgs.hypridle ];
xdg.configFile."hypr/hypridle.conf".source = hypridleConf; xdg.configFile."hypr/hypridle.conf".source = lib.mkForce hypridleConf;
xdg.configFile."hypr/hypridle.conf".backup = lib.mkForce false ;
} }
+28 -27
View File
@@ -1,40 +1,41 @@
{ config, lib, pkgs, flakeRoot, ... }: { config, lib, pkgs, flakeRoot, ... }:
let let
hyprConf = flakeRoot + "/assets/conf/desktop/hypr/hyprland.conf"; hyprConf = flakeRoot + "/assets/conf/desktop/hypr/hyprland.conf";
bindingsConf = flakeRoot + "/assets/conf/desktop/hypr/bindings.conf"; bindingsConf = flakeRoot + "/assets/conf/desktop/hypr/bindings.conf";
in in
{ {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
# Load base config + bindings from repo files # Load base config + bindings from repo files
extraConfig = extraConfig =
(builtins.readFile hyprConf) (builtins.readFile hyprConf)
+ "\n\n# --- Repo keybindings ---\n" + "\n\n# --- Repo keybindings ---\n"
+ (builtins.readFile bindingsConf) + (builtins.readFile bindingsConf)
+ "\n"; + "\n";
settings = { settings = {
windowrule = [ windowrule = [
"match:class nm-connection-editor, float 1, center 1, size 900 700" "match:class nm-connection-editor, float 1, center 1, size 900 700"
]; ];
}; };
}; };
xdg.configFile."hypr/scripts/lid-lock.sh" = { xdg.configFile."hypr/scripts/lid-lock.sh" = {
source = flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh"; source = lib.mkForce flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh";
executable = true; backup = lib.mkForce false;
executable = true;
}; };
xdg.portal = { xdg.portal = {
enable = true; enable = true;
extraPortals = with pkgs; [ extraPortals = with pkgs; [
xdg-desktop-portal-gtk xdg-desktop-portal-gtk
xdg-desktop-portal-hyprland xdg-desktop-portal-hyprland
]; ];
# GTK als algemene backend (OpenURI is daar betrouwbaar) # GTK als algemene backend (OpenURI is daar betrouwbaar)
config.common.default = [ "gtk" ]; config.common.default = [ "gtk" ];
# Hyprland alleen voor screensharing / remote desktop # Hyprland alleen voor screensharing / remote desktop
config.hyprland = { config.hyprland = {
"org.freedesktop.impl.portal.Screencast" = [ "hyprland" ]; "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
"org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ]; "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ];
}; };
}; };
} }
+5 -3
View File
@@ -1,10 +1,12 @@
{config, lib, pkgs, flakeRoot, ... }: {config, lib, pkgs, flakeRoot, ... }:
let let
lockPngSrc = flakeRoot + "/assets/lock.png"; lockPngSrc = flakeRoot + "/assets/lock.png";
hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf"; hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf";
in in
{ {
home.packages = [ pkgs.hyprlock ]; home.packages = [ pkgs.hyprlock ];
xdg.configFile."hypr/lock.png".source = lockPngSrc; xdg.configFile."hypr/lock.png".source = lib.mkForce lockPngSrc;
xdg.configFile."hypr/hyprlock.conf".source = hyprlockConf; xdg.configFile."hypr/lock.png".backup = lib.mkForce false;
xdg.configFile."hypr/hyprlock.conf".source = lib.mkForce hyprlockConf;
xdg.configFile."hypr/hyprlock.conf".backup = lib.mkForce false;
} }
+20 -17
View File
@@ -11,37 +11,40 @@ let
targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh"; targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh";
# Facilitate switching between scrolling and dwindle # Facilitate switching between scrolling and dwindle
repoSwitchScript = repoSwitchScript =
flakeRoot + "/assets/conf/desktop/hypr/scripts/toggle-layout-scrolling-dwindle.sh"; flakeRoot + "/assets/conf/desktop/hypr/scripts/toggle-layout-scrolling-dwindle.sh";
targetSwitchScript = "hypr/scripts/toggle-layout-scrolling-dwindle.sh"; targetSwitchScript = "hypr/scripts/toggle-layout-scrolling-dwindle.sh";
in in
{ {
# Ensure deps for the script exist at runtime # Ensure deps for the script exist at runtime
# (hyprctl comes with Hyprland; jq is often not installed by default) # (hyprctl comes with Hyprland; jq is often not installed by default)
home.packages = with pkgs; [ home.packages = with pkgs; [
jq jq
]; ];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
plugins = [ plugins = [
pkgs.hyprlandPlugins.hyprscrolling pkgs.hyprlandPlugins.hyprscrolling
]; ];
extraConfig = '' extraConfig = ''
source = ~/.config/${targetRel} source = ~/.config/${targetRel}
''; '';
}; };
# Copy repo configs/scripts into ~/.config # Copy repo configs/scripts into ~/.config
xdg.configFile."${targetRel}".source = repoConf; xdg.configFile."${targetRel}".source = lib.mkForce repoConf;
xdg.configFile."${targetRel}".backup = lib.mkForce false;
xdg.configFile."${targetOverflowRel}" = { xdg.configFile."${targetOverflowRel}" = {
source = repoOverflowScript; source = lib.mkForce repoOverflowScript;
executable = true; # makes it chmod +x backup = lib.mkForce false;
executable = true; # makes it chmod +x
}; };
xdg.configFile."${targetPerMonitor}" = { xdg.configFile."${targetPerMonitor}" = {
source = repoPerMonitorScript; source = lib.mkForce repoPerMonitorScript;
executable = true; # makes it chmod +x backup = lib.mkForce false;
executable = true; # makes it chmod +x
}; };
xdg.configFile."${targetSwitchScript}" = { xdg.configFile."${targetSwitchScript}" = {
source = repoSwitchScript; source = lib.mkForce repoSwitchScript;
executable = true; # makes it chmod +x backup = lib.mkForce false;
executable = true; # makes it chmod +x
}; };
} }
+17 -15
View File
@@ -9,22 +9,24 @@ in
xdg.enable = true; xdg.enable = true;
home.packages = [ pkgs.hyprshell ]; home.packages = [ pkgs.hyprshell ];
# Link repo -> ~/.config/hyprshell/... # Link repo -> ~/.config/hyprshell/...
xdg.configFile."hyprshell/config.ron".source = cfgRon; xdg.configFile."hyprshell/config.ron".source = lib.mkForce cfgRon;
xdg.configFile."hyprshell/styles.css".source = cssFile; xdg.configFile."hyprshell/config.ron".backup = lib.mkForce false;
xdg.configFile."hyprshell/styles.css".source = lib.mkForce cssFile;
xdg.configFile."hyprshell/styles.css".backup = lib.mkForce false;
# Autostart (systemd user service) # Autostart (systemd user service)
systemd.user.services.hyprshell = { systemd.user.services.hyprshell = {
Unit = { Unit = {
Description = "Hyprshell (window switcher / launcher)"; Description = "Hyprshell (window switcher / launcher)";
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ]; After = [ "graphical-session.target" ];
}; };
Service = { Service = {
ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; ExecStart = "${pkgs.hyprshell}/bin/hyprshell";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install = { Install = {
WantedBy = [ "graphical-session.target" ]; WantedBy = [ "graphical-session.target" ];
}; };
}; };
} }
+4 -3
View File
@@ -1,13 +1,14 @@
{ config, lib, pkgs, flakeRoot, ... }: { config, lib, pkgs, flakeRoot, ... }:
let let
repoScript = repoScript =
flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh"; flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh";
targetRel = "hypr/scripts/powermenu.sh"; targetRel = "hypr/scripts/powermenu.sh";
in in
{ {
# Ensure script exists in ~/.config/hypr/scripts/ # Ensure script exists in ~/.config/hypr/scripts/
xdg.configFile."${targetRel}" = { xdg.configFile."${targetRel}" = {
source = repoScript; source = lib.mkForce repoScript;
executable = true; backup = lib.mkForce false;
executable = true;
}; };
} }
@@ -8,35 +8,35 @@ let
userConfPath = "${userAbsRoot}/wallpaper.conf"; userConfPath = "${userAbsRoot}/wallpaper.conf";
# Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions) # Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions)
repoWallpapersOnly = lib.cleanSourceWith { repoWallpapersOnly = lib.cleanSourceWith {
src = repoWallpaperDir; src = repoWallpaperDir;
filter = path: type: filter = path: type:
(builtins.baseNameOf path) != "wallpaper.conf"; (builtins.baseNameOf path) != "wallpaper.conf";
}; };
in in
{ {
home.packages = [ pkgs.wpaperd ]; home.packages = [ pkgs.wpaperd ];
# Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff # Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff
home.file."${userRelRoot}" = { home.file."${userRelRoot}" = {
source = repoWallpapersOnly; source = repoWallpapersOnly;
recursive = true; recursive = true;
}; };
# Now safely overwrite the config every activation (no HM collision) # Now safely overwrite the config every activation (no HM collision)
home.activation.wallpaperConfForce = home.activation.wallpaperConfForce =
lib.hm.dag.entryAfter [ "writeBoundary" ] '' lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -euo pipefail set -euo pipefail
mkdir -p "${userAbsRoot}" mkdir -p "${userAbsRoot}"
install -m 0644 "${repoWallpaperConf}" "${userConfPath}" install -m 0644 "${repoWallpaperConf}" "${userConfPath}"
''; '';
systemd.user.services.wpaperd = { systemd.user.services.wpaperd = {
Unit = { Unit = {
Description = "wpaperd wallpaper daemon"; Description = "wpaperd wallpaper daemon";
After = [ "default.target" ]; After = [ "default.target" ];
}; };
Service = { Service = {
Type = "simple"; Type = "simple";
ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install.WantedBy = [ "default.target" ]; Install.WantedBy = [ "default.target" ];
; ;
+13 -9
View File
@@ -1,13 +1,13 @@
{ config, pkgs, lib, flakeRoot, inputs ? null, ... }: { config, pkgs, lib, flakeRoot, inputs ? null, ... }:
let let
walkerPkg = walkerPkg =
if inputs != null && inputs ? walker if inputs != null && inputs ? walker
then inputs.walker.packages.${pkgs.system}.default then inputs.walker.packages.${pkgs.system}.default
else pkgs.walker; else pkgs.walker;
elephantPkg = elephantPkg =
if inputs != null && inputs ? elephant if inputs != null && inputs ? elephant
then inputs.elephant.packages.${pkgs.system}.default then inputs.elephant.packages.${pkgs.system}.default
else pkgs.elephant; else pkgs.elephant;
sessionTarget = "graphical-session.target"; sessionTarget = "graphical-session.target";
# All theme files now live here # All theme files now live here
repoThemesDir = flakeRoot + "/assets/conf/desktop/walker"; repoThemesDir = flakeRoot + "/assets/conf/desktop/walker";
@@ -16,11 +16,15 @@ in
xdg.enable = true; xdg.enable = true;
home.packages = [ walkerPkg elephantPkg ]; home.packages = [ walkerPkg elephantPkg ];
# ~/.config/walker/themes/* # ~/.config/walker/themes/*
xdg.configFile."walker/themes/frosted/default.css".source = repoThemesDir + "/themes/frosted/default.css"; xdg.configFile."walker/themes/frosted/default.css".source = lib.mkForce repoThemesDir + "/themes/frosted/default.css";
xdg.configFile."walker/themes/frosted/default.css".backup = lib.mkForce false;
xdg.configFile."walker/themes/frosted/style.css".source = repoThemesDir + "/themes/frosted/style.css"; xdg.configFile."walker/themes/frosted/style.css".source = repoThemesDir + "/themes/frosted/style.css";
xdg.configFile."walker/themes/frosted/style.css".backup = lib.mkForce false;
xdg.configFile."walker/config.toml".source = repoThemesDir + "/config.toml"; xdg.configFile."walker/config.toml".source = repoThemesDir + "/config.toml";
# xdg.configFile."walker/themes/default.html".source = repoThemesDir + "/default.html"; xdg.configFile."walker/config.toml".backup = lib.mkForce false;
# xdg.configFile."walker/themes/default.html".source = lib.mkForce repoThemesDir + "/default.html";
# xdg.configFile."walker/themes/default.html".backup = lib.mkForce false;
# (services unchanged) # (services unchanged)
systemd.user.services.elephant = { /* ... your existing service ... */ }; systemd.user.services.elephant = { /* ... your existing service ... */ };
systemd.user.services.walker = { /* ... your existing service ... */ }; systemd.user.services.walker = { /* ... your existing service ... */ };
} }
+6 -4
View File
@@ -6,14 +6,16 @@ in
programs.waybar.enable = true; programs.waybar.enable = true;
# Ensure config matches repo (HM-managed symlink, not user-editable) # Ensure config matches repo (HM-managed symlink, not user-editable)
xdg.configFile."waybar/config" = { xdg.configFile."waybar/config" = {
source = repoWaybarDir + "/config.jsonc"; source = lib.mkForce repoWaybarDir + "/config.jsonc";
force = true; backup = lib.mkForce false;
force = true;
}; };
# Override HM's internally-generated waybar-style.css derivation # Override HM's internally-generated waybar-style.css derivation
# and use your repo file instead. # and use your repo file instead.
xdg.configFile."waybar/style.css" = { xdg.configFile."waybar/style.css" = {
source = lib.mkForce (repoWaybarDir + "/style.css"); source = lib.mkForce (repoWaybarDir + "/style.css");
force = true; backup = lib.mkForce false;
force = true;
}; };
# Prevent HM from also trying to generate style content via programs.waybar.style # Prevent HM from also trying to generate style content via programs.waybar.style
# (not strictly required once mkForce is in place, but keeps intent clear) # (not strictly required once mkForce is in place, but keeps intent clear)
+159 -156
View File
@@ -7,197 +7,200 @@ let
# (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff # (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff
repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper"; repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper";
repoWallpapersOnly = lib.cleanSourceWith { repoWallpapersOnly = lib.cleanSourceWith {
src = repoWallpaperDir; src = repoWallpaperDir;
filter = path: type: true; filter = path: type: true;
}; };
daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh"; daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh";
setRel = "hypr/scripts/set-wallpaper.sh"; setRel = "hypr/scripts/set-wallpaper.sh";
in in
{ {
home.packages = [ home.packages = [
pkgs.hyprpaper pkgs.hyprpaper
pkgs.socat pkgs.socat
pkgs.jq pkgs.jq
pkgs.findutils pkgs.findutils
pkgs.coreutils pkgs.coreutils
pkgs.gnused pkgs.gnused
pkgs.gawk pkgs.gawk
]; ];
# Keep your existing "sync wallpapers into a writable dir" pattern # Keep your existing "sync wallpapers into a writable dir" pattern
home.file."${userRelRoot}" = { home.file."${userRelRoot}" = {
source = repoWallpapersOnly; source = repoWallpapersOnly;
recursive = true; recursive = true;
}; };
# Hyprpaper config (hyprpaper reads this; it does NOT need to write it) # Hyprpaper config (hyprpaper reads this; it does NOT need to write it)
# `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0} # `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0}
xdg.configFile."hypr/hyprpaper.conf".text = '' xdg.configFile."hypr/hyprpaper.conf".text = lib.mkForce ''
ipc = true ipc = true
splash = false splash = false
''; '';
xdg.configFile."hypr/hyprpaper.conf".backup = lib.mkForce false;
# Workspace wallpaper daemon: listens to socket2, applies w-<id>=... mapping # Workspace wallpaper daemon: listens to socket2, applies w-<id>=... mapping
# Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1} # Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1}
xdg.configFile."${daemonRel}" = { xdg.configFile."${daemonRel}" = {
executable = true; executable = true;
text = '' text = lib.mkForce ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
: "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}"
: "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}"
SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
[[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
PICTURES_DIR="''${1:-${picturesDir}}" PICTURES_DIR="''${1:-${picturesDir}}"
FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2} FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2}
HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
focused_monitor() { focused_monitor() {
hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
} }
map_file_for_monitor() { map_file_for_monitor() {
local mon="''${1}" local mon="''${1}"
echo "''${MAP_ROOT}/''${mon}/defaults.conf" echo "''${MAP_ROOT}/''${mon}/defaults.conf"
} }
ensure_map_file() { ensure_map_file() {
local mon="''${1}" local mon="''${1}"
local f local f
f="$(map_file_for_monitor "''${mon}")" f="$(map_file_for_monitor "''${mon}")"
mkdir -p "$(dirname "''${f}")" mkdir -p "$(dirname "''${f}")"
if [[ ! -f "''${f}" ]]; then if [[ ! -f "''${f}" ]]; then
# Seed with 1..9 from picturesDir if present, else empty entries # Seed with 1..9 from picturesDir if present, else empty entries
{ {
for i in 1 2 3 4 5 6 7 8 9; do for i in 1 2 3 4 5 6 7 8 9; do
seed="$(ls -1 "''${PICTURES_DIR}/''${i}."* 2>/dev/null | head -n 1 || true)" seed="$(ls -1 "''${PICTURES_DIR}/''${i}."* 2>/dev/null | head -n 1 || true)"
echo "w-''${i}= ''${seed}" echo "w-''${i}= ''${seed}"
done done
} > "''${f}" } > "''${f}"
fi fi
echo "''${f}" echo "''${f}"
} }
get_wall_for_ws() { get_wall_for_ws() {
local mon="''${1}" local mon="''${1}"
local wsid="''${2}" local wsid="''${2}"
local f key val local f key val
f="$(ensure_map_file "''${mon}")" f="$(ensure_map_file "''${mon}")"
key="w-''${wsid}" key="w-''${wsid}"
# accept "w-1=/path" or "w-1= /path" # accept "w-1=/path" or "w-1= /path"
val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)" val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)"
echo "''${val}" echo "''${val}"
} }
apply_wallpaper() { apply_wallpaper() {
local mon="''${1}" local mon="''${1}"
local wsid="''${2}" local wsid="''${2}"
local file local file
file="$(get_wall_for_ws "''${mon}" "''${wsid}")" file="$(get_wall_for_ws "''${mon}" "''${wsid}")"
[[ -n "''${file}" ]] || return 0 [[ -n "''${file}" ]] || return 0
[[ -f "''${file}" ]] || return 0 [[ -f "''${file}" ]] || return 0
# Apply via IPC # Apply via IPC
# hyprpaper wallpaper { monitor path fit_mode } model is per monitor. :contentReference[oaicite:3]{index=3} # hyprpaper wallpaper { monitor path fit_mode } model is per monitor. :contentReference[oaicite:3]{index=3}
hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null
} }
# Initial apply on startup # Initial apply on startup
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
handle() { handle() {
local line="''${1}" local line="''${1}"
case "''${line}" in case "''${line}" in
workspacev2* ) workspacev2* )
# workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4} # workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4}
local payload wsid local payload wsid
payload="''${line#*>>}" payload="''${line#*>>}"
wsid="''${payload%%,*}" wsid="''${payload%%,*}"
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
;; ;;
focusedmon* ) focusedmon* )
# focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5} # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5}
# When monitor focus changes, re-apply for the active workspace id. # When monitor focus changes, re-apply for the active workspace id.
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
;; ;;
esac esac
} }
socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do
handle "''${line}" || true handle "''${line}" || true
done done
''; '';
backup = lib.mkForce false;
}; };
# CLI setter in the style of your inspiration script. # CLI setter in the style of your inspiration script.
# Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper] # Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper]
xdg.configFile."${setRel}" = { xdg.configFile."${setRel}" = {
executable = true; executable = true;
text = '' text = lib.mkForce ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
usage() { usage() {
echo "Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper_path]" echo "Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper_path]"
} }
wsid="''${1:-}" wsid="''${1:-}"
mon="''${2:-}" mon="''${2:-}"
wp="''${3:-}" wp="''${3:-}"
[[ -n "''${wsid}" ]] || { usage; exit 1; } [[ -n "''${wsid}" ]] || { usage; exit 1; }
[[ -n "''${mon}" ]] || { usage; exit 1; } [[ -n "''${mon}" ]] || { usage; exit 1; }
cfg="''${MAP_ROOT}/''${mon}/defaults.conf" cfg="''${MAP_ROOT}/''${mon}/defaults.conf"
mkdir -p "$(dirname "''${cfg}")" mkdir -p "$(dirname "''${cfg}")"
[[ -f "''${cfg}" ]] || touch "''${cfg}" [[ -f "''${cfg}" ]] || touch "''${cfg}"
if [[ -z "''${wp}" ]]; then if [[ -z "''${wp}" ]]; then
# Random pick from your defaults folder if you want; adjust path if needed: # Random pick from your defaults folder if you want; adjust path if needed:
wp="$(find "$HOME/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)" wp="$(find "$HOME/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)"
[[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
fi fi
# Ensure key exists; if not, append it # Ensure key exists; if not, append it
key="w-''${wsid}" key="w-''${wsid}"
if ! grep -q "^''${key}=" "''${cfg}"; then if ! grep -q "^''${key}=" "''${cfg}"; then
echo "''${key}=" >> "''${cfg}" echo "''${key}=" >> "''${cfg}"
fi fi
# Set mapping # Set mapping
${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}" ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}"
# If this monitor is currently showing that workspace id, apply immediately # If this monitor is currently showing that workspace id, apply immediately
curws="$(hyprctl -j monitors | jq -r --arg m "''${mon}" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)" curws="$(hyprctl -j monitors | jq -r --arg m "''${mon}" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)"
if [[ "''${curws}" == "''${wsid}" ]]; then if [[ "''${curws}" == "''${wsid}" ]]; then
hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null
fi fi
''; '';
backup = lib.mkForce false;
}; };
# Services # Services
systemd.user.services.hyprpaper = { systemd.user.services.hyprpaper = {
Unit = { Unit = {
Description = "hyprpaper wallpaper daemon"; Description = "hyprpaper wallpaper daemon";
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ]; After = [ "graphical-session.target" ];
}; };
Service = { Service = {
ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper"; ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };
}; };
systemd.user.services.hyprpaper-ws-daemon = { systemd.user.services.hyprpaper-ws-daemon = {
Unit = { Unit = {
Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" "hyprpaper.service" ]; After = [ "graphical-session.target" "hyprpaper.service" ];
}; };
Service = { Service = {
ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}"; ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };
}; };
} }
+1
View File
@@ -7,6 +7,7 @@ in
programs.alacritty.enable = true; programs.alacritty.enable = true;
# Override the config generated by programs.alacritty # Override the config generated by programs.alacritty
xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf; xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf;
xdg.configFile."alacritty/alacritty.toml".backup = lib.mkForce false
catppuccin.alacritty.enable = true; catppuccin.alacritty.enable = true;
catppuccin.alacritty.flavor = "mocha"; catppuccin.alacritty.flavor = "mocha";
} }
+36 -36
View File
@@ -1,42 +1,42 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
{ {
programs = { programs = {
vscode.enable = true; vscode.enable = true;
vim.enable = true; vim.enable = true;
ripgrep.enable = true; ripgrep.enable = true;
btop.enable = true; btop.enable = true;
fzf = { fzf = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true; enableBashIntegration = true;
}; };
zoxide = { zoxide = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true; enableBashIntegration = true;
}; };
eza = { eza = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true; enableBashIntegration = true;
}; };
direnv = { direnv = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true; enableBashIntegration = true;
nix-direnv.enable = true; nix-direnv.enable = true;
}; };
# Zsh-specific config belongs here # Zsh-specific config belongs here
zsh = { zsh = {
# for emacs-eat package # for emacs-eat package
initContent = lib.mkOrder 1200 '' initContent = lib.mkOrder 1200 ''
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \ [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \
source "$EAT_SHELL_INTEGRATION_DIR/zsh" source "$EAT_SHELL_INTEGRATION_DIR/zsh"
''; '';
}; };
git = { git = {
enable = true; enable = true;
lfs.enable = true; lfs.enable = true;
}; };
}; };
} }
+64 -64
View File
@@ -1,67 +1,67 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
programs.emacs = { programs.emacs = {
enable = true; enable = true;
# install with tree sitter enabled # install with tree sitter enabled
package = (pkgs.emacs-pgtk.override { withTreeSitter = true; }); package = (pkgs.emacs-pgtk.override { withTreeSitter = true; });
extraPackages = epkgs: [ extraPackages = epkgs: [
# also install all tree sitter grammars # also install all tree sitter grammars
epkgs.manualPackages.treesit-grammars.with-all-grammars epkgs.manualPackages.treesit-grammars.with-all-grammars
epkgs.nerd-icons # nerd fonts support epkgs.nerd-icons # nerd fonts support
epkgs.doom-modeline # model line epkgs.doom-modeline # model line
epkgs.diminish # hides modes from modeline epkgs.diminish # hides modes from modeline
epkgs.eldoc # doc support epkgs.eldoc # doc support
epkgs.pulsar # pulses the cursor when jumping about epkgs.pulsar # pulses the cursor when jumping about
epkgs.which-key # help porcelain epkgs.which-key # help porcelain
epkgs.expreg # expand region epkgs.expreg # expand region
epkgs.vundo # undo tree epkgs.vundo # undo tree
epkgs.puni # structured editing epkgs.puni # structured editing
epkgs.avy # jumping utility epkgs.avy # jumping utility
epkgs.consult # emacs right click epkgs.consult # emacs right click
epkgs.vertico # minibuffer completion epkgs.vertico # minibuffer completion
epkgs.marginalia # annotations for completions epkgs.marginalia # annotations for completions
epkgs.crux # utilities epkgs.crux # utilities
epkgs.magit # git porcelain epkgs.magit # git porcelain
epkgs.nerd-icons-corfu # nerd icons for completion epkgs.nerd-icons-corfu # nerd icons for completion
epkgs.corfu # completion epkgs.corfu # completion
epkgs.cape # completion extensions epkgs.cape # completion extensions
epkgs.orderless # search paradigm epkgs.orderless # search paradigm
epkgs.yasnippet # snippets support epkgs.yasnippet # snippets support
epkgs.yasnippet-snippets # commonly used snippets epkgs.yasnippet-snippets # commonly used snippets
epkgs.rg # ripgrep epkgs.rg # ripgrep
epkgs.exec-path-from-shell # load env and path epkgs.exec-path-from-shell # load env and path
epkgs.eat # better shell epkgs.eat # better shell
epkgs.rust-mode # rust mode (when rust-ts doesn't cut it) epkgs.rust-mode # rust mode (when rust-ts doesn't cut it)
epkgs.rustic # more rust things epkgs.rustic # more rust things
epkgs.nix-mode # nix lang epkgs.nix-mode # nix lang
epkgs.hcl-mode # hashicorp file mode epkgs.hcl-mode # hashicorp file mode
epkgs.shell-pop # quick shell popup epkgs.shell-pop # quick shell popup
epkgs.envrc # support for loading .envrc epkgs.envrc # support for loading .envrc
epkgs.nixpkgs-fmt # format nix files epkgs.nixpkgs-fmt # format nix files
epkgs.f # string + file utilities epkgs.f # string + file utilities
epkgs.gptel # llm chat (mainly claude) epkgs.gptel # llm chat (mainly claude)
epkgs.catppuccin-theme # catppuccin theme epkgs.catppuccin-theme # catppuccin theme
epkgs.eldoc-box # docs in a box epkgs.eldoc-box # docs in a box
epkgs.sideline # mainly for flymake errors on the side epkgs.sideline # mainly for flymake errors on the side
epkgs.sideline-flymake # mainly for flymake errors on the side epkgs.sideline-flymake # mainly for flymake errors on the side
epkgs.sideline-eglot # mainly for flymake errors on the side epkgs.sideline-eglot # mainly for flymake errors on the side
]; ];
}; };
home.sessionVariables = { home.sessionVariables = {
EDITOR = "emacs"; EDITOR = "emacs";
XDG_SCREENSHOTS_DIR = "~/screenshots"; XDG_SCREENSHOTS_DIR = "~/screenshots";
}; };
home.file = { home.file = {
emacs-init = { emacs-init = {
source = ./early-init.el; source = ./early-init.el;
target = ".emacs.d/early-init.el"; target = ".emacs.d/early-init.el";
}; };
emacs = { emacs = {
source = ./init.el; source = ./init.el;
target = ".emacs.d/init.el"; target = ".emacs.d/init.el";
}; };
}; };
services.nextcloud-client = { services.nextcloud-client = {
enable = true; enable = true;
}; };
} }
+91 -91
View File
@@ -1,92 +1,92 @@
;;; package --- early init -*- lexical-binding: t -*- ;;; package --- early init -*- lexical-binding: t -*-
;;; Commentary: ;;; Commentary:
;;; Prevents white flash and better Emacs defaults ;;; Prevents white flash and better Emacs defaults
;;; Code: ;;; Code:
(set-language-environment "UTF-8") (set-language-environment "UTF-8")
(setq-default (setq-default
default-frame-alist default-frame-alist
'((background-color . "#1e1e2e") '((background-color . "#1e1e2e")
(bottom-divider-width . 1) ; Thin horizontal window divider (bottom-divider-width . 1) ; Thin horizontal window divider
(foreground-color . "#bac2de") ; Default foreground color (foreground-color . "#bac2de") ; Default foreground color
(fullscreen . maximized) ; Maximize the window by default (fullscreen . maximized) ; Maximize the window by default
(horizontal-scroll-bars . nil) ; No horizontal scroll-bars (horizontal-scroll-bars . nil) ; No horizontal scroll-bars
(left-fringe . 8) ; Thin left fringe (left-fringe . 8) ; Thin left fringe
(menu-bar-lines . 0) ; No menu bar (menu-bar-lines . 0) ; No menu bar
(right-divider-width . 1) ; Thin vertical window divider (right-divider-width . 1) ; Thin vertical window divider
(right-fringe . 8) ; Thin right fringe (right-fringe . 8) ; Thin right fringe
(tool-bar-lines . 0) ; No tool bar (tool-bar-lines . 0) ; No tool bar
(undecorated . t) ; Remove extraneous X decorations (undecorated . t) ; Remove extraneous X decorations
(vertical-scroll-bars . nil)) ; No vertical scroll-bars (vertical-scroll-bars . nil)) ; No vertical scroll-bars
user-full-name "Henrov henrov" ; ME! user-full-name "Henrov henrov" ; ME!
;; memory configuration ;; memory configuration
;; Higher garbage collection threshold, prevents frequent gc locks, reset later ;; Higher garbage collection threshold, prevents frequent gc locks, reset later
gc-cons-threshold most-positive-fixnum gc-cons-threshold most-positive-fixnum
;; Ignore warnings for (obsolete) elisp compilations ;; Ignore warnings for (obsolete) elisp compilations
byte-compile-warnings '(not obsolete) byte-compile-warnings '(not obsolete)
;; And other log types completely ;; And other log types completely
warning-suppress-log-types '((comp) (bytecomp)) warning-suppress-log-types '((comp) (bytecomp))
;; Large files are okay in the new millenium. ;; Large files are okay in the new millenium.
large-file-warning-threshold 100000000 large-file-warning-threshold 100000000
;; dont show garbage collection messages at startup, will reset later ;; dont show garbage collection messages at startup, will reset later
garbage-collection-messages nil garbage-collection-messages nil
;; native compilation ;; native compilation
package-native-compile t package-native-compile t
native-comp-warning-on-missing-source nil native-comp-warning-on-missing-source nil
native-comp-async-report-warnings-errors 'silent native-comp-async-report-warnings-errors 'silent
;; Read more based on system pipe capacity ;; Read more based on system pipe capacity
read-process-output-max (max (* 10240 10240) read-process-output-max) read-process-output-max (max (* 10240 10240) read-process-output-max)
;; scroll configuration ;; scroll configuration
scroll-margin 0 ; Lets scroll to the end of the margin scroll-margin 0 ; Lets scroll to the end of the margin
scroll-conservatively 100000 ; Never recenter the window scroll-conservatively 100000 ; Never recenter the window
scroll-preserve-screen-position 1 ; Scrolling back and forth scroll-preserve-screen-position 1 ; Scrolling back and forth
;; frame config ;; frame config
;; Improve emacs startup time by not resizing to adjust for custom settings ;; Improve emacs startup time by not resizing to adjust for custom settings
frame-inhibit-implied-resize t frame-inhibit-implied-resize t
;; Dont resize based on character height / width but to exact pixels ;; Dont resize based on character height / width but to exact pixels
frame-resize-pixelwise t frame-resize-pixelwise t
;; backups & files ;; backups & files
backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter
backup-by-copying t ; Don't clobber symlinks backup-by-copying t ; Don't clobber symlinks
create-lockfiles nil ; Don't have temp files create-lockfiles nil ; Don't have temp files
delete-old-versions t ; Cleanup automatically delete-old-versions t ; Cleanup automatically
kept-new-versions 6 ; Update every few times kept-new-versions 6 ; Update every few times
kept-old-versions 2 ; And cleanup even more kept-old-versions 2 ; And cleanup even more
version-control t ; Version them backups version-control t ; Version them backups
delete-by-moving-to-trash t ; Dont delete, send to trash instead delete-by-moving-to-trash t ; Dont delete, send to trash instead
;; startup ;; startup
inhibit-startup-screen t ; I have already done the tutorial. Twice inhibit-startup-screen t ; I have already done the tutorial. Twice
inhibit-startup-message t ; I know I am ready inhibit-startup-message t ; I know I am ready
inhibit-startup-echo-area-message t ; Yep, still know it inhibit-startup-echo-area-message t ; Yep, still know it
initial-scratch-message nil ; I know it is the scratch buffer! initial-scratch-message nil ; I know it is the scratch buffer!
initial-buffer-choice nil initial-buffer-choice nil
inhibit-startup-buffer-menu t inhibit-startup-buffer-menu t
inhibit-x-resources t inhibit-x-resources t
initial-major-mode 'fundamental-mode initial-major-mode 'fundamental-mode
pgtk-wait-for-event-timeout 0.001 ; faster child frames pgtk-wait-for-event-timeout 0.001 ; faster child frames
ad-redefinition-action 'accept ; dont care about legacy things being redefined ad-redefinition-action 'accept ; dont care about legacy things being redefined
inhibit-compacting-font-caches t inhibit-compacting-font-caches t
;; tabs ;; tabs
tab-width 4 ; Always tab 4 spaces. tab-width 4 ; Always tab 4 spaces.
indent-tabs-mode nil ; Never use actual tabs. indent-tabs-mode nil ; Never use actual tabs.
;; rendering ;; rendering
cursor-in-non-selected-windows nil ; dont render cursors other windows cursor-in-non-selected-windows nil ; dont render cursors other windows
;; packages ;; packages
use-package-always-defer t use-package-always-defer t
load-prefer-newer t load-prefer-newer t
default-input-method nil default-input-method nil
use-dialog-box nil use-dialog-box nil
use-file-dialog nil use-file-dialog nil
use-package-expand-minimally t use-package-expand-minimally t
package-enable-at-startup nil package-enable-at-startup nil
use-package-enable-imenu-support t use-package-enable-imenu-support t
auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist. auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist.
package-archives '(("melpa" . "https://melpa.org/packages/") package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/") ("gnu" . "https://elpa.gnu.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/") ("nongnu" . "https://elpa.nongnu.org/nongnu/")
("melpa-stable" . "https://stable.melpa.org/packages/")) ("melpa-stable" . "https://stable.melpa.org/packages/"))
package-archive-priorities '(("gnu" . 99) package-archive-priorities '(("gnu" . 99)
("nongnu" . 80) ("nongnu" . 80)
("melpa" . 70) ("melpa" . 70)
("melpa-stable" . 50)) ("melpa-stable" . 50))
) )
;;; early-init.el ends here ;;; early-init.el ends here
+298 -298
View File
@@ -1,400 +1,400 @@
;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*- ;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-
;;; Commentary: ;;; Commentary:
;;; Simple Emacs setup I carry everywhere ;;; Simple Emacs setup I carry everywhere
;;; Code: ;;; Code:
(setq custom-file (locate-user-emacs-file "custom.el")) (setq custom-file (locate-user-emacs-file "custom.el"))
(load custom-file 'noerror) ;; no error on missing custom file (load custom-file 'noerror) ;; no error on missing custom file
(require 'package) (require 'package)
(package-initialize) (package-initialize)
(defun reset-custom-vars () (defun reset-custom-vars ()
"Resets the custom variables that were set to crazy numbers" "Resets the custom variables that were set to crazy numbers"
(setopt gc-cons-threshold (* 1024 1024 100)) (setopt gc-cons-threshold (* 1024 1024 100))
(setopt garbage-collection-messages t)) (setopt garbage-collection-messages t))
(use-package emacs (use-package emacs
:custom :custom
(native-comp-async-query-on-exit t) (native-comp-async-query-on-exit t)
(read-answer-short t) (read-answer-short t)
(use-short-answers t) (use-short-answers t)
(enable-recursive-minibuffers t) (enable-recursive-minibuffers t)
(which-func-update-delay 1.0) (which-func-update-delay 1.0)
(visible-bell nil) (visible-bell nil)
(custom-buffer-done-kill t) (custom-buffer-done-kill t)
(whitespace-line-column nil) (whitespace-line-column nil)
(x-underline-at-descent-line t) (x-underline-at-descent-line t)
(imenu-auto-rescan t) (imenu-auto-rescan t)
(uniquify-buffer-name-style 'forward) (uniquify-buffer-name-style 'forward)
(confirm-nonexistent-file-or-buffer nil) (confirm-nonexistent-file-or-buffer nil)
(create-lockfiles nil) (create-lockfiles nil)
(make-backup-files nil) (make-backup-files nil)
(kill-do-not-save-duplicates t) (kill-do-not-save-duplicates t)
(sentence-end-double-space nil) (sentence-end-double-space nil)
(treesit-enabled-modes t) (treesit-enabled-modes t)
:init :init
;; base visual ;; base visual
(menu-bar-mode -1) ;; no menu bar (menu-bar-mode -1) ;; no menu bar
(toggle-scroll-bar -1) ;; no scroll bar (toggle-scroll-bar -1) ;; no scroll bar
(tool-bar-mode -1) ;; no tool bar either (tool-bar-mode -1) ;; no tool bar either
(blink-cursor-mode -1) ;; stop blinking (blink-cursor-mode -1) ;; stop blinking
;; font of the century ;; font of the century
(set-frame-font "Aporetic Sans Mono 12" nil t) (set-frame-font "Aporetic Sans Mono 12" nil t)
:bind :bind
(("C-<wheel-up>" . pixel-scroll-precision) ; dont zoom in please, just scroll (("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-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask ("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask
:hook :hook
(text-mode . delete-trailing-whitespace-mode) (text-mode . delete-trailing-whitespace-mode)
(prog-mode . delete-trailing-whitespace-mode) (prog-mode . delete-trailing-whitespace-mode)
(after-init . global-display-line-numbers-mode) ;; always show line numbers (after-init . global-display-line-numbers-mode) ;; always show line numbers
(after-init . column-number-mode) ;; column number in the mode line (after-init . column-number-mode) ;; column number in the mode line
(after-init . size-indication-mode) ;; file size 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 . pixel-scroll-precision-mode) ;; smooth mouse scroll
(after-init . electric-pair-mode) ;; i mean ... parens should auto create (after-init . electric-pair-mode) ;; i mean ... parens should auto create
(after-init . reset-custom-vars) (after-init . reset-custom-vars)
) )
(use-package autorevert (use-package autorevert
:ensure nil :ensure nil
:custom :custom
(auto-revert-interval 3) (auto-revert-interval 3)
(auto-revert-remote-files nil) (auto-revert-remote-files nil)
(auto-revert-use-notify t) (auto-revert-use-notify t)
(auto-revert-avoid-polling nil) (auto-revert-avoid-polling nil)
(auto-revert-verbose t) (auto-revert-verbose t)
:hook :hook
(after-init . global-auto-revert-mode)) (after-init . global-auto-revert-mode))
(use-package recentf (use-package recentf
:ensure nil :ensure nil
:commands (recentf-mode recentf-cleanup) :commands (recentf-mode recentf-cleanup)
:hook :hook
(after-init . recentf-mode) (after-init . recentf-mode)
:custom :custom
(recentf-auto-cleanup 'never) (recentf-auto-cleanup 'never)
(recentf-exclude (recentf-exclude
(list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$" (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
"\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$" "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
"\\.7z$" "\\.rar$" "\\.7z$" "\\.rar$"
"COMMIT_EDITMSG\\'" "COMMIT_EDITMSG\\'"
"\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$" "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
"-autoloads\\.el$" "autoload\\.el$")) "-autoloads\\.el$" "autoload\\.el$"))
:config :config
;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before ;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
;; `recentf-save-list', allowing stale entries to be removed before the list ;; `recentf-save-list', allowing stale entries to be removed before the list
;; is saved by `recentf-save-list', which is automatically added to ;; is saved by `recentf-save-list', which is automatically added to
;; `kill-emacs-hook' by `recentf-mode'. ;; `kill-emacs-hook' by `recentf-mode'.
(add-hook 'kill-emacs-hook #'recentf-cleanup -90)) (add-hook 'kill-emacs-hook #'recentf-cleanup -90))
(use-package savehist (use-package savehist
:ensure nil :ensure nil
:commands (savehist-mode savehist-save) :commands (savehist-mode savehist-save)
:hook :hook
(after-init . savehist-mode) (after-init . savehist-mode)
:custom :custom
(savehist-autosave-interval 600) (savehist-autosave-interval 600)
(savehist-additional-variables (savehist-additional-variables
'(kill-ring ; clipboard '(kill-ring ; clipboard
register-alist ; macros register-alist ; macros
mark-ring global-mark-ring ; marks mark-ring global-mark-ring ; marks
search-ring regexp-search-ring))) search-ring regexp-search-ring)))
(use-package hl-line (use-package hl-line
:ensure nil :ensure nil
:custom :custom
(hl-line-sticky-flag nil) (hl-line-sticky-flag nil)
(global-hl-line-sticky-flag nil) (global-hl-line-sticky-flag nil)
:hook :hook
(after-init . global-hl-line-mode)) (after-init . global-hl-line-mode))
(use-package saveplace (use-package saveplace
:ensure nil :ensure nil
:commands (save-place-mode save-place-local-mode) :commands (save-place-mode save-place-local-mode)
:hook :hook
(after-init . save-place-mode) (after-init . save-place-mode)
:custom :custom
(save-place-limit 400)) (save-place-limit 400))
(use-package nerd-icons (use-package nerd-icons
:custom :custom
;; disable bright icon colors ;; disable bright icon colors
(nerd-icons-color-icons nil))hells.nix (nerd-icons-color-icons nil))hells.nix
(use-package doom-modeline (use-package doom-modeline
:custom :custom
(inhibit-compacting-font-caches t) ;; speed (inhibit-compacting-font-caches t) ;; speed
(doom-modeline-buffer-file-name-style 'relative-from-project) (doom-modeline-buffer-file-name-style 'relative-from-project)
(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you (doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you
(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway (doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway
(doom-modeline-buffer-state-icon nil) ;; the filename already shows me (doom-modeline-buffer-state-icon nil) ;; the filename already shows me
(doom-modeline-lsp nil) ;; lsp state is too distracting, too often (doom-modeline-lsp nil) ;; lsp state is too distracting, too often
:hook (after-init . doom-modeline-mode)) :hook (after-init . doom-modeline-mode))
(load-theme 'catppuccin :no-confirm) (load-theme 'catppuccin :no-confirm)
(use-package diminish :demand t) ;; declutter the modeline (use-package diminish :demand t) ;; declutter the modeline
(use-package eldoc (use-package eldoc
:diminish eldoc-mode :diminish eldoc-mode
:custom :custom
(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything (eldoc-echo-area-use-multiline-p nil)) ;; docs for everything
(use-package eldoc-box (use-package eldoc-box
:defer t :defer t
:config :config
(set-face-background 'eldoc-box-border (catppuccin-color 'green)) (set-face-background 'eldoc-box-border (catppuccin-color 'green))
(set-face-background 'eldoc-box-body (catppuccin-color 'base)) (set-face-background 'eldoc-box-body (catppuccin-color 'base))
:bind :bind
(("M-h" . eldoc-box-help-at-point))) (("M-h" . eldoc-box-help-at-point)))
(use-package pulsar (use-package pulsar
:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry :commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
:init :init
(defface pulsar-catppuccin (defface pulsar-catppuccin
`((default :extend t) `((default :extend t)
(((class color) (min-colors 88) (background light)) (((class color) (min-colors 88) (background light))
:background ,(catppuccin-color 'sapphire)) :background ,(catppuccin-color 'sapphire))
(((class color) (min-colors 88) (background dark)) (((class color) (min-colors 88) (background dark))
:background ,(catppuccin-color 'sapphire)) :background ,(catppuccin-color 'sapphire))
(t :inverse-video t)) (t :inverse-video t))
"Alternative nord face for `pulsar-face'." "Alternative nord face for `pulsar-face'."
:group 'pulsar-faces) :group 'pulsar-faces)
:custom :custom
(pulsar-face 'pulsar-catppuccin) (pulsar-face 'pulsar-catppuccin)
:hook :hook
(after-init . pulsar-global-mode)) (after-init . pulsar-global-mode))
(use-package which-key (use-package which-key
:commands which-key-mode :commands which-key-mode
:diminish which-key-mode :diminish which-key-mode
:hook :hook
(after-init . which-key-mode)) (after-init . which-key-mode))
(use-package expreg (use-package expreg
:bind ("M-m" . expreg-expand)) :bind ("M-m" . expreg-expand))
(use-package vundo) ;; undo tree (use-package vundo) ;; undo tree
;; better structured editing ;; better structured editing
(use-package puni (use-package puni
:commands puni-global-mode :commands puni-global-mode
:hook :hook
(after-init . puni-global-mode)) (after-init . puni-global-mode))
(use-package avy (use-package avy
:bind :bind
("M-i" . avy-goto-char-2) ("M-i" . avy-goto-char-2)
:custom :custom
(avy-background t)) (avy-background t))
(use-package consult (use-package consult
:bind :bind
("C-x b" . consult-buffer) ;; orig. switch-to-buffer ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("M-y" . consult-yank-pop) ;; orig. yank-pop ("M-y" . consult-yank-pop) ;; orig. yank-pop
("M-g M-g" . consult-goto-line) ;; orig. goto-line ("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g i" . consult-imenu) ;; consult version is interactive ("M-g i" . consult-imenu) ;; consult version is interactive
("M-g r" . consult-ripgrep) ;; find in project also works ("M-g r" . consult-ripgrep) ;; find in project also works
:custom :custom
(consult-narrow-key "<")) (consult-narrow-key "<"))
(use-package vertico (use-package vertico
:commands vertico-mode :commands vertico-mode
:custom :custom
(read-file-name-completion-ignore-case t) (read-file-name-completion-ignore-case t)
(read-buffer-completion-ignore-case t) (read-buffer-completion-ignore-case t)
(completion-ignore-case t) (completion-ignore-case t)
(enable-recursive-minibuffers t) (enable-recursive-minibuffers t)
(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
:init :init
(vertico-mode) (vertico-mode)
:hook :hook
(minibuffer-setup-hook . cursor-intangible-mode)) (minibuffer-setup-hook . cursor-intangible-mode))
(use-package marginalia (use-package marginalia
:commands marginalia-mode :commands marginalia-mode
:hook (after-init . marginalia-mode)) :hook (after-init . marginalia-mode))
(use-package crux (use-package crux
:bind :bind
("C-c M-e" . crux-find-user-init-file) ("C-c M-e" . crux-find-user-init-file)
("C-c C-w" . crux-transpose-windows) ("C-c C-w" . crux-transpose-windows)
("C-c M-d" . crux-find-current-directory-dir-locals-file) ("C-c M-d" . crux-find-current-directory-dir-locals-file)
("C-a" . crux-move-beginning-of-line)) ("C-a" . crux-move-beginning-of-line))
(use-package magit (use-package magit
:bind (("C-M-g" . magit-status))) :bind (("C-M-g" . magit-status)))
(use-package nerd-icons-corfu (use-package nerd-icons-corfu
:commands nerd-icons-corfu-formatter :commands nerd-icons-corfu-formatter
:defines corfu-margin-formatters) :defines corfu-margin-formatters)
(use-package corfu (use-package corfu
:commands global-corfu-mode :commands global-corfu-mode
:custom :custom
(corfu-cycle t) (corfu-cycle t)
(corfu-auto t) (corfu-auto t)
(corfu-auto-delay 1) (corfu-auto-delay 1)
(corfu-auto-prefix 3) (corfu-auto-prefix 3)
(corfu-separator ?_) (corfu-separator ?_)
:hook :hook
(after-init . global-corfu-mode) (after-init . global-corfu-mode)
:config :config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(use-package cape) (use-package cape)
(use-package orderless (use-package orderless
:custom :custom
(completion-styles '(orderless partial-completion basic)) (completion-styles '(orderless partial-completion basic))
(completion-category-defaults nil) (completion-category-defaults nil)
(completion-category-overrides nil)) (completion-category-overrides nil))
(use-package yasnippet (use-package yasnippet
:commands yas-global-mode :commands yas-global-mode
:diminish yas-minor-mode :diminish yas-minor-mode
:hook :hook
(after-init . yas-global-mode)) (after-init . yas-global-mode))
(use-package yasnippet-snippets :after yasnippet) (use-package yasnippet-snippets :after yasnippet)
(use-package exec-path-from-shell (use-package exec-path-from-shell
:commands exec-path-from-shell-initialize :commands exec-path-from-shell-initialize
:custom :custom
(exec-path-from-shell-arguments nil) (exec-path-from-shell-arguments nil)
:hook :hook
(after-init . exec-path-from-shell-initialize)) (after-init . exec-path-from-shell-initialize))
(use-package nixpkgs-fmt (use-package nixpkgs-fmt
:custom :custom
(nixpkgs-fmt-command "nixfmt")) (nixpkgs-fmt-command "nixfmt"))
(use-package eat (use-package eat
:bind :bind
(("C-c e p" . eat-project) (("C-c e p" . eat-project)
("C-c e t" . eat))) ("C-c e t" . eat)))
(use-package f :demand t) (use-package f :demand t)
(use-package envrc (use-package envrc
:commands envrc-global-mode :commands envrc-global-mode
:hook :hook
(after-init . envrc-global-mode)) (after-init . envrc-global-mode))
(use-package gptel (use-package gptel
:commands gptel-make-anthropic f-read-text :commands gptel-make-anthropic f-read-text
:config :config
(gptel-make-anthropic "Claude" (gptel-make-anthropic "Claude"
:stream t :key (f-read-text "/run/secrets/claude_key"))) :stream t :key (f-read-text "/run/secrets/claude_key")))
(use-package sideline-flymake) (use-package sideline-flymake)
(use-package sideline-eglot) (use-package sideline-eglot)
(use-package sideline (use-package sideline
:custom :custom
(sideline-backends-right '(sideline-flymake sideline-eglot)) (sideline-backends-right '(sideline-flymake sideline-eglot))
:hook :hook
(eglot-managed-mode . sideline-mode) (eglot-managed-mode . sideline-mode)
(flymake-mode . sideline-mode)) (flymake-mode . sideline-mode))
(use-package eglot (use-package eglot
:custom :custom
(eglot-extend-to-xref t) (eglot-extend-to-xref t)
(eglot-ignored-server-capabilities '(:inlayHintProvider)) (eglot-ignored-server-capabilities '(:inlayHintProvider))
(jsonrpc-event-hook nil) (jsonrpc-event-hook nil)
:hook :hook
(eglot-managed-mode . eldoc-box-hover-mode) (eglot-managed-mode . eldoc-box-hover-mode)
(before-save . eldoc-format-buffer) (before-save . eldoc-format-buffer)
:bind :bind
(:map eglot-mode-map (:map eglot-mode-map
("C-c l a" . eglot-code-actions) ("C-c l a" . eglot-code-actions)
("C-c l r" . eglot-rename) ("C-c l r" . eglot-rename)
("C-c l h" . eldoc) ("C-c l h" . eldoc)
("C-c l g" . xref-find-references) ("C-c l g" . xref-find-references)
("C-c l w" . eglot-reconnect))) ("C-c l w" . eglot-reconnect)))
(use-package proced (use-package proced
:custom :custom
(proced-auto-update-flag t) (proced-auto-update-flag t)
(proced-auto-update-interval 3) (proced-auto-update-interval 3)
(proced-enable-color-flag t) (proced-enable-color-flag t)
(proced-show-remote-processes t)) (proced-show-remote-processes t))
(use-package org (use-package org
:ensure t :ensure t
:defer t :defer t
:commands (org-mode org-capture org-agenda) :commands (org-mode org-capture org-agenda)
:init :init
(defvar org-journal-file "~/nextcloud/org/journal.org") (defvar org-journal-file "~/nextcloud/org/journal.org")
(defvar org-archive-file "~/nextcloud/org/archive.org") (defvar org-archive-file "~/nextcloud/org/archive.org")
(defvar org-notes-file "~/nextcloud/org/notes.org") (defvar org-notes-file "~/nextcloud/org/notes.org")
(defvar org-inbox-file "~/nextcloud/org/inbox.org") (defvar org-inbox-file "~/nextcloud/org/inbox.org")
(defvar org-work-file "~/nextcloud/org/work.org") (defvar org-work-file "~/nextcloud/org/work.org")
(defun my/org-capture-project-target-heading () (defun my/org-capture-project-target-heading ()
"Determine Org target headings from the current file's project path. "Determine Org target headings from the current file's project path.
This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'. This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
It extracts 'COMPANY' and 'PROJECT' to use as nested headlines It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
for an Org capture template. for an Org capture template.
If the current buffer is not visi If the current buffer is not visi
ting a file within such a ting a file within such a
project structure, it returns nil, causing capture to default to project structure, it returns nil, causing capture to default to
the top of the file." the top of the file."
(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer (when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
(let ((path-parts (split-string path "/" t " "))) (let ((path-parts (split-string path "/" t " ")))
(when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=)) (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
(company (nth (+ 1 projects-pos) path-parts)) (company (nth (+ 1 projects-pos) path-parts))
(project (nth (+ 2 projects-pos) path-parts))) (project (nth (+ 2 projects-pos) path-parts)))
;; Return a list of headlines for Org to find or create. ;; Return a list of headlines for Org to find or create.
(list company project))))) (list company project)))))
:bind :bind
(("C-c c" . org-capture) (("C-c c" . org-capture)
("C-c i" . org-store-link) ("C-c i" . org-store-link)
("C-c a" . org-agenda) ("C-c a" . org-agenda)
:map org-mode-map :map org-mode-map
("C-c t" . org-toggle-inline-images) ("C-c t" . org-toggle-inline-images)
("C-c l" . org-toggle-link-display)) ("C-c l" . org-toggle-link-display))
:custom :custom
(org-agenda-files (list org-inbox-file org-journal-file)) (org-agenda-files (list org-inbox-file org-journal-file))
(org-directory "~/nextcloud/org") (org-directory "~/nextcloud/org")
(org-default-notes-file org-inbox-file) (org-default-notes-file org-inbox-file)
(org-archive-location (concat org-archive-file "::* From %s")) (org-archive-location (concat org-archive-file "::* From %s"))
(org-log-done 'time) (org-log-done 'time)
(org-log-into-drawer t) (org-log-into-drawer t)
(org-hide-emphasis-markers t) (org-hide-emphasis-markers t)
(org-src-fontify-natively t) (org-src-fontify-natively t)
(org-src-tab-acts-natively t) (org-src-tab-acts-natively t)
(org-capture-templates '(("t" "Todo" entry (file org-inbox-file) (org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
"* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)") "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
("j" "Journal" entry (file+olp+datetree org-journal-file) ("j" "Journal" entry (file+olp+datetree org-journal-file)
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
("n" "Note" entry (file org-notes-file) ("n" "Note" entry (file org-notes-file)
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
("p" "Project Task" item ("p" "Project Task" item
(file+function org-work-file my/org-capture-project-target-heading) (file+function org-work-file my/org-capture-project-target-heading)
"* TODO %? \n CLOCK: %U" "* TODO %? \n CLOCK: %U"
)) ))
) )
:config :config
;; Enable syntax highlighting in code blocks ;; Enable syntax highlighting in code blocks
(add-hook 'org-mode-hook 'turn-on-font-lock) (add-hook 'org-mode-hook 'turn-on-font-lock)
(add-hook 'org-mode-hook 'org-indent-mode)) (add-hook 'org-mode-hook 'org-indent-mode))
;; extras ;; extras
(use-package comp-run (use-package comp-run
:ensure nil :ensure nil
:config :config
(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list) (push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list)) (push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))
(use-package rustic (use-package rustic
:custom :custom
(rustic-lsp-client 'eglot)) (rustic-lsp-client 'eglot))
(provide 'init) (provide 'init)
;;; init.el ends here ;;; init.el ends here
+18 -17
View File
@@ -1,29 +1,30 @@
{ config, pkgs, lib, flakeRoot, ... }: { config, pkgs, lib, flakeRoot, ... }:
let let
catppuccinMochaConf = catppuccinMochaConf =
builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/Catppuccin-Mocha.conf"); builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/Catppuccin-Mocha.conf");
# Your own keymaps / other settings (but we will NOT rely on it for opacity) # Your own keymaps / other settings (but we will NOT rely on it for opacity)
repoKittyConfText = repoKittyConfText =
builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf"); builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf");
in in
{ {
xdg.enable = true; xdg.enable = true;
# Stable theme file so kitty.conf can include it without /nix/store paths # Stable theme file so kitty.conf can include it without /nix/store paths
xdg.configFile."kitty/themes/Catppuccin-Mocha.conf".text = catppuccinMochaConf; xdg.configFile."kitty/themes/Catppuccin-Mocha.conf".text = lib.mkForce catppuccinMochaConf;
xdg.configFile."kitty/themes/Catppuccin-Mocha.conf".backup = lib.mkForce false;
programs.kitty = { programs.kitty = {
enable = true; enable = true;
# Home Manager generates ~/.config/kitty/kitty.conf; we append in-order: # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order:
# 1) include theme # 1) include theme
# 2) your repo config (keymaps etc.) # 2) your repo config (keymaps etc.)
# 3) force opacity LAST so it always wins # 3) force opacity LAST so it always wins
extraConfig = '' extraConfig = ''
# 1) Theme first (stable path) # 1) Theme first (stable path)
include themes/Catppuccin-Mocha.conf include themes/Catppuccin-Mocha.conf
# 2) Your repo config (may also include theme; harmless if duplicated) # 2) Your repo config (may also include theme; harmless if duplicated)
${repoKittyConfText} ${repoKittyConfText}
# 3) Force transparency last (wins) # 3) Force transparency last (wins)
#background_opacity 0.60 #background_opacity 0.60
#dynamic_background_opacity yes #dynamic_background_opacity yes
''; '';
}; };
} }
+116 -116
View File
@@ -1,8 +1,8 @@
# shells.nix — Home-Manager module # shells.nix — Home-Manager module
# #
# Reads: # Reads:
# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf # ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf
# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf # ${flakeRoot}/assets/conf/dev/terminal/aliases.conf
# #
# For each enabled shell in [enabled_shells]: # For each enabled shell in [enabled_shells]:
# - installs/enables shell (where HM has an enable option) # - installs/enables shell (where HM has an enable option)
@@ -23,53 +23,53 @@ let
readMaybe = p: if builtins.pathExists p then builtins.readFile p else ""; readMaybe = p: if builtins.pathExists p then builtins.readFile p else "";
normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l); normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l);
parseSections = text: parseSections = text:
let let
lines = map normalizeLine (lib.splitString "\n" text); lines = map normalizeLine (lib.splitString "\n" text);
isHeader = l: isHeader = l:
let s = l; let s = l;
in lib.hasPrefix "[" s in lib.hasPrefix "[" s
&& lib.hasSuffix "]" s && lib.hasSuffix "]" s
&& builtins.stringLength s >= 3; && builtins.stringLength s >= 3;
nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l); nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l);
folded = folded =
builtins.foldl' builtins.foldl'
(st: l: (st: l:
if l == "" then st else if l == "" then st else
if isHeader l then st // { current = nameOf l; } if isHeader l then st // { current = nameOf l; }
else else
let let
cur = st.current; cur = st.current;
prev = st.sections.${cur} or []; prev = st.sections.${cur} or [];
in in
st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; } st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; }
) )
{ current = "__root__"; sections = {}; } { current = "__root__"; sections = {}; }
lines; lines;
in in
folded.sections; folded.sections;
enabledSections = parseSections (readMaybe enabledFile); enabledSections = parseSections (readMaybe enabledFile);
aliasSections = parseSections (readMaybe aliasesFile); aliasSections = parseSections (readMaybe aliasesFile);
# [enabled_shells] lines: key = yes/no # [enabled_shells] lines: key = yes/no
enabledShells = enabledShells =
let let
raw = enabledSections.enabled_shells or []; raw = enabledSections.enabled_shells or [];
parseKV = l: parseKV = l:
let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l; let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l;
in if m == null then null else { in if m == null then null else {
k = trim (builtins.elemAt m 0); k = trim (builtins.elemAt m 0);
v = lib.toLower (trim (builtins.elemAt m 1)); v = lib.toLower (trim (builtins.elemAt m 1));
}; };
kvs = builtins.filter (x: x != null) (map parseKV raw); kvs = builtins.filter (x: x != null) (map parseKV raw);
in in
map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs); map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs);
shellEnabled = shell: builtins.elem shell enabledShells; shellEnabled = shell: builtins.elem shell enabledShells;
# ---------- per-shell repo config file (<shell>.conf) ---------- # ---------- per-shell repo config file (<shell>.conf) ----------
shellConfPath = shell: terminalDir + "/${shell}.conf"; shellConfPath = shell: terminalDir + "/${shell}.conf";
shellConfExists = shell: builtins.pathExists (shellConfPath shell); shellConfExists = shell: builtins.pathExists (shellConfPath shell);
sourceIfExistsSh = p: '' sourceIfExistsSh = p: ''
if [ -f "${toString p}" ]; then if [ -f "${toString p}" ]; then
source "${toString p}" source "${toString p}"
fi fi
''; '';
# ---------- aliases section helpers ---------- # ---------- aliases section helpers ----------
secLines = name: aliasSections.${name} or []; secLines = name: aliasSections.${name} or [];
@@ -80,55 +80,55 @@ let
fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish"; fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish";
# Seeds (created once; user can edit afterwards) # Seeds (created once; user can edit afterwards)
bashSeed = '' bashSeed = ''
# Created once from: ${toString aliasesFile} # Created once from: ${toString aliasesFile}
# Edit freely; Home Manager will not overwrite this file. # Edit freely; Home Manager will not overwrite this file.
# #
${secText "bash_zsh"} ${secText "bash_zsh"}
${secText "bash_specific"} ${secText "bash_specific"}
''; '';
zshSeed = '' zshSeed = ''
# Created once from: ${toString aliasesFile} # Created once from: ${toString aliasesFile}
# Edit freely; Home Manager will not overwrite this file. # Edit freely; Home Manager will not overwrite this file.
${secText "bash_zsh"} ${secText "bash_zsh"}
${secText "zsh_specific"} ${secText "zsh_specific"}
''; '';
# Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is # Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is
parsePosixAlias = l: parsePosixAlias = l:
let
m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l;
in
if m == null then null else
let let
m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l; name = trim (builtins.elemAt m 0);
rhs0 = trim (builtins.elemAt m 1);
unquote =
if lib.hasPrefix "'" rhs0 && lib.hasSuffix "'" rhs0 then
lib.removeSuffix "'" (lib.removePrefix "'" rhs0)
else if lib.hasPrefix "\"" rhs0 && lib.hasSuffix "\"" rhs0 then
lib.removeSuffix "\"" (lib.removePrefix "\"" rhs0)
else
rhs0;
in in
if m == null then null else { inherit name; cmd = unquote; };
let
name = trim (builtins.elemAt m 0);
rhs0 = trim (builtins.elemAt m 1);
unquote =
if lib.hasPrefix "'" rhs0 && lib.hasSuffix "'" rhs0 then
lib.removeSuffix "'" (lib.removePrefix "'" rhs0)
else if lib.hasPrefix "\"" rhs0 && lib.hasSuffix "\"" rhs0 then
lib.removeSuffix "\"" (lib.removePrefix "\"" rhs0)
else
rhs0;
in
{ inherit name; cmd = unquote; };
escapeForFish = s: escapeForFish = s:
lib.replaceStrings lib.replaceStrings
[ "\\" "\"" "$" "`" ] [ "\\" "\"" "$" "`" ]
[ "\\\\" "\\\"" "\\$" "\\`" ] [ "\\\\" "\\\"" "\\$" "\\`" ]
s; s;
fishTranslated = fishTranslated =
let let
parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh")); parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh"));
in in
lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed); lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed);
fishSeed = '' fishSeed = ''
# Created once from: ${toString aliasesFile} # Created once from: ${toString aliasesFile}
# Edit freely; Home Manager will not overwrite this file. # Edit freely; Home Manager will not overwrite this file.
status is-interactive; or exit status is-interactive; or exit
# Translated from [bash_zsh]: # Translated from [bash_zsh]:
${fishTranslated} ${fishTranslated}
# From [fish_specific]: # From [fish_specific]:
${secText "fish_specific"} ${secText "fish_specific"}
''; '';
in in
{ {
xdg.enable = true; xdg.enable = true;
@@ -137,70 +137,70 @@ in
programs.zsh.enable = shellEnabled "zsh"; programs.zsh.enable = shellEnabled "zsh";
programs.fish.enable = shellEnabled "fish"; programs.fish.enable = shellEnabled "fish";
home.packages = home.packages =
(lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++ (lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++
(lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]); (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]);
# Source per-shell repo config (if present) AND source the user alias file (if it exists). # Source per-shell repo config (if present) AND source the user alias file (if it exists).
# Important: define each option only ONCE. # Important: define each option only ONCE.
programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter '' programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter ''
${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))} ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))}
if [ -f "${bashAliasesPath}" ]; then if [ -f "${bashAliasesPath}" ]; then
source "${bashAliasesPath}" source "${bashAliasesPath}"
fi fi
''); '');
programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter '' programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter ''
${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))} ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))}
if [ -f "${zshAliasesPath}" ]; then if [ -f "${zshAliasesPath}" ]; then
source "${zshAliasesPath}" source "${zshAliasesPath}"
fi fi
''); '');
programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter '' programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter ''
${lib.optionalString (shellConfExists "fish") '' ${lib.optionalString (shellConfExists "fish") ''
if test -f "${toString (shellConfPath "fish")}" if test -f "${toString (shellConfPath "fish")}"
source "${toString (shellConfPath "fish")}" source "${toString (shellConfPath "fish")}"
end end
''} ''}
if test -f "${fishAliasesPath}" if test -f "${fishAliasesPath}"
source "${fishAliasesPath}" source "${fishAliasesPath}"
end end
''); '');
# Create/remove alias files based on enabled shells # Create/remove alias files based on enabled shells
home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] '' home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -euo pipefail set -euo pipefail
# bash ------------------------------------------------------- # bash -------------------------------------------------------
if ${if shellEnabled "bash" then "true" else "false"}; then if ${if shellEnabled "bash" then "true" else "false"}; then
cat > "${bashAliasesPath}" <<'EOF' cat > "${bashAliasesPath}" <<'EOF'
${bashSeed} ${bashSeed}
EOF EOF
else else
rm -f "${bashAliasesPath}" rm -f "${bashAliasesPath}"
fi fi
# zsh ------------------------------------------------------- # zsh -------------------------------------------------------
if ${if shellEnabled "zsh" then "true" else "false"}; then if ${if shellEnabled "zsh" then "true" else "false"}; then
cat > "${zshAliasesPath}" <<'EOF' cat > "${zshAliasesPath}" <<'EOF'
${zshSeed} ${zshSeed}
EOF EOF
else else
rm -f "${zshAliasesPath}" rm -f "${zshAliasesPath}"
fi fi
# fish ------------------------------------------------------- # fish -------------------------------------------------------
if ${if shellEnabled "fish" then "true" else "false"}; then if ${if shellEnabled "fish" then "true" else "false"}; then
mkdir -p "$(dirname "${fishAliasesPath}")" mkdir -p "$(dirname "${fishAliasesPath}")"
cat > "${fishAliasesPath}" <<'EOF' cat > "${fishAliasesPath}" <<'EOF'
${fishSeed} ${fishSeed}
EOF EOF
else else
rm -f "${fishAliasesPath}" rm -f "${fishAliasesPath}"
fi fi
# fish # fish
if ${if shellEnabled "fish" then "true" else "false"}; then if ${if shellEnabled "fish" then "true" else "false"}; then
mkdir -p "$(dirname "${fishAliasesPath}")" mkdir -p "$(dirname "${fishAliasesPath}")"
if [ ! -f "${fishAliasesPath}" ]; then if [ ! -f "${fishAliasesPath}" ]; then
cat > "${fishAliasesPath}" <<'EOF' cat > "${fishAliasesPath}" <<'EOF'
${fishSeed} ${fishSeed}
EOF EOF
fi fi
else else
rm -f "${fishAliasesPath}" rm -f "${fishAliasesPath}"
fi fi
''; '';
} }
+4 -4
View File
@@ -10,10 +10,10 @@ in
xdg.enable = true; xdg.enable = true;
programs.starship = { programs.starship = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true; enableBashIntegration = true;
enableFishIntegration = true; enableFishIntegration = true;
}; };
# Force the *actual conflicting option* (home.file."<abs path>".source) # Force the *actual conflicting option* (home.file."<abs path>".source)
+21 -21
View File
@@ -1,26 +1,26 @@
{ config, pkgs, lib, flakeRoot, ... }: { config, pkgs, lib, flakeRoot, ... }:
{ {
programs.zsh = { programs.zsh = {
enable = true; enable = true;
enableCompletion = true; enableCompletion = true;
autocd = true; autocd = true;
# Optional but recommended: keep zsh config in one dir (relative to $HOME) # Optional but recommended: keep zsh config in one dir (relative to $HOME)
dotDir = ".config/zsh"; dotDir = ".config/zsh";
oh-my-zsh = { oh-my-zsh = {
enable = true; enable = true;
theme = ""; theme = "";
plugins = [ plugins = [
"git" "git"
"sudo" "sudo"
"extract" "extract"
"colored-man-pages" "colored-man-pages"
"command-not-found" "command-not-found"
"history" "history"
"docker" "docker"
"kubectl" "kubectl"
]; ];
}; };
autosuggestion.enable = true; autosuggestion.enable = true;
syntaxHighlighting.enable = true; syntaxHighlighting.enable = true;
}; };
} }
@@ -1,7 +1,7 @@
{ user, ... } : { { user, ... } : {
imports = imports =
[ [
./hardware-configuration.nix ./hardware-configuration.nix
../../configuration ../../configuration
]; ];
} }
@@ -1,17 +1,17 @@
{ {
hostname, hostname,
pkgs, pkgs,
lib, lib,
modulesPath, modulesPath,
user, user,
config, config,
... ...
}: }:
{ {
imports = [ imports = [
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
../../hardware/hardware.nix ../../hardware/hardware.nix
]; ];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ]; boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [ ];
@@ -19,19 +19,19 @@ boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = fileSystems."/" =
{ device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2"; { device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" = fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/811D-0676"; { device = "/dev/disk/by-uuid/811D-0676";
fsType = "vfat"; fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ]; options = [ "fmask=0077" "dmask=0077" ];
}; };
swapDevices = swapDevices =
[ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; } [ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; }
]; ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+6 -6
View File
@@ -1,15 +1,15 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [ imports = [
../../home ../../home
]; ];
home.packages = with pkgs; [ home.packages = with pkgs; [
brightnessctl brightnessctl
]; ];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
extraConfig = '' extraConfig = ''
# Default portable monitor rule # Default portable monitor rule
monitor=DP-1,3840x1080@144,1920x0,1 monitor=DP-1,3840x1080@144,1920x0,1
''; '';
}; };
} }
+4 -4
View File
@@ -37,13 +37,13 @@ nmcli connection show --active
nmcli device status nmcli device status
find ~/Repos/nixos/henrovnix_ok \ find ~/Repos/nixos/henrovnix_ok \
-type d -name ".*" -prune -o \ -type d -name ".*" -prune -o \
-type f -print0 \ -type f -print0 \
| xargs -0 sed -i 's/=<defaultUser>=/YOUR_USER/g' | xargs -0 sed -i 's/=<defaultUser>=/YOUR_USER/g'
find ~/Repos/nixos/henrovnix_ok \ find ~/Repos/nixos/henrovnix_ok \
-type d -name ".*" -prune -o \ -type d -name ".*" -prune -o \
-type f -print0 \ -type f -print0 \
| xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g' | xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g'
mv ./machines/machine1 ./machines/YOUR_HOSTNAME mv ./machines/machine1 ./machines/YOUR_HOSTNAME