From 72006f36eabd7f96ef9cfb961f7216cca5b4dd1c Mon Sep 17 00:00:00 2001 From: Henro Veijer Date: Sun, 1 Mar 2026 17:23:50 +0100 Subject: [PATCH] Added lib.mkForce + backup = false --- henrovnix_ok/.envrc | 2 +- henrovnix_ok/README.html | 3781 +++++++++-------- henrovnix_ok/README.org | 3283 +++++++------- .../configuration/apps/install_flatpaks.nix | 112 +- .../configuration/apps/install_packages.nix | 50 +- henrovnix_ok/configuration/core/boot.nix | 32 +- henrovnix_ok/configuration/core/files.nix | 32 +- henrovnix_ok/configuration/core/locale.nix | 34 +- .../configuration/core/login-lightdm.nix | 172 +- .../configuration/core/login-tuigreeter.nix | 20 +- .../configuration/core/networking.nix | 30 +- .../configuration/core/nix-settings.nix | 62 +- henrovnix_ok/configuration/default.nix | 70 +- henrovnix_ok/configuration/desktop/audio.nix | 90 +- .../configuration/desktop/hyprland.nix | 72 +- .../configuration/services/services.nix | 36 +- henrovnix_ok/flake.nix | 166 +- henrovnix_ok/hardware/hardware.nix | 32 +- henrovnix_ok/home/apps/defaults-apps.nix | 6 +- henrovnix_ok/home/apps/ollama.nix | 6 +- henrovnix_ok/home/apps/theme.nix | 38 +- henrovnix_ok/home/default.nix | 58 +- .../home/desktop/animated_wallpaper.nix | 60 +- henrovnix_ok/home/desktop/hyprexpo.nix | 40 +- henrovnix_ok/home/desktop/hypridle.nix | 3 +- henrovnix_ok/home/desktop/hyprland.nix | 55 +- henrovnix_ok/home/desktop/hyprlock.nix | 8 +- henrovnix_ok/home/desktop/hyprscrolling.nix | 37 +- henrovnix_ok/home/desktop/hyprshell.nix | 32 +- henrovnix_ok/home/desktop/powermenu.nix | 7 +- .../home/desktop/rotating_wallpaper.nix | 42 +- henrovnix_ok/home/desktop/walker.nix | 22 +- henrovnix_ok/home/desktop/waybar.nix | 10 +- .../home/desktop/workspace_wallpaper.nix | 315 +- henrovnix_ok/home/dev/alacritty.nix | 1 + henrovnix_ok/home/dev/dev.nix | 72 +- henrovnix_ok/home/dev/emacs/default.nix | 128 +- henrovnix_ok/home/dev/emacs/early-init.el | 182 +- henrovnix_ok/home/dev/emacs/init.el | 596 +-- henrovnix_ok/home/dev/kitty.nix | 35 +- henrovnix_ok/home/dev/shells.nix | 232 +- henrovnix_ok/home/dev/starship.nix | 8 +- henrovnix_ok/home/dev/zsh.nix | 42 +- .../machines/traveldroid/configuration.nix | 8 +- .../traveldroid/hardware-configuration.nix | 40 +- henrovnix_ok/machines/traveldroid/home.nix | 12 +- henrovnix_ok/no block | 8 +- 47 files changed, 5121 insertions(+), 5058 deletions(-) diff --git a/henrovnix_ok/.envrc b/henrovnix_ok/.envrc index 508a5ca20..5370a3ad1 100755 --- a/henrovnix_ok/.envrc +++ b/henrovnix_ok/.envrc @@ -2,5 +2,5 @@ use flake watch_file .envrc.private if [[ -f .envrc.private ]]; then - source_env .envrc.private +source_env .envrc.private fi diff --git a/henrovnix_ok/README.html b/henrovnix_ok/README.html index 213a86b91..324af578a 100644 --- a/henrovnix_ok/README.html +++ b/henrovnix_ok/README.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + @@ -201,154 +201,154 @@

Table of Contents

-gf#+OPTIONS: toc:nil broken-links:t +f#+OPTIONS: toc:nil broken-links:t

@@ -384,8 +384,8 @@ gf#+OPTIONS: toc:nil broken-links:t
-
-

1. Introduction

+
+

1. Introduction

Screenshot

@@ -400,8 +400,8 @@ Customization is designed to occur primarily through modular .conf files, allowi Before proceeding with installation, it is strongly recommended to read this documentation carefully. Understanding the structure and design philosophy will help ensure a smooth setup and provide the necessary context for extending the system effectively.

-
-

1.1. What do you get?

+
+

1.1. What do you get?

This repository delivers a reproducible foundation built on NixOS, Home-Manager, and Flakes. It assumes a clean NixOS installation as a starting point, preferably minimal or headless, onto which the configuration is applied. @@ -410,8 +410,8 @@ Core packages are installed as part of the base configuration. Additional softwa

-
-

1.2. What you do not get

+
+

1.2. What you do not get

This repository does not provide a fully polished, bug-free desktop system with every default preconfigured and validated across all hardware combinations. It is a structured foundation, not a turnkey end-user distribution. @@ -423,8 +423,8 @@ In short, this repository provides a coherent and extensible base, not a finishe

-
-

2. What Is a Literate System in the Context of NixOS?

+
+

2. What Is a Literate System in the Context of NixOS?

A literate system combines documentation and implementation into a single, coherent source. @@ -458,8 +458,8 @@ The README is not describing the system. The README is the system.

-
-

2.1. Two Types of Code Blocks

+
+

2.1. Two Types of Code Blocks

This literate system uses two different kinds of source blocks. @@ -471,7 +471,7 @@ These blocks exist purely for documentation purposes. They generate visible code blocks in the exported documentation, but they do not create files. Example:

-
+
 #+begin_src bash :tangle no
 <tekst>
 #+end_src
@@ -487,7 +487,7 @@ They are never tangled into the filesystem.
 These blocks generate real .nix files and insert the same code into the documentation.
 Example:
 

-
+
 ** install_packages.nix
 <tekst>
 #+begin_src nix :tangle configuration/apps/install_packages.nix :noweb tangle :mkdirp yes
@@ -515,8 +515,8 @@ This means:
 
 
-
-

2.2. The Two Core Commands

+
+

2.2. The Two Core Commands

There are exactly two commands that matter. @@ -564,8 +564,8 @@ Both come from the same source.

-
-

2.3. Editing Generated Files

+
+

2.3. Editing Generated Files

The directories: @@ -591,8 +591,8 @@ Generated directories are output, not source.

-
-

2.4. Recommended Workflow

+
+

2.4. Recommended Workflow

This workflow allows safe experimentation while preserving literate structure. @@ -633,15 +633,15 @@ If you are confident about your changes, you may skip steps 1–3 and edit READM

-
-

2.5. Folder Structure Explained

+
+

2.5. Folder Structure Explained

The repository separates generated system code from non-generated supporting files.

-
-

2.5.1. ./assets

+
+

2.5.1. ./assets

Contains non-generated assisting files such as: @@ -656,8 +656,8 @@ These files are safe to edit directly.

-
-

2.5.2. ./assets/conf

+
+

2.5.2. ./assets/conf

Contains non-generated assisting configuration files that influence several aspects of builds. @@ -665,8 +665,8 @@ Users are expected to modify these when needed.

-
-

2.5.3. ./configuration

+
+

2.5.3. ./configuration

Fully (re)generated by README.org. @@ -685,8 +685,8 @@ This directory is output.

-
-

2.5.4. ./hardware

+
+

2.5.4. ./hardware

Contains non-generated hardware.nix files detailing hardware-specific details. @@ -694,8 +694,8 @@ This directory will likely be deprecated in the future.

-
-

2.5.5. ./home

+
+

2.5.5. ./home

Fully (re)generated by README.org. @@ -711,8 +711,8 @@ Contains:

-
-

2.5.6. ./machines

+
+

2.5.6. ./machines

Contains one folder per machine you want to configure. @@ -730,8 +730,8 @@ These determine how shared modules apply to each system.

-
-

2.6. Final Principle

+
+

2.6. Final Principle

A literate NixOS system guarantees: @@ -750,8 +750,8 @@ You are maintaining a structured narrative that builds an operating system.

-
-

2.7. Base packages

+
+

2.7. Base packages

The baseline package set is defined explicitly within the repository to ensure reproducibility: @@ -825,8 +825,8 @@ The baseline package set is defined explicitly within the repository to ensure r

-
-

2.8. Additional packages

+
+

2.8. Additional packages

Additional software can be installed by extending the dedicated configuration files that define system and Flatpak packages: @@ -867,12 +867,12 @@ This separation maintains clarity between system-level packages and user-facing

-
-

3. Setting up your system manually

+
+

3. Setting up your system manually

-
-

3.1. Pre-requisites to build this setup

+
+

3.1. Pre-requisites to build this setup

- a NIXOS system installed with a user with sudo rights.
@@ -882,8 +882,8 @@ This separation maintains clarity between system-level packages and user-facing
 
-
-

3.2. Setup when Emacs not (yet) available

+
+

3.2. Setup when Emacs not (yet) available

  1. Copy the folder henrovnixok to your machine
  2. @@ -912,8 +912,8 @@ Replace <defaultUser> in all files with YOUR_USER

    find ~/Repos/nixos/henrovnix_ok \
    -  -type d -name ".*" -prune -o \
    -  -type f -print0 \
    +-type d -name ".*" -prune -o \
    +-type f -print0 \
     | xargs -0 sed -i 's/=<defaultUser>=/YOUR_USER/g'
     
    @@ -922,8 +922,8 @@ Replace machine1 in all files with YOUR_HOSTNAME

    find ~/Repos/nixos/henrovnix_ok \
    -  -type d -name ".*" -prune -o \
    -  -type f -print0 \
    +-type d -name ".*" -prune -o \
    +-type f -print0 \
     | xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g'
     
    @@ -952,8 +952,8 @@ Run the build command to set up the system for the first time
-
-

4. Testing and generating builds

+
+

4. Testing and generating builds

At this stage, you should have a functional and reproducible system that can be edited, rebuilt, and extended according to your needs. The foundational structure is now in place, and further customization can occur incrementally through the modular configuration files. @@ -1016,46 +1016,46 @@ Other important files:

-
-

5. flake.lock for pinning input versions.

+
+

5. flake.lock for pinning input versions.

-
-

6. assets/* for non-Nix-managed artifacts such as images and wallpapers.

+
+

6. assets/* for non-Nix-managed artifacts such as images and wallpapers.

Generated outputs should not be edited directly. A CI workflow can tangle and commit generated outputs when they differ.

-
-

6.1. Emacs + Org + Tangle

+
+

6.1. Emacs + Org + Tangle

-
-

7. [Emacs](https://www.gnu.org/software/emacs/][Emacs) is used as the editor and execution environment for this literate configuration.

+
+

7. [Emacs](https://www.gnu.org/software/emacs/][Emacs) is used as the editor and execution environment for this literate configuration.

-
-

8. [Org](https://orgmode.org/][Org) mode provides the document structure and the source block execution model used here.

+
+

8. [Org](https://orgmode.org/][Org) mode provides the document structure and the source block execution model used here.

-
-

9. Tangling exports source blocks from this Org document into the corresponding configuration files.

+
+

9. Tangling exports source blocks from this Org document into the corresponding configuration files.

  • References of the form <<code-id>> are noweb placeholders that are expanded from other blocks during tangling.
-
-

9.1. Nix & NixOS

+
+

9.1. Nix & NixOS

-
-

10. [Nix](https://nix.dev/][Nix) is used to define packages, environments, and configuration as pure expressions.

+
+

10. [Nix](https://nix.dev/][Nix) is used to define packages, environments, and configuration as pure expressions.

-
-

11. [NixOS](https://nixos.org/][NixOS) evaluates Nix expressions into a complete system configuration that can be applied by rebuild operations.

+
+

11. [NixOS](https://nixos.org/][NixOS) evaluates Nix expressions into a complete system configuration that can be applied by rebuild operations.

-
-

11.1. Repository layout and folder conventions

+
+

11.1. Repository layout and folder conventions

<p> @@ -1068,8 +1068,8 @@ Generated outputs should not be edited directly. A CI workflow can tangle and co

-
-

11.2. Shared domain folders

+
+

11.2. Shared domain folders

<ul> @@ -1083,8 +1083,8 @@ Generated outputs should not be edited directly. A CI workflow can tangle and co

-
-

11.3. Full tree (including unchanged parts)

+
+

11.3. Full tree (including unchanged parts)

The tree below shows the full repository layout, with the standardized internal structure applied only inside @@ -1113,11 +1113,11 @@ The tree below shows the full repository layout, with the standardized internal │   │   │   │   │   ├── config.ron │   │   │   │   │   └── styles.css │   │   │   │   └── scripts -│   │   │   │   ├── hyprscrolling-per-monitor.sh -│   │   │   │   ├── hyprscroll-overflow.sh -│   │   │   │   ├── lid-lock.sh -│   │   │   │   ├── lid-restore.sh -│   │   │   │   └── powermenu.sh +│   │   │   │   ├── hyprscrolling-per-monitor.sh +│   │   │   │   ├── hyprscroll-overflow.sh +│   │   │   │   ├── lid-lock.sh +│   │   │   │   ├── lid-restore.sh +│   │   │   │   └── powermenu.sh │   │   │   ├── wallpaper │   │   │   │   ├── gif │   │   │   │   ├── pictures @@ -1135,20 +1135,20 @@ The tree below shows the full repository layout, with the standardized internal │   │   │   │   │   └── white_blobs_small.mp4 │   │   │   │   └── wallpaper.conf │   │   │   └── waybar -│   │   │   ├── config.jsonc -│   │   │   └── style.css +│   │   │   ├── config.jsonc +│   │   │   └── style.css │   │   ├── dev │   │   │   └── terminal -│   │   │   ├── alacritty.toml -│   │   │   ├── aliases.conf -│   │   │   ├── Catppuccin-Mocha.conf -│   │   │   ├── enabled_shells.conf -│   │   │   ├── kitty.conf -│   │   │   ├── starship.toml -│   │   │   └── zsh.conf +│   │   │   ├── alacritty.toml +│   │   │   ├── aliases.conf +│   │   │   ├── Catppuccin-Mocha.conf +│   │   │   ├── enabled_shells.conf +│   │   │   ├── kitty.conf +│   │   │   ├── starship.toml +│   │   │   └── zsh.conf │   │   ├── security │   │   │   └── ssh -│   │   │   └── ssh-client.conf +│   │   │   └── ssh-client.conf │   │   └── services │   ├── lock.png │   └── scripts @@ -1171,7 +1171,7 @@ The tree below shows the full repository layout, with the standardized internal │   ├── dev │   │   └── terminal.nix │   └── services -│   └── services.nix +│   └── services.nix ├── flake.lock ├── flake.nix ├── hardware @@ -1196,22 +1196,22 @@ The tree below shows the full repository layout, with the standardized internal │   │   ├── waybar.nix │   │   └── workspace_wallpaper.nix │   └── dev -│   ├── alacritty.nix -│   ├── dev.nix -│   ├── emacs -│   │   ├── default.nix -│   │   ├── early-init.el -│   │   └── init.el -│   ├── kitty.nix -│   ├── shells.nix -│   ├── starship.nix -│   └── zsh.nix +│   ├── alacritty.nix +│   ├── dev.nix +│   ├── emacs +│   │   ├── default.nix +│   │   ├── early-init.el +│   │   └── init.el +│   ├── kitty.nix +│   ├── shells.nix +│   ├── starship.nix +│   └── zsh.nix ├── LICENSE ├── machines │   └── traveldroid -│   ├── configuration.nix -│   ├── hardware-configuration.nix -│   └── home.nix +│   ├── configuration.nix +│   ├── hardware-configuration.nix +│   └── home.nix ├── README.html ├── README.org └── user.nix @@ -1219,8 +1219,8 @@ The tree below shows the full repository layout, with the standardized internal

-
-

11.4. Notes

+
+

11.4. Notes

<ul> @@ -1239,8 +1239,8 @@ I use nix flakes which means that t

{
-  inputs: # describes the function input, consisting mainly of package sources
-  outputs: # what the function outputs, a nixos configuration in our case
+inputs: # describes the function input, consisting mainly of package sources
+outputs: # what the function outputs, a nixos configuration in our case
 }
 
@@ -1253,8 +1253,8 @@ This prevents unwanted and surprise updates when rebuilding without changing the
-
-

12. TLDR App List

+
+

12. TLDR App List

@@ -1312,7 +1312,7 @@ This prevents unwanted and surprise updates when rebuilding without changing the - + @@ -1328,8 +1328,8 @@ This prevents unwanted and surprise updates when rebuilding without changing the
IconsCatppuccin Nix Catppuccin Nix
-
-

13. Configuration Variables

+
+

13. Configuration Variables

I have a bunch of constant strings that I would rather put in a file. Thats what user.nix is. @@ -1346,8 +1346,8 @@ The values are imported at the beginning and are available to almost all the fun

-
-

14. Flake Inputs

+
+

14. Flake Inputs

The inputs for my system's configuration are very simple @@ -1362,34 +1362,34 @@ Sometimes pinned to a specific commit because unstable broke something and the f

{
-  description = "Henrov's nixos configuration";
-  inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
-    home-manager = {
-      url = "github:nix-community/home-manager";
-      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";
-    };
+description = "Henrov's nixos configuration";
+inputs = {
+nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+home-manager = {
+  url = "github:nix-community/home-manager";
+  inputs.nixpkgs.follows = "nixpkgs";
+};
+emacs-overlay = {
+  url = "github:nix-community/emacs-overlay";
+  inputs.nixpkgs.follows = "nixpkgs";
   };
-  <<flake-outputs>>
+catppuccin = {
+  url = "github:catppuccin/nix";
+  inputs.nixpkgs.follows = "nixpkgs";
+};
+zen-browser = {
+  url = "github:youwen5/zen-browser-flake";
+  inputs.nixpkgs.follows = "nixpkgs";
+};
+};
+<<flake-outputs>>
 }
 
-
-

15. Flake Output

+
+

15. Flake Output

Now that the inputs are ready, the outputs define what the system will actually look like. I also define the machines that this configuration specifies early on. Finally, I iterate over the machines list and pull files from /.machines/${name} subdirectory. This allows me to have configuration that has machine specific configuration limited to those files while also keeping a modular reusable base. @@ -1397,52 +1397,52 @@ We also add a devshell that makes editing this repository easier in emacs.

-
outputs = inputs@{
-  nixpkgs,
-  home-manager,
-  emacs-overlay,
-  catppuccin,
-  ...
+
outputs = inputs@{
+nixpkgs,
+home-manager,
+emacs-overlay,
+catppuccin,
+...
 }:
-  let
-    user = import ./user.nix;
-    lib = nixpkgs.lib;
-    machines = [
-      "traveldroid"
+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 = [
+    <<flake-emacs-module>>
+    <<flake-config-module>>
+    <<flake-home-module>>
+    catppuccin.nixosModules.catppuccin # theme
     ];
-    pkgs = import nixpkgs {
-      inherit (user) system;
-    };
-  in
-    {
-      nixosConfigurations = builtins.listToAttrs (
-        builtins.map (machine: {
-          name = machine;
-          value = lib.nixosSystem {
-            modules = [
-              <<flake-emacs-module>>
-              <<flake-config-module>>
-              <<flake-home-module>>
-              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
-        ];
-      };
+    specialArgs = {
+    hostname = machine;
+    inherit user;
+    inherit inputs;
+    flakeRoot = inputs.self;
     };
+  };
+  }) machines
+  );
+
+  devShells.${user.system}.default = pkgs.mkShell {
+  buildInputs = with pkgs; [
+  nil
+  nixfmt-rfc-style
+  ];
+  };
+};
 
 
@@ -1458,8 +1458,8 @@ Overlays are a special nix way to override existing packages within a repository

-
({ ... }: {
-  nixpkgs.overlays = [ emacs-overlay.overlays.default ];
+
({ ... }: {
+nixpkgs.overlays = [ emacs-overlay.overlays.default ];
 })
 
@@ -1468,7 +1468,7 @@ Overlays are a special nix way to override existing packages within a repository Then the machine specific configuration, in this case, just "traveldroid".

-
./machines/${machine}/configuration.nix
+
./machines/${machine}/configuration.nix
 
@@ -1478,18 +1478,18 @@ This can be initialized and managed on its own but I'd rather use the nixo

-
home-manager.nixosModules.home-manager
+
home-manager.nixosModules.home-manager
 {
-  home-manager.useGlobalPkgs = true;
-  home-manager.useUserPackages = true;
+home-manager.useGlobalPkgs = true;
+home-manager.useUserPackages = true;
 
-  home-manager.extraSpecialArgs = {
-    inherit user inputs;
-    flakeRoot = inputs.self;
-  };
+home-manager.extraSpecialArgs = {
+  inherit user inputs;
+  flakeRoot = inputs.self;
+};
 
-  <<flake-home-backup>>
-  <<flake-home-config>>
+<<flake-home-backup>>
+<<flake-home-config>>
 }
 
 
@@ -1512,17 +1512,17 @@ Finally I pull in the machine specific home configuration. Along with the overri
home-manager.users.${user.username} = {
-  imports =  [
-    ./machines/${machine}/home.nix
-    catppuccin.homeModules.catppuccin
-  ];
+imports =  [
+  ./machines/${machine}/home.nix
+  catppuccin.homeModules.catppuccin
+];
 };
 
-
-

15.1. Envrc + Direnv

+
+

15.1. Envrc + Direnv

Editing this file will be much nicer if we have the dev environment configured. @@ -1536,21 +1536,21 @@ This tells direnv to load the devshell in the watch_file .envrc.private if [[ -f .envrc.private ]]; then - source_env .envrc.private +source_env .envrc.private fi

-
-

16. Machines

+
+

16. Machines

The individual machines subdirectory is configured as follows :-

-
+--machine
+
+--machine
 |  +--configuration.nix
 |  +--home.nix
 |  +--hardware-configuration.nix
@@ -1571,12 +1571,12 @@ This imported object (or function result) is just trivially merged into a common
 We can take a look at that the common hardware options I have for all my machines.
 

-
-

16.0.1. Other Utils

+
+

16.0.1. Other Utils

    -
  1. Updates
    +
  2. Updates

    To update the computer, I just need to update the flake.lock file to have references to the latest repository. This is done with :- @@ -1590,8 +1590,8 @@ To update the computer, I just need to update the flake.lock file t

-
-

17. Hardware

+
+

17. Hardware

I'll let the code comments explain the file here. @@ -1600,33 +1600,33 @@ I'll let the code comments explain the file here.

{ pkgs, lib, user, config, ...} :
 {
-  nixpkgs.hostPlatform = lib.mkDefault user.system;            # x86_64-linux
-  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu
+nixpkgs.hostPlatform = lib.mkDefault user.system;    # x86_64-linux
+powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu
 
-  # update cpu microcode with firmware that allows redistribution
-  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+# update cpu microcode with firmware that allows redistribution
+hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
 
-  hardware = {
-    # always enable bluetooth
-    bluetooth.enable = true;
+hardware = {
+# always enable bluetooth
+bluetooth.enable = true;
 
-    # always enable graphics drivers and enable a bunch of layers for it (including vulkan validation)
-    graphics = {
-      enable = true;
-      extraPackages = with pkgs; [
-        vulkan-validation-layers # helps catch and debug vulkan crashes
-      ];
-    };
-  };
+# always enable graphics drivers and enable a bunch of layers for it (including vulkan validation)
+graphics = {
+  enable = true;
+  extraPackages = with pkgs; [
+  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
 }
 
-
-

18. Configuration

+
+

18. Configuration

This section describes the main system configuration for the computers that I have. Nix will look for a default.nix file if you give it a path to a folder to import. And default.nix looks as follows :- @@ -1636,49 +1636,49 @@ This section describes the main system configuration for the computers that I ha

  { pkgs, user, ... } :
 {
   imports = [
-      ./apps/install_flatpaks.nix
-      ./apps/install_packages.nix
-      ./core/files.nix
-      ./core/locale.nix
-      ./core/networking.nix
-      ./core/nix-settings.nix
-      #./core/login-tuigreeter.nix
-      ./core/login-lightdm.nix
-      ./desktop/audio.nix
-      ./desktop/hyprland.nix
-      ./dev/terminal.nix
-      ./core/boot.nix
-      ./services/services.nix
-    ];
+  ./apps/install_flatpaks.nix
+  ./apps/install_packages.nix
+  ./core/files.nix
+  ./core/locale.nix
+  ./core/networking.nix
+  ./core/nix-settings.nix
+  #./core/login-tuigreeter.nix
+  ./core/login-lightdm.nix
+  ./desktop/audio.nix
+  ./desktop/hyprland.nix
+  ./dev/terminal.nix
+  ./core/boot.nix
+  ./services/services.nix
+  ];
 
-    <<config-system-packages>>
+  <<config-system-packages>>
 
-    <<config-user>>
+  <<config-user>>
 
-    <<config-programs>>
+  <<config-programs>>
 
-    <<config-fonts>>
+  <<config-fonts>>
 
-    # enable the catppuccin theme for everything with mocha + blue accents
-    catppuccin.enable = true;
-    catppuccin.flavor = "mocha";
-    catppuccin.accent = "blue";
+  # enable the catppuccin theme for everything with mocha + blue accents
+  catppuccin.enable = true;
+  catppuccin.flavor = "mocha";
+  catppuccin.accent = "blue";
 
-    system.stateVersion = user.stateVersion;
+  system.stateVersion = user.stateVersion;
 }
 
-
-

18.1. Apps section

+
+

18.1. Apps section

This section describes a way of installing packages, either through nixpkgs orr flatpak. What apps to instal is decided in the files ./assets/conf/apps/packages.conf and flatpaks.conf

-
-

18.2. installpackages.nix

+
+

18.2. installpackages.nix

{ config, lib, pkgs, flakeRoot, inputs, ... }:
@@ -1689,47 +1689,47 @@ let
   rawLines = lib.splitString "\n" raw;
   # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
   _guard = assert !(
-    builtins.stringLength raw > 1 &&
-    builtins.length rawLines == builtins.stringLength raw
+  builtins.stringLength raw > 1 &&
+  builtins.length rawLines == builtins.stringLength raw
   ); true;
   cleanLine = l:
-    let
-      noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
-      noInlineComment = lib.head (lib.splitString "#" noCR);
-    in
-      lib.strings.trim noInlineComment;
+  let
+  noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
+  noInlineComment = lib.head (lib.splitString "#" noCR);
+  in
+  lib.strings.trim noInlineComment;
   entries =
-    builtins.filter (l: l != "")
-      (map cleanLine rawLines);
+  builtins.filter (l: l != "")
+  (map cleanLine rawLines);
   resolvePkg = name:
-    let
-      parts = lib.splitString "." name;
-      found = lib.attrByPath parts null pkgs;
-    in
-      if found == null then
-        throw ''
-          install_packages.nix: package not found in pkgs
-          Token            : ${builtins.toJSON name}
-          packages.conf     : ${toString packagesConfPath}
-          Hint             : check the attribute name on search.nixos.org/packages
-        ''
-      else
-        found;
+  let
+  parts = lib.splitString "." name;
+  found = lib.attrByPath parts null pkgs;
+  in
+  if found == null then
+    throw ''
+    install_packages.nix: package not found in pkgs
+    Token    : ${builtins.toJSON name}
+    packages.conf   : ${toString packagesConfPath}
+    Hint     : check the attribute name on search.nixos.org/packages
+    ''
+  else
+    found;
   packages = builtins.seq _guard (map resolvePkg entries);
   zenBrowser =
-    inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
+  inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
 in
 {
   environment.systemPackages =
-    packages
-    ++ [ zenBrowser ];
+  packages
+  ++ [ zenBrowser ];
 }
 
-
-

18.3. installflatpaks.nix

+
+

18.3. installflatpaks.nix

{ config, pkgs, lib, flakeRoot, ... }:
@@ -1742,107 +1742,107 @@ let
 
   # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
   _guard = assert !(
-    builtins.stringLength raw > 1 &&
-    builtins.length rawLines == builtins.stringLength raw
+  builtins.stringLength raw > 1 &&
+  builtins.length rawLines == builtins.stringLength raw
   ); true;
 
   cleanLine = l:
-    let
-      noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
-      noInlineComment = lib.head (lib.splitString "#" noCR);
-    in
-      lib.strings.trim noInlineComment;
+  let
+  noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
+  noInlineComment = lib.head (lib.splitString "#" noCR);
+  in
+  lib.strings.trim noInlineComment;
 
   entries =
-    builtins.filter (l: l != "")
-      (map cleanLine rawLines);
+  builtins.filter (l: l != "")
+  (map cleanLine rawLines);
 
   # 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.
   dotCount = s: builtins.length (lib.splitString "." s) - 1;
 
   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 =
-    builtins.seq _guard (
-      builtins.map (id:
-        if isValidId id then true else
-          throw ''
-            ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots)
+  builtins.seq _guard (
+  builtins.map (id:
+    if isValidId id then true else
+    throw ''
+    ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots)
 
-            Token        : ${builtins.toJSON id}
-            flatpaks.conf : ${toString flatpakConfPath}
+    Token    : ${builtins.toJSON id}
+    flatpaks.conf : ${toString flatpakConfPath}
 
-            Fix: remove stray tokens/headers, or comment them out with '#'.
-          ''
-      ) entries
-    );
+    Fix: remove stray tokens/headers, or comment them out with '#'.
+    ''
+  ) entries
+  );
 
   # Use validated entries
   flatpakApps = builtins.seq _validate entries;
 
   syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" ''
-    set -euo pipefail
+  set -euo pipefail
 
-    # Use the deployed config path (matches environment.etc below)
-    CONF="/etc/flatpak/flatpaks.conf"
-    if [[ -f "$CONF" ]]; then
-      echo "flatpak-sync: using $CONF"
-    else
-      echo "flatpak-sync: WARNING: $CONF not found, using embedded list"
-    fi
+  # Use the deployed config path (matches environment.etc below)
+  CONF="/etc/flatpak/flatpaks.conf"
+  if [[ -f "$CONF" ]]; then
+  echo "flatpak-sync: using $CONF"
+  else
+  echo "flatpak-sync: WARNING: $CONF not found, using embedded list"
+  fi
 
-    if ! flatpak remotes --system --columns=name | grep -qx flathub; then
-      flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
-    fi
+  if ! flatpak remotes --system --columns=name | grep -qx flathub; then
+  flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
+  fi
 
-    desired_apps=(
-      ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)}
-    )
+  desired_apps=(
+  ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)}
+  )
 
-    for app in "''${desired_apps[@]}"; do
-      if ! flatpak info --system "$app" >/dev/null 2>&1; then
-        flatpak install --system -y --noninteractive flathub "$app"
-      fi
-    done
+  for app in "''${desired_apps[@]}"; do
+  if ! flatpak info --system "$app" >/dev/null 2>&1; then
+    flatpak install --system -y --noninteractive flathub "$app"
+  fi
+  done
   '';
 in
 {
   services.flatpak.enable = true;
 
   xdg.portal = {
-    enable = true;
-    extraPortals = with pkgs; [
-      xdg-desktop-portal-hyprland
-      xdg-desktop-portal-gtk
-    ];
+  enable = true;
+  extraPortals = with pkgs; [
+  xdg-desktop-portal-hyprland
+  xdg-desktop-portal-gtk
+  ];
   };
 
   # 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 = {
-    description = "Install Flatpak apps listed in flatpaks.conf";
-    wantedBy = [ "multi-user.target" ];
-    wants = [ "network-online.target" ];
-    after = [ "network-online.target" ];
+  description = "Install Flatpak apps listed in flatpaks.conf";
+  wantedBy = [ "multi-user.target" ];
+  wants = [ "network-online.target" ];
+  after = [ "network-online.target" ];
 
-    serviceConfig = {
-      Type = "oneshot";
-      ExecStart = syncFlatpaks;
-    };
+  serviceConfig = {
+  Type = "oneshot";
+  ExecStart = syncFlatpaks;
+  };
 
-    restartTriggers = [ flatpakConfPath ];
-    path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
+  restartTriggers = [ flatpakConfPath ];
+  path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
   };
 }
 
-
-

18.4. Nix Settings

+
+

18.4. Nix Settings

These are global nix settings that configure the settings for the actual tool. @@ -1851,48 +1851,48 @@ These are global nix settings that configure the settings for the actual tool.

{ pkgs, user, ... } :
 {
-  nix.settings = {
-    # enable flakes
-    experimental-features = ["nix-command" "flakes"];
+nix.settings = {
+# enable flakes
+experimental-features = ["nix-command" "flakes"];
 
-    # add a cache that speed up new applications by downloading binaries
-    # from the trusted cache instead of compiling from sourcer
-    substituters = [
-      "https://nix-community.cachix.org"
-    ];
-    # trust the cache public key
-    trusted-public-keys = [
-      "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
-    ];
-  };
+# add a cache that speed up new applications by downloading binaries
+# from the trusted cache instead of compiling from sourcer
+substituters = [
+  "https://nix-community.cachix.org"
+];
+# trust the cache public key
+trusted-public-keys = [
+  "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
+];
+};
 
-  # allow proprietary software on this machine. I'm not a purist.
-  nixpkgs.config.allowUnfree = true;
-  # unityhub depends on this... for now
-  nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ];
+# allow proprietary software on this machine. I'm not a purist.
+nixpkgs.config.allowUnfree = true;
+# unityhub depends on this... for now
+nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ];
 
-  # this declares how often old configurations are cleared up.
-  # i cleanup anything older than a week, every week.
-  nix.gc = {
-    automatic = true;
-    options = "--delete-older-than 7d";
-    dates = "weekly";
-  };
+# this declares how often old configurations are cleared up.
+# i cleanup anything older than a week, every week.
+nix.gc = {
+automatic = true;
+options = "--delete-older-than 7d";
+dates = "weekly";
+};
 
-  programs = {
-    # command line utility that makes applying changes easy and pretty
-    nh = {
-      enable = true;
-      flake = "/home/${user.username}/system";
-    };
-  };
+programs = {
+# command line utility that makes applying changes easy and pretty
+nh = {
+  enable = true;
+  flake = "/home/${user.username}/system";
+};
+};
 }
 
-
-

18.5. Boot

+
+

18.5. Boot

This file has most of the settings the control how the computer boots up. @@ -1902,44 +1902,44 @@ This file has most of the settings the control how the computer boots up.

{ pkgs, ... } :
 {
   boot = {
-    initrd = {
-      verbose = false;     # its a lot of logs. dont need it, unless we do.
-      kernelModules = [ ]; # no kernel modules on boot
-    };
+  initrd = {
+  verbose = false;   # its a lot of logs. dont need it, unless we do.
+  kernelModules = [ ]; # no kernel modules on boot
+  };
 
-    extraModulePackages = [ ];                   # no extra packages on boot either
-    kernelPackages = pkgs.linuxPackages_latest;  # latest greatest linux kernel
-    kernelParams = [ "silent" ];                 # quiet those logs
+  extraModulePackages = [ ];       # no extra packages on boot either
+  kernelPackages = pkgs.linuxPackages_latest;  # latest greatest linux kernel
+  kernelParams = [ "silent" ];       # quiet those logs
 
-    consoleLogLevel = 0;                         # quiten more logs
-    plymouth.enable = true;                      # graphical boot animation instead
+  consoleLogLevel = 0;         # quiten more logs
+  plymouth.enable = true;        # graphical boot animation instead
 
-    supportedFilesystems = [ "ntfs" ];           # should see the ntfs (windows)
+  supportedFilesystems = [ "ntfs" ];     # should see the ntfs (windows)
 
-    loader = {
-      systemd-boot.enable = true;                # systemd-boot
-      systemd-boot.configurationLimit = 10;
-      efi.canTouchEfiVariables = true;           # allow editing efi to edit the boot loader
+  loader = {
+  systemd-boot.enable = true;      # systemd-boot
+  systemd-boot.configurationLimit = 10;
+  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
+  };
   };
 }
 
-
-

18.6. Login

+
+

18.6. Login

Here we control what the login screen would look like. In configuration/default.nix you can choose whether to use tuigreet (very minimalistic) or LightDM (nicer, themeable)

-
-

18.7. Tuigreet

+
+

18.7. Tuigreet

Doesn't match the rest of the aesthetic of the system (with hyprland), but I like its simplicity. @@ -1948,64 +1948,64 @@ Doesn't match the rest of the aesthetic of the system (with hyprland), but I lik

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

18.8. LightDM

+
+

18.8. LightDM

{ config, pkgs, lib, ... }:
 
 let
   lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf;
-  lockPng     = ../../assets/lock.png;
+  lockPng   = ../../assets/lock.png;
 
   greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf;
-  greeterRaw      = builtins.readFile greeterConfPath;
+  greeterRaw  = builtins.readFile greeterConfPath;
 
   # Extract "key = value" from the greeter conf.
   # Returns null if not found.
   getIniValue = key:
-    let
-      lines = lib.splitString "\n" greeterRaw;
+  let
+  lines = lib.splitString "\n" greeterRaw;
 
-      # 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).
-      m =
-        let
-          ms = builtins.filter (x: x != null) (map (line:
-            builtins.match
-              ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$")
-              line
-          ) lines);
-        in
-          if ms == [] then null else builtins.elemAt ms 0;
+  # 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).
+  m =
+    let
+    ms = builtins.filter (x: x != null) (map (line:
+    builtins.match
+      ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$")
+      line
+    ) lines);
     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.
   themePkgKey  = getIniValue "theme-name";
-  iconPkgKey   = getIniValue "icon-theme-name";
+  iconPkgKey = getIniValue "icon-theme-name";
   cursorPkgKey = getIniValue "cursor-theme-name";
 
   cursorSizeStr = getIniValue "cursor-theme-size";
   cursorSize =
-    if cursorSizeStr == null then null
-    else lib.toInt (lib.strings.trim cursorSizeStr);
+  if cursorSizeStr == null then null
+  else lib.toInt (lib.strings.trim cursorSizeStr);
 
   # Map package-keys (from greeter.conf) -> { package, name }
   #
@@ -2013,98 +2013,98 @@ let
   # - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons.
   # - "package" is the Nixpkgs derivation providing it.
   pkgMap = {
-    catppuccinThemePkg = {
-      package = pkgs.catppuccin-gtk.override {
-        accents = [ "blue" ];
-        variant = "mocha";
-        size    = "standard";
-        tweaks  = [ ];
-      };
-      name = "Catppuccin-Mocha-Standard-Blue-Dark";
-    };
+  catppuccinThemePkg = {
+  package = pkgs.catppuccin-gtk.override {
+    accents = [ "blue" ];
+    variant = "mocha";
+    size  = "standard";
+    tweaks  = [ ];
+  };
+  name = "Catppuccin-Mocha-Standard-Blue-Dark";
+  };
 
-    papirus-icon-theme = {
-      package = pkgs.papirus-icon-theme;
-      name    = "Papirus-Dark";
-    };
+  papirus-icon-theme = {
+  package = pkgs.papirus-icon-theme;
+  name  = "Papirus-Dark";
+  };
 
-    bibata-cursors = {
-      package = pkgs.bibata-cursors;
-      name    = "Bibata-Modern-Ice";
-    };
+  bibata-cursors = {
+  package = pkgs.bibata-cursors;
+  name  = "Bibata-Modern-Ice";
+  };
   };
 
   pick = key:
-    if key == null then
-      throw "lightdm: missing required key in ${toString greeterConfPath}"
-    else if !(pkgMap ? "${key}") then
-      throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}"
-    else
-      pkgMap."${key}";
+  if key == null then
+  throw "lightdm: missing required key in ${toString greeterConfPath}"
+  else if !(pkgMap ? "${key}") then
+  throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}"
+  else
+  pkgMap."${key}";
 
   themeSel  = pick themePkgKey;
-  iconSel   = pick iconPkgKey;
+  iconSel = pick iconPkgKey;
   cursorSel = pick cursorPkgKey;
 
   # Rewrite greeter.conf so LightDM sees REAL names, not package keys.
   # Also force background to lockPng.
-    greeterFixed =
-    ''
-      [greeter]
-      theme-name = ${themeSel.name}
-      icon-theme-name = ${iconSel.name}
-      cursor-theme-name = ${cursorSel.name}
-      ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"}
-    ''
-    + "\n"
-    + greeterRaw;
+  greeterFixed =
+  ''
+  [greeter]
+  theme-name = ${themeSel.name}
+  icon-theme-name = ${iconSel.name}
+  cursor-theme-name = ${cursorSel.name}
+  ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"}
+  ''
+  + "\n"
+  + greeterRaw;
 in
 {
   services.greetd.enable = false;
 
   services.xserver = {
+  enable = true;
+  desktopManager.xterm.enable = false;
+
+  displayManager.lightdm = {
+  enable = true;
+  background = lockPng;
+
+  greeters.gtk = {
     enable = true;
-    desktopManager.xterm.enable = false;
 
-    displayManager.lightdm = {
-      enable = true;
-      background = lockPng;
-
-      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;
+    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;
+  };
   };
 
   programs.hyprland.enable = true;
 
   # Optional: make them available system-wide as well
   environment.systemPackages = [
-    themeSel.package
-    iconSel.package
-    cursorSel.package
+  themeSel.package
+  iconSel.package
+  cursorSel.package
   ];
 }
 
@@ -2112,8 +2112,8 @@ in
 
-
-

18.9. Terminal (default system)

+
+

18.9. Terminal (default system)

This is the initial system level configuration for the terminal that I use on this machine. Its just zsh. @@ -2132,8 +2132,8 @@ This is the initial system level configuration for the terminal that I use on th

-
-

18.10. Files

+
+

18.10. Files

I use Thunar as the file explorer. Also setup a few plugins for Thunar in this config. @@ -2144,38 +2144,38 @@ Along with that, a few other utilities like zip and enabling services to automou

{ pkgs, user, config, ... }:
 {
   environment.systemPackages = with pkgs; [
-    zip
-    unzip
-    p7zip
-    usbutils
-    udiskie
-    file-roller
+  zip
+  unzip
+  p7zip
+  usbutils
+  udiskie
+  file-roller
   ];
 
   programs.thunar = {
-    enable = true;
-    plugins = with pkgs; [
-      thunar-archive-plugin
-      thunar-media-tags-plugin
-      thunar-volman
-      thunar-vcs-plugin
-    ];
+  enable = true;
+  plugins = with pkgs; [
+  thunar-archive-plugin
+  thunar-media-tags-plugin
+  thunar-volman
+  thunar-vcs-plugin
+  ];
   };
 
   programs.xfconf.enable = true; # to save thunar settings
 
   services = {
-    gvfs.enable = true;    # Mount, trash, and other functionalities
-    tumbler.enable = true; # Thumbnail support for images
-    udisks2.enable = true; # Auto mount usb drives
+  gvfs.enable = true;  # Mount, trash, and other functionalities
+  tumbler.enable = true; # Thumbnail support for images
+  udisks2.enable = true; # Auto mount usb drives
   };
 }
 
-
-

18.11. Locale

+
+

18.11. Locale

I live in Netherlands and would like all my locale and timezone settings to match. Except my default locale. @@ -2183,34 +2183,34 @@ I live in Netherlands and would like all my locale and timezone settings to matc

{ user, ... } :
 let
-  locale = user.locale;
-  defaultLocale = "nl_NL.UTF-8";
+locale = user.locale;
+defaultLocale = "nl_NL.UTF-8";
 in
 {
-  # Set your time zone.
-  time.timeZone = "Europe/Amsterdam";
+# Set your time zone.
+time.timeZone = "Europe/Amsterdam";
 
-  # Select internationalisation properties.
-  i18n.defaultLocale = defaultLocale;
+# Select internationalisation properties.
+i18n.defaultLocale = defaultLocale;
 
-  i18n.extraLocaleSettings = {
-    LC_ADDRESS = locale;
-    LC_IDENTIFICATION = locale;
-    LC_MEASUREMENT = locale;
-    LC_MONETARY = locale;
-    LC_NAME = locale;
-    LC_NUMERIC = locale;
-    LC_PAPER = locale;
-    LC_TELEPHONE = locale;
-    LC_TIME = defaultLocale;
-  };
+i18n.extraLocaleSettings = {
+LC_ADDRESS = locale;
+LC_IDENTIFICATION = locale;
+LC_MEASUREMENT = locale;
+LC_MONETARY = locale;
+LC_NAME = locale;
+LC_NUMERIC = locale;
+LC_PAPER = locale;
+LC_TELEPHONE = locale;
+LC_TIME = defaultLocale;
+};
 }
 
-
-

18.12. Networking

+
+

18.12. Networking

Not much to see here. I want networking to be enabled. I want firewall as well. @@ -2219,21 +2219,21 @@ Not much to see here. I want networking to be enabled. I want firewall as well.

{ pkgs, lib, ... }:
 {
   networking = {
-    useDHCP = lib.mkDefault true;
-    networkmanager.enable = true;
-    networkmanager.wifi.backend = "iwd";
-    wireless.iwd.enable = true;
-    wireless.userControlled.enable = true;
-    firewall = {
-      enable = true;
-      # KDE Connect: discovery + encrypted connections
-      allowedTCPPortRanges = [
-        { from = 1714; to = 1764; }
-      ];
-      allowedUDPPortRanges = [
-        { from = 1714; to = 1764; }
-      ];
-    };
+  useDHCP = lib.mkDefault true;
+  networkmanager.enable = true;
+  networkmanager.wifi.backend = "iwd";
+  wireless.iwd.enable = true;
+  wireless.userControlled.enable = true;
+  firewall = {
+  enable = true;
+  # KDE Connect: discovery + encrypted connections
+  allowedTCPPortRanges = [
+    { from = 1714; to = 1764; }
+  ];
+  allowedUDPPortRanges = [
+    { from = 1714; to = 1764; }
+  ];
+  };
   };
   environment.systemPackages = with pkgs; [ impala ];
 }
@@ -2241,8 +2241,8 @@ Not much to see here. I want networking to be enabled. I want firewall as well.
 
-
-

18.13. Hyprland

+
+

18.13. Hyprland

This is a big one because the DE needs so much configuration. This section mostly installs Hyprland. @@ -2252,56 +2252,56 @@ The configuration is done in the home manager section.

{ pkgs, ... }:
 {
   nix.settings = {
-    substituters = [ "https://hyprland.cachix.org" ];
-    trusted-public-keys = [
-      "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
-    ];
+  substituters = [ "https://hyprland.cachix.org" ];
+  trusted-public-keys = [
+  "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
+  ];
   };
   services.dbus.enable = true;
   security.polkit.enable = true;
   services.flatpak.enable = true;
   services.pipewire = {
-    enable = true;
-    alsa.enable = true;
-    alsa.support32Bit = true;
-    pulse.enable = true;
-    wireplumber.enable = true;
+  enable = true;
+  alsa.enable = true;
+  alsa.support32Bit = true;
+  pulse.enable = true;
+  wireplumber.enable = true;
   };
   services.gvfs.enable = true;
   xdg.portal = {
-    enable = true;
-    extraPortals = with pkgs; [
-      xdg-desktop-portal-hyprland
-      xdg-desktop-portal-gtk
-    ];
-    config.common.default = [ "hyprland" "gtk" ];
+  enable = true;
+  extraPortals = with pkgs; [
+  xdg-desktop-portal-hyprland
+  xdg-desktop-portal-gtk
+  ];
+  config.common.default = [ "hyprland" "gtk" ];
   };
   environment.systemPackages = with pkgs; [
-    walker
-    uwsm
-    hyprland-qtutils
-    hyprpolkitagent
-    grimblast
+  walker
+  uwsm
+  hyprland-qtutils
+  hyprpolkitagent
+  grimblast
   ];
   programs = {
-    uwsm.enable = true;
-    uwsm.waylandCompositors.hyprland = {
-      prettyName = "Hyprland";
-      comment = "Hyprland compositor managed by UWSM";
-      binPath = "/run/current-system/sw/bin/Hyprland";
-    };
-    hyprland = {
-      withUWSM = true;
-      enable = true;
-      xwayland.enable = true;
-    };
+  uwsm.enable = true;
+  uwsm.waylandCompositors.hyprland = {
+  prettyName = "Hyprland";
+  comment = "Hyprland compositor managed by UWSM";
+  binPath = "/run/current-system/sw/bin/Hyprland";
+  };
+  hyprland = {
+  withUWSM = true;
+  enable = true;
+  xwayland.enable = true;
+  };
   };
   environment.sessionVariables = {
-    XDG_SESSION_TYPE = "wayland";
-    XDG_CURRENT_DESKTOP = "Hyprland";
-    XDG_SESSION_DESKTOP = "Hyprland";
-    NIXOS_OZONE_WL = "1";
-    XCURSOR_SIZE = "24";
+  XDG_SESSION_TYPE = "wayland";
+  XDG_CURRENT_DESKTOP = "Hyprland";
+  XDG_SESSION_DESKTOP = "Hyprland";
+  NIXOS_OZONE_WL = "1";
+  XCURSOR_SIZE = "24";
   };
   security.pam.services.hyprlock = { };
   # Optional; GNOME-specific (keep only if you really use gnome-keyring integration)
@@ -2313,8 +2313,8 @@ The configuration is done in the home manager section.
 
-
-

18.14. Services

+
+

18.14. Services

These are some of the services that I enable at the system level. Explanation in the comments. @@ -2322,54 +2322,54 @@ These are some of the services that I enable at the system level. Explanation in

{ user, ...} :
 {
-  services = {
-    blueman.enable = true;                # bluetooth manager
-    fwupd.enable = true;                  # firmware updating service
-    fstrim.enable = true;                 # ssd maintenance service
-    thermald.enable = true;               # thermal regulation service
-    printing.enable = true;               # printing services, cups
-    gnome.gnome-keyring.enable = true;    # keyring
-    flatpak.enable = true;                # allow installing things from flatpaks
-    #flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
+services = {
+blueman.enable = true;      # bluetooth manager
+fwupd.enable = true;      # firmware updating service
+fstrim.enable = true;       # ssd maintenance service
+thermald.enable = true;     # thermal regulation service
+printing.enable = true;     # printing services, cups
+gnome.gnome-keyring.enable = true;  # keyring
+flatpak.enable = true;      # allow installing things from flatpaks
+#flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
 
-    # printer discovery
-    avahi = {
-      enable = true;
-      nssmdns4 = true;
-      openFirewall = true;
-    };
-  };
+# printer discovery
+avahi = {
+  enable = true;
+  nssmdns4 = true;
+  openFirewall = true;
+};
+};
 
-  virtualisation.docker.enable = true;    # enable docker
-  users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group
+virtualisation.docker.enable = true;  # enable docker
+users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group
 }
 
-
-

18.15. Audio

+
+

18.15. Audio

{ config, pkgs, lib, ... }:
 
 {
   environment.systemPackages = with pkgs; [
-    pipewire
-    wireplumber
-    alsa-utils
-    pulseaudio
-    pamixer
-    pavucontrol
+  pipewire
+  wireplumber
+  alsa-utils
+  pulseaudio
+  pamixer
+  pavucontrol
   ];
 
   services.pipewire = {
-    enable = true;
-    alsa.enable = true;
-    alsa.support32Bit = true;
-    pulse.enable = true;
-    jack.enable = true;
-    wireplumber.enable = true;
+  enable = true;
+  alsa.enable = true;
+  alsa.support32Bit = true;
+  pulse.enable = true;
+  jack.enable = true;
+  wireplumber.enable = true;
   };
 
   security.rtkit.enable = true;
@@ -2379,91 +2379,91 @@ These are some of the services that I enable at the system level. Explanation in
 
   # Prefer analog over HDMI/DP in a machine-agnostic way
   services.pipewire.wireplumber.extraConfig."51-audio-priorities" = {
-    "monitor.alsa.rules" = [
-      # De-prioritize HDMI / DisplayPort sinks
-      {
-        matches = [
-          { "node.name" = "~alsa_output\\..*HDMI.*"; }
-          { "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;
-        };
-      }
+  "monitor.alsa.rules" = [
+  # De-prioritize HDMI / DisplayPort sinks
+  {
+    matches = [
+    { "node.name" = "~alsa_output\\..*HDMI.*"; }
+    { "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;
+    };
+  }
+  ];
   };
 
   # Optional: clear "sticky" user-selected defaults so priority rules win
   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" ];
-    partOf = [ "wireplumber.service" ];
-    wantedBy = [ "default.target" ];
+  after = [ "wireplumber.service" ];
+  partOf = [ "wireplumber.service" ];
+  wantedBy = [ "default.target" ];
 
-    serviceConfig = {
-      Type = "oneshot";
-      ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes";
-    };
+  serviceConfig = {
+  Type = "oneshot";
+  ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes";
+  };
   };
 }
 
-
-

18.16. Fonts

+
+

18.16. Fonts

Nothing much to see here. I love Aporetic, and I use it everywhere.

-
fonts.packages = with pkgs; [
-  aporetic
-  nerd-fonts.iosevka
+
fonts.packages = with pkgs; [
+aporetic
+nerd-fonts.iosevka
 ];
 
-
-

18.17. User Config

+
+

18.17. User Config

This creates the user profile that I login with. Initially created during install.

-
users.users.${user.username} = {
-  isNormalUser = true;
-  description = "henrov";
-  extraGroups = [
-    "networkmanager" # allow editing network connections
-    "wheel"          # can do sudo
-    "scanner"        # access to the network scanner
-    "lp"             # access to the printer
-  ];
+
users.users.${user.username} = {
+isNormalUser = true;
+description = "henrov";
+extraGroups = [
+"networkmanager" # allow editing network connections
+"wheel"    # can do sudo
+"scanner"    # access to the network scanner
+"lp"     # access to the printer
+];
 };
 
-
-

19. Home

+
+

19. Home

I use home-manager to manage my user level dotfiles and configurations. @@ -2471,8 +2471,8 @@ Most of the "theme" of the system is decided here. I also use it to install programs that are okay with being installed at the user level instead of the system.

-
-

19.1. default.nix

+
+

19.1. default.nix

This module will import all necessities. @@ -2481,43 +2481,43 @@ This module will import all necessities.

{ pkgs, user, ... } :
   {
-    imports = [
-      ./apps/ollama.nix
-      #./apps/default-apps.nix
-      ./apps/theme.nix
-      ./desktop/hypridle.nix
-      ./desktop/hyprland.nix
-      ./desktop/hyprexpo.nix
-      ./desktop/hyprlock.nix
-      ./desktop/hyprscrolling.nix
-      ./desktop/hyprshell.nix
-      ./desktop/ncsway.nix
-      ./desktop/powermenu.nix
-      #./desktop/animated_wallpaper.nix
-      #./desktop/rotating_wallpaper.nix
-      ./desktop/workspace_wallpaper.nix
-      ./desktop/waybar.nix
-      ./desktop/walker.nix
-      ./dev/dev.nix
-      ./dev/kitty.nix
-      ./dev/shells.nix
-      ./dev/starship.nix
-      ./dev/zsh.nix
-      ./dev/emacs
-    ];
+  imports = [
+  ./apps/ollama.nix
+  #./apps/default-apps.nix
+  ./apps/theme.nix
+  ./desktop/hypridle.nix
+  ./desktop/hyprland.nix
+  ./desktop/hyprexpo.nix
+  ./desktop/hyprlock.nix
+  ./desktop/hyprscrolling.nix
+  ./desktop/hyprshell.nix
+  ./desktop/ncsway.nix
+  ./desktop/powermenu.nix
+  #./desktop/animated_wallpaper.nix
+  #./desktop/rotating_wallpaper.nix
+  ./desktop/workspace_wallpaper.nix
+  ./desktop/waybar.nix
+  ./desktop/walker.nix
+  ./dev/dev.nix
+  ./dev/kitty.nix
+  ./dev/shells.nix
+  ./dev/starship.nix
+  ./dev/zsh.nix
+  ./dev/emacs
+  ];
 
-    <<home-user>>
+  <<home-user>>
 
-    <<home-packages>>
+  <<home-packages>>
 
-    programs.home-manager.enable =  true;
+  programs.home-manager.enable =  true;
   }
 
-
-

19.2. Ollama

+
+

19.2. Ollama

This Home Manager Nix module (ai.nix) installs the Ollama package and configures it by reading a simple key-value configuration file (ollama.conf) for settings like the server host and default model. It sets environment variables (OLLAMAHOST and OLAMADEFAULTMODEL) for easy access in your shell or applications, with fallback defaults if the config file is missing or empty. Optionally, it also defines a user-level systemd service to automatically start the Ollama server on NixOS or systems with Home Manager’s systemd support enabled. @@ -2533,9 +2533,9 @@ in { services.ollama = { - enable = true; - package = pkgs.ollama; - environmentVariables = envVars; + enable = true; + package = pkgs.ollama; + environmentVariables = envVars; }; } @@ -2544,8 +2544,8 @@ in

-
-

19.3. Powermenu

+
+

19.3. Powermenu

Creates a script for a powermenu @@ -2554,22 +2554,23 @@ Creates a script for a powermenu

{ config, lib, pkgs, flakeRoot, ... }:
 let
   repoScript =
-    flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh";
+  flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh";
   targetRel = "hypr/scripts/powermenu.sh";
 in
 {
   # Ensure script exists in ~/.config/hypr/scripts/
   xdg.configFile."${targetRel}" = {
-    source = repoScript;
-    executable = true;
+  source = lib.mkForce repoScript;
+  backup = lib.mkForce false;
+  executable = true;
   };
 }
 
-
-

19.4. Animated Wallpaper

+
+

19.4. Animated Wallpaper

userRelRoot = "nixosconf/wallpaperstuff"; @@ -2585,53 +2586,53 @@ let userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4"; # (keep your existing approach: sync the repo wallpaper dir to the user dir) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: true; + src = repoWallpaperDir; + filter = path: type: true; }; in { home.packages = [ - pkgs.mpvpaper - pkgs.mpv + pkgs.mpvpaper + pkgs.mpv ]; # Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; systemd.user.services.mpvpaper-wallpaper = { - Unit = { - Description = "Video wallpaper (mpvpaper)"; - After = [ "graphical-session.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - Service = { - Type = "simple"; - # -p auto-pause saves resources when the wallpaper surface is hidden. - # '*' applies to all outputs. - # Stretch-to-fill (cover) behavior: - # --panscan=1.0 fills the entire output by cropping (no letterboxing). - # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. - ExecStart = '' - ${pkgs.mpvpaper}/bin/mpvpaper \ - -p \ - -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ - '*' "${userVideoPath}" - ''; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Video wallpaper (mpvpaper)"; + After = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "simple"; + # -p auto-pause saves resources when the wallpaper surface is hidden. + # '*' applies to all outputs. + # Stretch-to-fill (cover) behavior: + # --panscan=1.0 fills the entire output by cropping (no letterboxing). + # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. + ExecStart = '' + ${pkgs.mpvpaper}/bin/mpvpaper \ + -p \ + -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ + '*' "${userVideoPath}" + ''; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; }

-
-

19.5. Rotating Wallpaper

+
+

19.5. Rotating Wallpaper

rotatingwallpaper.nix installs wpaperd and deploys your wallpaper files from the repo (./assets/conf/desktop/wallpaper/pictures/) into ~/conf/desktop/wallpaper/pictures. It also deploys the default wallpaper configuration from assets/conf/desktop/wallpaper/wallpaper.conf into ~/conf/desktop/wallpaper/wallpaper.conf, which is the file you can edit as a user override. @@ -2648,45 +2649,45 @@ let userConfPath = "${userAbsRoot}/wallpaper.conf"; # Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: - (builtins.baseNameOf path) != "wallpaper.conf"; + src = repoWallpaperDir; + filter = path: type: + (builtins.baseNameOf path) != "wallpaper.conf"; }; in { home.packages = [ pkgs.wpaperd ]; # Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; # Now safely overwrite the config every activation (no HM collision) home.activation.wallpaperConfForce = - lib.hm.dag.entryAfter [ "writeBoundary" ] '' - set -euo pipefail - mkdir -p "${userAbsRoot}" - install -m 0644 "${repoWallpaperConf}" "${userConfPath}" - ''; + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + set -euo pipefail + mkdir -p "${userAbsRoot}" + install -m 0644 "${repoWallpaperConf}" "${userConfPath}" + ''; systemd.user.services.wpaperd = { - Unit = { - Description = "wpaperd wallpaper daemon"; - After = [ "default.target" ]; - }; - Service = { - Type = "simple"; - ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install.WantedBy = [ "default.target" ]; + Unit = { + Description = "wpaperd wallpaper daemon"; + After = [ "default.target" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install.WantedBy = [ "default.target" ]; ;

-
-

19.6. Workspace Wallpaper

+
+

19.6. Workspace Wallpaper

{ config, lib, pkgs, flakeRoot, ... }:
@@ -2698,209 +2699,212 @@ let
   # (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff
   repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper";
   repoWallpapersOnly = lib.cleanSourceWith {
-    src = repoWallpaperDir;
-    filter = path: type: true;
+  src = repoWallpaperDir;
+  filter = path: type: true;
   };
   daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh";
-  setRel    = "hypr/scripts/set-wallpaper.sh";
+  setRel  = "hypr/scripts/set-wallpaper.sh";
 in
 {
   home.packages = [
-    pkgs.hyprpaper
-    pkgs.socat
-    pkgs.jq
-    pkgs.findutils
-    pkgs.coreutils
-    pkgs.gnused
-    pkgs.gawk
+  pkgs.hyprpaper
+  pkgs.socat
+  pkgs.jq
+  pkgs.findutils
+  pkgs.coreutils
+  pkgs.gnused
+  pkgs.gawk
   ];
   # Keep your existing "sync wallpapers into a writable dir" pattern
   home.file."${userRelRoot}" = {
-    source = repoWallpapersOnly;
-    recursive = true;
+  source = repoWallpapersOnly;
+  recursive = true;
   };
   # Hyprpaper config (hyprpaper reads this; it does NOT need to write it)
   # `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0}
-  xdg.configFile."hypr/hyprpaper.conf".text = ''
-    ipc = true
-    splash = false
+  xdg.configFile."hypr/hyprpaper.conf".text = lib.mkForce ''
+  ipc = true
+  splash = false
   '';
+  xdg.configFile."hypr/hyprpaper.conf".backup = lib.mkForce false;
   # Workspace wallpaper daemon: listens to socket2, applies w-<id>=... mapping
   # Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1}
   xdg.configFile."${daemonRel}" = {
-    executable = true;
-    text = ''
-      #!/usr/bin/env bash
-      set -euo pipefail
-      : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}"
-      : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}"
-      SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
-      [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
-      PICTURES_DIR="''${1:-${picturesDir}}"
-      FIT_MODE="fill"   # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2}
-      HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
-      MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
-      focused_monitor() {
-        hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
-      }
-      map_file_for_monitor() {
-        local mon="''${1}"
-        echo "''${MAP_ROOT}/''${mon}/defaults.conf"
-      }
-      ensure_map_file() {
-        local mon="''${1}"
-        local f
-        f="$(map_file_for_monitor "''${mon}")"
-        mkdir -p "$(dirname "''${f}")"
-        if [[ ! -f "''${f}" ]]; then
-          # Seed with 1..9 from picturesDir if present, else empty entries
-          {
-            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)"
-              echo "w-''${i}= ''${seed}"
-            done
-          } > "''${f}"
-        fi
-        echo "''${f}"
-      }
-      get_wall_for_ws() {
-        local mon="''${1}"
-        local wsid="''${2}"
-        local f key val
-        f="$(ensure_map_file "''${mon}")"
-        key="w-''${wsid}"
-        # accept "w-1=/path" or "w-1= /path"
-        val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)"
-        echo "''${val}"
-      }
-      apply_wallpaper() {
-        local mon="''${1}"
-        local wsid="''${2}"
-        local file
-        file="$(get_wall_for_ws "''${mon}" "''${wsid}")"
-        [[ -n "''${file}" ]] || return 0
-        [[ -f "''${file}" ]] || return 0
-        # Apply via IPC
-        # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3}
-        hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null
-      }
-      # Initial apply on startup
-      mon="$(focused_monitor || true)"
-      wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
-      [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
-      handle() {
-        local line="''${1}"
-        case "''${line}" in
-          workspacev2* )
-            # workspacev2>>ID,NAME  :contentReference[oaicite:4]{index=4}
-            local payload wsid
-            payload="''${line#*>>}"
-            wsid="''${payload%%,*}"
-            mon="$(focused_monitor || true)"
-            [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
-            ;;
-          focusedmon* )
-            # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5}
-            # When monitor focus changes, re-apply for the active workspace id.
-            mon="$(focused_monitor || true)"
-            wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
-            [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
-            ;;
-        esac
-      }
-      socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do
-        handle "''${line}" || true
-      done
-    '';
+  executable = true;
+  text = lib.mkForce ''
+  #!/usr/bin/env bash
+  set -euo pipefail
+  : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}"
+  : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}"
+  SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
+  [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
+  PICTURES_DIR="''${1:-${picturesDir}}"
+  FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2}
+  HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
+  MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
+  focused_monitor() {
+    hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
+  }
+  map_file_for_monitor() {
+    local mon="''${1}"
+    echo "''${MAP_ROOT}/''${mon}/defaults.conf"
+  }
+  ensure_map_file() {
+    local mon="''${1}"
+    local f
+    f="$(map_file_for_monitor "''${mon}")"
+    mkdir -p "$(dirname "''${f}")"
+    if [[ ! -f "''${f}" ]]; then
+    # Seed with 1..9 from picturesDir if present, else empty entries
+    {
+    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)"
+      echo "w-''${i}= ''${seed}"
+    done
+    } > "''${f}"
+    fi
+    echo "''${f}"
+  }
+  get_wall_for_ws() {
+    local mon="''${1}"
+    local wsid="''${2}"
+    local f key val
+    f="$(ensure_map_file "''${mon}")"
+    key="w-''${wsid}"
+    # accept "w-1=/path" or "w-1= /path"
+    val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)"
+    echo "''${val}"
+  }
+  apply_wallpaper() {
+    local mon="''${1}"
+    local wsid="''${2}"
+    local file
+    file="$(get_wall_for_ws "''${mon}" "''${wsid}")"
+    [[ -n "''${file}" ]] || return 0
+    [[ -f "''${file}" ]] || return 0
+    # Apply via IPC
+    # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3}
+    hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null
+  }
+  # Initial apply on startup
+  mon="$(focused_monitor || true)"
+  wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
+  [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
+  handle() {
+    local line="''${1}"
+    case "''${line}" in
+    workspacev2* )
+    # workspacev2>>ID,NAME  :contentReference[oaicite:4]{index=4}
+    local payload wsid
+    payload="''${line#*>>}"
+    wsid="''${payload%%,*}"
+    mon="$(focused_monitor || true)"
+    [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
+    ;;
+    focusedmon* )
+    # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5}
+    # When monitor focus changes, re-apply for the active workspace id.
+    mon="$(focused_monitor || true)"
+    wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
+    [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
+    ;;
+    esac
+  }
+  socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do
+    handle "''${line}" || true
+  done
+  '';
+  backup = lib.mkForce false;
   };
 
   # CLI setter in the style of your inspiration script.
   # Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper]
   xdg.configFile."${setRel}" = {
-    executable = true;
-    text = ''
-      #!/usr/bin/env bash
-      set -euo pipefail
+  executable = true;
+  text = lib.mkForce ''
+  #!/usr/bin/env bash
+  set -euo pipefail
 
-      HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
-      MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
+  HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
+  MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
 
-      usage() {
-        echo "Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper_path]"
-      }
+  usage() {
+    echo "Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper_path]"
+  }
 
-      wsid="''${1:-}"
-      mon="''${2:-}"
-      wp="''${3:-}"
+  wsid="''${1:-}"
+  mon="''${2:-}"
+  wp="''${3:-}"
 
-      [[ -n "''${wsid}" ]] || { usage; exit 1; }
-      [[ -n "''${mon}"  ]] || { usage; exit 1; }
+  [[ -n "''${wsid}" ]] || { usage; exit 1; }
+  [[ -n "''${mon}"  ]] || { usage; exit 1; }
 
-      cfg="''${MAP_ROOT}/''${mon}/defaults.conf"
-      mkdir -p "$(dirname "''${cfg}")"
-      [[ -f "''${cfg}" ]] || touch "''${cfg}"
+  cfg="''${MAP_ROOT}/''${mon}/defaults.conf"
+  mkdir -p "$(dirname "''${cfg}")"
+  [[ -f "''${cfg}" ]] || touch "''${cfg}"
 
-      if [[ -z "''${wp}" ]]; then
-        # 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)"
-        [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
-      fi
+  if [[ -z "''${wp}" ]]; then
+    # 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)"
+    [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
+  fi
 
-      # Ensure key exists; if not, append it
-      key="w-''${wsid}"
-      if ! grep -q "^''${key}=" "''${cfg}"; then
-        echo "''${key}=" >> "''${cfg}"
-      fi
+  # Ensure key exists; if not, append it
+  key="w-''${wsid}"
+  if ! grep -q "^''${key}=" "''${cfg}"; then
+    echo "''${key}=" >> "''${cfg}"
+  fi
 
-      # Set mapping
-      ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}"
+  # Set mapping
+  ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}"
 
-      # 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)"
-      if [[ "''${curws}" == "''${wsid}" ]]; then
-        hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null
-      fi
-    '';
+  # 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)"
+  if [[ "''${curws}" == "''${wsid}" ]]; then
+    hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null
+  fi
+  '';
+  backup = lib.mkForce false;
   };
 
   # Services
   systemd.user.services.hyprpaper = {
-    Unit = {
-      Description = "hyprpaper wallpaper daemon";
-      PartOf = [ "graphical-session.target" ];
-      After  = [ "graphical-session.target" ];
-    };
-    Service = {
-      ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper";
-      Restart = "on-failure";
-      RestartSec = 1;
-    };
-    Install = { WantedBy = [ "graphical-session.target" ]; };
+  Unit = {
+  Description = "hyprpaper wallpaper daemon";
+  PartOf = [ "graphical-session.target" ];
+  After  = [ "graphical-session.target" ];
+  };
+  Service = {
+  ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper";
+  Restart = "on-failure";
+  RestartSec = 1;
+  };
+  Install = { WantedBy = [ "graphical-session.target" ]; };
   };
 
   systemd.user.services.hyprpaper-ws-daemon = {
-    Unit = {
-      Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
-      PartOf = [ "graphical-session.target" ];
-      After  = [ "graphical-session.target" "hyprpaper.service" ];
-    };
-    Service = {
-      ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}";
-      Restart = "on-failure";
-      RestartSec = 1;
-    };
-    Install = { WantedBy = [ "graphical-session.target" ]; };
+  Unit = {
+  Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
+  PartOf = [ "graphical-session.target" ];
+  After  = [ "graphical-session.target" "hyprpaper.service" ];
+  };
+  Service = {
+  ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}";
+  Restart = "on-failure";
+  RestartSec = 1;
+  };
+  Install = { WantedBy = [ "graphical-session.target" ]; };
   };
 }
 
-
-

19.7. Waybar

+
+

19.7. Waybar

-
+

waybar.png

@@ -2917,14 +2921,16 @@ in programs.waybar.enable = true; # Ensure config matches repo (HM-managed symlink, not user-editable) xdg.configFile."waybar/config" = { - source = repoWaybarDir + "/config.jsonc"; - force = true; + source = lib.mkForce repoWaybarDir + "/config.jsonc"; + backup = lib.mkForce false; + force = true; }; # Override HM's internally-generated waybar-style.css derivation # and use your repo file instead. xdg.configFile."waybar/style.css" = { - source = lib.mkForce (repoWaybarDir + "/style.css"); - force = true; + source = lib.mkForce (repoWaybarDir + "/style.css"); + backup = lib.mkForce false; + force = true; }; # 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) @@ -2934,8 +2940,8 @@ in
-
-

19.8. Lock Screen

+
+

19.8. Lock Screen

The lock screen configured using hyprlock. @@ -2945,20 +2951,22 @@ They are configured below.

{config, lib, pkgs, flakeRoot, ... }:
 let
-  lockPngSrc   = flakeRoot + "/assets/lock.png";
+  lockPngSrc = flakeRoot + "/assets/lock.png";
   hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf";
 in
 {
   home.packages = [ pkgs.hyprlock ];
-  xdg.configFile."hypr/lock.png".source = lockPngSrc;
-  xdg.configFile."hypr/hyprlock.conf".source = hyprlockConf;
+  xdg.configFile."hypr/lock.png".source = lib.mkForce lockPngSrc;
+  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;
 }
 
-
-

19.9. Idle Screen

+
+

19.9. Idle Screen

<henro: needs instruction> @@ -2970,14 +2978,15 @@ let in { 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 ; }

-
-

19.10. hyprscrolling

+
+

19.10. hyprscrolling

This Nix module integrates the hyprscrolling plugin into a Home-Manager managed Hyprland setup in a declarative and reproducible way. It ensures the plugin is installed, optionally switches Hyprland to the scrolling layout, and renders user-defined plugin settings directly into the Hyprland configuration. The goal is to manage the scrolling workspace behavior entirely from Nix instead of maintaining manual edits inside hyprland.conf. @@ -2996,46 +3005,49 @@ let targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh"; # Facilitate switching between scrolling and dwindle 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"; in { # Ensure deps for the script exist at runtime # (hyprctl comes with Hyprland; jq is often not installed by default) home.packages = with pkgs; [ - jq + jq ]; wayland.windowManager.hyprland = { - enable = true; - plugins = [ - pkgs.hyprlandPlugins.hyprscrolling - ]; - extraConfig = '' - source = ~/.config/${targetRel} - ''; + enable = true; + plugins = [ + pkgs.hyprlandPlugins.hyprscrolling + ]; + extraConfig = '' + source = ~/.config/${targetRel} + ''; }; # 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}" = { - source = repoOverflowScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoOverflowScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetPerMonitor}" = { - source = repoPerMonitorScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoPerMonitorScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetSwitchScript}" = { - source = repoSwitchScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoSwitchScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; }

-
-

19.11. Hyprshell

+
+

19.11. Hyprshell

For nice task-starting and -switching @@ -3052,31 +3064,33 @@ in xdg.enable = true; home.packages = [ pkgs.hyprshell ]; # Link repo -> ~/.config/hyprshell/... - xdg.configFile."hyprshell/config.ron".source = cfgRon; - xdg.configFile."hyprshell/styles.css".source = cssFile; + xdg.configFile."hyprshell/config.ron".source = lib.mkForce cfgRon; + 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) systemd.user.services.hyprshell = { - Unit = { - Description = "Hyprshell (window switcher / launcher)"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Hyprshell (window switcher / launcher)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; }

-
-

19.12. Hyprland

+
+

19.12. Hyprland

This configures the desktop environment along with the peripherals. The comments should explain whats happening. @@ -3084,50 +3098,51 @@ This configures the desktop environment along with the peripherals. The comments

{ config, lib, pkgs, flakeRoot, ... }:
 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";
 in
 {
   wayland.windowManager.hyprland = {
-    enable = true;
-    # Load base config + bindings from repo files
-    extraConfig =
-      (builtins.readFile hyprConf)
-      + "\n\n# --- Repo keybindings ---\n"
-      + (builtins.readFile bindingsConf)
-      + "\n";
-      settings = {
-        windowrule = [
-          "match:class nm-connection-editor, float 1, center 1, size 900 700"
-        ];
-      };
+  enable = true;
+  # Load base config + bindings from repo files
+  extraConfig =
+  (builtins.readFile hyprConf)
+  + "\n\n# --- Repo keybindings ---\n"
+  + (builtins.readFile bindingsConf)
+  + "\n";
+  settings = {
+    windowrule = [
+    "match:class nm-connection-editor, float 1, center 1, size 900 700"
+    ];
+  };
 
   };
   xdg.configFile."hypr/scripts/lid-lock.sh" = {
-    source = flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh";
-    executable = true;
+  source = lib.mkForce flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh";
+  backup = lib.mkForce false;
+  executable = true;
   };
   xdg.portal = {
-    enable = true;
-    extraPortals = with pkgs; [
-      xdg-desktop-portal-gtk
-      xdg-desktop-portal-hyprland
-    ];
-    # GTK als algemene backend (OpenURI is daar betrouwbaar)
-    config.common.default = [ "gtk" ];
-    # Hyprland alleen voor screensharing / remote desktop
-    config.hyprland = {
-      "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
-      "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ];
-    };
+  enable = true;
+  extraPortals = with pkgs; [
+  xdg-desktop-portal-gtk
+  xdg-desktop-portal-hyprland
+  ];
+  # GTK als algemene backend (OpenURI is daar betrouwbaar)
+  config.common.default = [ "gtk" ];
+  # Hyprland alleen voor screensharing / remote desktop
+  config.hyprland = {
+  "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
+  "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ];
+  };
   };
 }
 
-
-

19.13. Walker

+
+

19.13. Walker

This is how I launch applications. It is bound to Win+Space in the ./asstes/conf/desktop/hypr/bindings.conf. @@ -3136,13 +3151,13 @@ in

{ config, pkgs, lib, flakeRoot, inputs ? null, ... }:
 let
   walkerPkg =
-    if inputs != null && inputs ? walker
-    then inputs.walker.packages.${pkgs.system}.default
-    else pkgs.walker;
+  if inputs != null && inputs ? walker
+  then inputs.walker.packages.${pkgs.system}.default
+  else pkgs.walker;
   elephantPkg =
-    if inputs != null && inputs ? elephant
-    then inputs.elephant.packages.${pkgs.system}.default
-    else pkgs.elephant;
+  if inputs != null && inputs ? elephant
+  then inputs.elephant.packages.${pkgs.system}.default
+  else pkgs.elephant;
   sessionTarget = "graphical-session.target";
   # All theme files now live here
   repoThemesDir = flakeRoot + "/assets/conf/desktop/walker";
@@ -3151,20 +3166,24 @@ in
   xdg.enable = true;
   home.packages = [ walkerPkg elephantPkg ];
   # ~/.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".backup = lib.mkForce false;
   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)
   systemd.user.services.elephant = { /* ... your existing service ... */ };
-  systemd.user.services.walker   = { /* ... your existing service ... */ };
+  systemd.user.services.walker = { /* ... your existing service ... */ };
 }
 
-
-

19.14. Theme

+
+

19.14. Theme

I use the Catppuccin almost everywhere. The nix module integrates almost automatically everywhere (except gtk). @@ -3173,32 +3192,32 @@ You'll notice the color values in multiple places outside this as well.

{ pkgs, ...}:
 {
-  gtk = {
-    enable = true;
-    colorScheme = "dark";
-    theme = {
-      name = "Catppuccin-GTK-Grey-Dark-Compact";
-      package = (pkgs.magnetic-catppuccin-gtk.override {
-        accent = [ "grey" ];
-        shade = "dark";
-        tweaks = [ "black" ];
-        size = "compact";
-      });
-    };
-    iconTheme.name = "Papirus-Dark";
-  };
-  catppuccin.enable = true;
-  catppuccin.flavor = "mocha";
-  catppuccin.accent = "blue";
-  catppuccin.gtk.icon.enable = true;
-  catppuccin.cursors.enable = true;
+gtk = {
+enable = true;
+colorScheme = "dark";
+theme = {
+  name = "Catppuccin-GTK-Grey-Dark-Compact";
+  package = (pkgs.magnetic-catppuccin-gtk.override {
+  accent = [ "grey" ];
+  shade = "dark";
+  tweaks = [ "black" ];
+  size = "compact";
+  });
+};
+iconTheme.name = "Papirus-Dark";
+};
+catppuccin.enable = true;
+catppuccin.flavor = "mocha";
+catppuccin.accent = "blue";
+catppuccin.gtk.icon.enable = true;
+catppuccin.cursors.enable = true;
 }
 
-
-

19.15. Default-apps

+
+

19.15. Default-apps

This is where you can set defaults @@ -3208,17 +3227,17 @@ This is where you can set defaults { xdg.mimeApps.enable = true; xdg.mimeApps.defaultApplications = { - "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; - "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; - "text/html" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; + "text/html" = [ "app.zen_browser.zen.desktop" ]; }; }

-
-

19.16. Hyperexpo

+
+

19.16. Hyperexpo

hyprexpo gets installed and configured @@ -3227,29 +3246,29 @@ hyprexpo gets installed and configured

{ config, lib, pkgs, ... }:
 {
   wayland.windowManager.hyprland = {
-    # Load the Hyprexpo plugin (from nixpkgs)
-    plugins = [
-      pkgs.hyprlandPlugins.hyprexpo
-    ];
+  # Load the Hyprexpo plugin (from nixpkgs)
+  plugins = [
+  pkgs.hyprlandPlugins.hyprexpo
+  ];
 
-    # Append plugin config + keybind after your existing hyprland.conf
-    extraConfig = lib.mkAfter ''
-      ############################
-      # Hyprexpo (workspace/window overview)
-      ############################
+  # Append plugin config + keybind after your existing hyprland.conf
+  extraConfig = lib.mkAfter ''
+  ############################
+  # Hyprexpo (workspace/window overview)
+  ############################
 
-      # Basic plugin config (tweak as you like)
-      plugin {
-        hyprexpo {
-          columns = 3
-          gaps_in = 5
-          gaps_out = 20
+  # Basic plugin config (tweak as you like)
+  plugin {
+    hyprexpo {
+    columns = 3
+    gaps_in = 5
+    gaps_out = 20
 
-          # Optional; comment out if you don't want it
-          # workspace_method = center current
-        }
-      }
-    '';
+    # Optional; comment out if you don't want it
+    # workspace_method = center current
+    }
+  }
+  '';
   };
 }
 
@@ -3257,8 +3276,8 @@ hyprexpo gets installed and configured
 
-
-

19.17. Alacritty

+
+

19.17. Alacritty

Alacritty gets installed and configured @@ -3273,6 +3292,7 @@ in programs.alacritty.enable = true; # Override the config generated by programs.alacritty xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf; + xdg.configFile."alacritty/alacritty.toml".backup = lib.mkForce false catppuccin.alacritty.enable = true; catppuccin.alacritty.flavor = "mocha"; } @@ -3280,8 +3300,8 @@ in

-
-

19.18. Dev Tools

+
+

19.18. Dev Tools

All the miscellaneous dev tools on this computer. @@ -3290,51 +3310,51 @@ All the miscellaneous dev tools on this computer.

{ config, pkgs, lib, ... }:
 {
   programs = {
-    vscode.enable = true;
-    vim.enable = true;
-    ripgrep.enable = true;
-    btop.enable = true;
-    fzf = {
-      enable = true;
-      enableZshIntegration = true;
-      enableBashIntegration = true;
-    };
-    zoxide = {
-      enable = true;
-      enableZshIntegration = true;
-      enableBashIntegration = true;
-    };
-    eza = {
-      enable = true;
-      enableZshIntegration = true;
-      enableBashIntegration = true;
-    };
-    direnv = {
-      enable = true;
-      enableZshIntegration = true;
-      enableBashIntegration = true;
-      nix-direnv.enable = true;
-    };
-    # Zsh-specific config belongs here
-    zsh = {
+  vscode.enable = true;
+  vim.enable = true;
+  ripgrep.enable = true;
+  btop.enable = true;
+  fzf = {
+  enable = true;
+  enableZshIntegration = true;
+  enableBashIntegration = true;
+  };
+  zoxide = {
+  enable = true;
+  enableZshIntegration = true;
+  enableBashIntegration = true;
+  };
+  eza = {
+  enable = true;
+  enableZshIntegration = true;
+  enableBashIntegration = true;
+  };
+  direnv = {
+  enable = true;
+  enableZshIntegration = true;
+  enableBashIntegration = true;
+  nix-direnv.enable = true;
+  };
+  # Zsh-specific config belongs here
+  zsh = {
  # for emacs-eat package
-      initContent = lib.mkOrder 1200 ''
-        [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \
-          source "$EAT_SHELL_INTEGRATION_DIR/zsh"
-      '';
-    };
-    git = {
-      enable = true;
-      lfs.enable = true;
-    };
+  initContent = lib.mkOrder 1200 ''
+    [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \
+    source "$EAT_SHELL_INTEGRATION_DIR/zsh"
+  '';
+  };
+  git = {
+  enable = true;
+  lfs.enable = true;
+  };
   };
 }
 
-
-

19.19. Kitty

+
+

19.19. Kitty

Kitty gets installed and configured @@ -3343,38 +3363,39 @@ Kitty gets installed and configured

{ config, pkgs, lib, flakeRoot, ... }:
 let
   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)
   repoKittyConfText =
-    builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf");
+  builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf");
 in
 {
   xdg.enable = true;
   # 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 = {
-    enable = true;
-    # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order:
-    # 1) include theme
-    # 2) your repo config (keymaps etc.)
-    # 3) force opacity LAST so it always wins
-    extraConfig = ''
-      # 1) Theme first (stable path)
-      include themes/Catppuccin-Mocha.conf
-      # 2) Your repo config (may also include theme; harmless if duplicated)
-      ${repoKittyConfText}
-      # 3) Force transparency last (wins)
-      #background_opacity 0.60
-      #dynamic_background_opacity yes
-    '';
+  enable = true;
+  # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order:
+  # 1) include theme
+  # 2) your repo config (keymaps etc.)
+  # 3) force opacity LAST so it always wins
+  extraConfig = ''
+  # 1) Theme first (stable path)
+  include themes/Catppuccin-Mocha.conf
+  # 2) Your repo config (may also include theme; harmless if duplicated)
+  ${repoKittyConfText}
+  # 3) Force transparency last (wins)
+  #background_opacity 0.60
+  #dynamic_background_opacity yes
+  '';
   };
 }
 
-
-

19.20. Shells

+
+

19.20. Shells

The aliases mentioned in ./assets/conf/dev/terminal/shells.conf will be added to enabled shells @@ -3383,8 +3404,8 @@ The aliases mentioned in ./assets/conf/dev/terminal/shells.conf will be added to

# shells.nix — Home-Manager module
 #
 # Reads:
-#   ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf
-#   ${flakeRoot}/assets/conf/dev/terminal/aliases.conf
+# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf
+# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf
 #
 # For each enabled shell in [enabled_shells]:
 # - installs/enables shell (where HM has an enable option)
@@ -3405,53 +3426,53 @@ let
   readMaybe = p: if builtins.pathExists p then builtins.readFile p else "";
   normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l);
   parseSections = text:
-    let
-      lines = map normalizeLine (lib.splitString "\n" text);
-        isHeader = l:
-        let s = l;
-        in lib.hasPrefix "[" s
-          && lib.hasSuffix "]" s
-          && builtins.stringLength s >= 3;
-      nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l);
-      folded =
-        builtins.foldl'
-          (st: l:
-            if l == "" then st else
-            if isHeader l then st // { current = nameOf l; }
-            else
-              let
-                cur = st.current;
-                prev = st.sections.${cur} or [];
-              in
-                st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; }
-          )
-          { current = "__root__"; sections = {}; }
-          lines;
-    in
-      folded.sections;
+  let
+  lines = map normalizeLine (lib.splitString "\n" text);
+    isHeader = l:
+    let s = l;
+    in lib.hasPrefix "[" s
+    && lib.hasSuffix "]" s
+    && builtins.stringLength s >= 3;
+  nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l);
+  folded =
+    builtins.foldl'
+    (st: l:
+    if l == "" then st else
+    if isHeader l then st // { current = nameOf l; }
+    else
+      let
+      cur = st.current;
+      prev = st.sections.${cur} or [];
+      in
+      st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; }
+    )
+    { current = "__root__"; sections = {}; }
+    lines;
+  in
+  folded.sections;
   enabledSections = parseSections (readMaybe enabledFile);
-  aliasSections   = parseSections (readMaybe aliasesFile);
+  aliasSections = parseSections (readMaybe aliasesFile);
   # [enabled_shells] lines: key = yes/no
   enabledShells =
-    let
-      raw = enabledSections.enabled_shells or [];
-      parseKV = l:
-        let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l;
-        in if m == null then null else {
-          k = trim (builtins.elemAt m 0);
-          v = lib.toLower (trim (builtins.elemAt m 1));
-        };
-      kvs = builtins.filter (x: x != null) (map parseKV raw);
-    in
-      map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs);
+  let
+  raw = enabledSections.enabled_shells or [];
+  parseKV = l:
+    let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l;
+    in if m == null then null else {
+    k = trim (builtins.elemAt m 0);
+    v = lib.toLower (trim (builtins.elemAt m 1));
+    };
+  kvs = builtins.filter (x: x != null) (map parseKV raw);
+  in
+  map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs);
   shellEnabled = shell: builtins.elem shell enabledShells;
   # ---------- per-shell repo config file (<shell>.conf) ----------
   shellConfPath = shell: terminalDir + "/${shell}.conf";
   shellConfExists = shell: builtins.pathExists (shellConfPath shell);
   sourceIfExistsSh = p: ''
-    if [ -f "${toString p}" ]; then
-      source "${toString p}"
-    fi
+  if [ -f "${toString p}" ]; then
+  source "${toString p}"
+  fi
   '';
  # ---------- aliases section helpers ----------
   secLines = name: aliasSections.${name} or [];
@@ -3462,55 +3483,55 @@ let
   fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish";
   # Seeds (created once; user can edit afterwards)
   bashSeed = ''
-    # Created once from: ${toString aliasesFile}
-    # Edit freely; Home Manager will not overwrite this file.
-    #
-    ${secText "bash_zsh"}
-    ${secText "bash_specific"}
-    '';
+  # Created once from: ${toString aliasesFile}
+  # Edit freely; Home Manager will not overwrite this file.
+  #
+  ${secText "bash_zsh"}
+  ${secText "bash_specific"}
+  '';
   zshSeed = ''
-    # Created once from: ${toString aliasesFile}
-    # Edit freely; Home Manager will not overwrite this file.
-    ${secText "bash_zsh"}
-    ${secText "zsh_specific"}
-    '';
+  # Created once from: ${toString aliasesFile}
+  # Edit freely; Home Manager will not overwrite this file.
+  ${secText "bash_zsh"}
+  ${secText "zsh_specific"}
+  '';
   # Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is
   parsePosixAlias = l:
+  let
+  m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l;
+  in
+  if m == null then null else
     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
-      if m == null then null else
-        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; };
+    { inherit name; cmd = unquote; };
   escapeForFish = s:
-    lib.replaceStrings
-      [ "\\"  "\""  "$"   "`" ]
-      [ "\\\\" "\\\"" "\\$" "\\`" ]
-      s;
+  lib.replaceStrings
+  [ "\\"  "\""  "$" "`" ]
+  [ "\\\\" "\\\"" "\\$" "\\`" ]
+  s;
   fishTranslated =
-    let
-      parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh"));
-    in
-      lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed);
+  let
+  parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh"));
+  in
+  lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed);
   fishSeed = ''
-    # Created once from: ${toString aliasesFile}
-    # Edit freely; Home Manager will not overwrite this file.
-    status is-interactive; or exit
-    # Translated from [bash_zsh]:
-    ${fishTranslated}
-    # From [fish_specific]:
-    ${secText "fish_specific"}
-      '';
+  # Created once from: ${toString aliasesFile}
+  # Edit freely; Home Manager will not overwrite this file.
+  status is-interactive; or exit
+  # Translated from [bash_zsh]:
+  ${fishTranslated}
+  # From [fish_specific]:
+  ${secText "fish_specific"}
+  '';
 in
 {
   xdg.enable = true;
@@ -3519,79 +3540,79 @@ in
   programs.zsh.enable  = shellEnabled "zsh";
   programs.fish.enable = shellEnabled "fish";
   home.packages =
-    (lib.optionals (shellEnabled "dash")    [ pkgs.dash ]) ++
-    (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]);
+  (lib.optionals (shellEnabled "dash")  [ pkgs.dash ]) ++
+  (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]);
   # Source per-shell repo config (if present) AND source the user alias file (if it exists).
   # Important: define each option only ONCE.
   programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter ''
-    ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))}
-    if [ -f "${bashAliasesPath}" ]; then
-      source "${bashAliasesPath}"
-    fi
+  ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))}
+  if [ -f "${bashAliasesPath}" ]; then
+  source "${bashAliasesPath}"
+  fi
   '');
   programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter ''
-    ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))}
-    if [ -f "${zshAliasesPath}" ]; then
-      source "${zshAliasesPath}"
-    fi
+  ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))}
+  if [ -f "${zshAliasesPath}" ]; then
+  source "${zshAliasesPath}"
+  fi
   '');
   programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter ''
-    ${lib.optionalString (shellConfExists "fish") ''
-      if test -f "${toString (shellConfPath "fish")}"
-        source "${toString (shellConfPath "fish")}"
-      end
-    ''}
-    if test -f "${fishAliasesPath}"
-      source "${fishAliasesPath}"
-    end
+  ${lib.optionalString (shellConfExists "fish") ''
+  if test -f "${toString (shellConfPath "fish")}"
+    source "${toString (shellConfPath "fish")}"
+  end
+  ''}
+  if test -f "${fishAliasesPath}"
+  source "${fishAliasesPath}"
+  end
   '');
 # Create/remove alias files based on enabled shells
 home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
   set -euo pipefail
   # bash -------------------------------------------------------
   if ${if shellEnabled "bash" then "true" else "false"}; then
-    cat > "${bashAliasesPath}" <<'EOF'
+  cat > "${bashAliasesPath}" <<'EOF'
 ${bashSeed}
 EOF
   else
-    rm -f "${bashAliasesPath}"
+  rm -f "${bashAliasesPath}"
   fi
   # zsh -------------------------------------------------------
  if ${if shellEnabled "zsh" then "true" else "false"}; then
-    cat > "${zshAliasesPath}" <<'EOF'
+  cat > "${zshAliasesPath}" <<'EOF'
 ${zshSeed}
 EOF
   else
-    rm -f "${zshAliasesPath}"
+  rm -f "${zshAliasesPath}"
   fi
   # fish -------------------------------------------------------
   if ${if shellEnabled "fish" then "true" else "false"}; then
-    mkdir -p "$(dirname "${fishAliasesPath}")"
-    cat > "${fishAliasesPath}" <<'EOF'
+  mkdir -p "$(dirname "${fishAliasesPath}")"
+  cat > "${fishAliasesPath}" <<'EOF'
 ${fishSeed}
 EOF
   else
-    rm -f "${fishAliasesPath}"
+  rm -f "${fishAliasesPath}"
   fi
-    # fish
-    if ${if shellEnabled "fish" then "true" else "false"}; then
-      mkdir -p "$(dirname "${fishAliasesPath}")"
-      if [ ! -f "${fishAliasesPath}" ]; then
-        cat > "${fishAliasesPath}" <<'EOF'
+  # fish
+  if ${if shellEnabled "fish" then "true" else "false"}; then
+  mkdir -p "$(dirname "${fishAliasesPath}")"
+  if [ ! -f "${fishAliasesPath}" ]; then
+    cat > "${fishAliasesPath}" <<'EOF'
 ${fishSeed}
 EOF
-      fi
-    else
-      rm -f "${fishAliasesPath}"
-    fi
+  fi
+  else
+  rm -f "${fishAliasesPath}"
+  fi
   '';
 }
 
-
-

19.21. Zsh

+
+

19.21. Zsh

Zsh gets installed and configured @@ -3600,35 +3621,35 @@ Zsh gets installed and configured

{  config,  pkgs,  lib, flakeRoot,  ... }:
 {
   programs.zsh = {
-    enable = true;
-    enableCompletion = true;
-    autocd = true;
-    # Optional but recommended: keep zsh config in one dir (relative to $HOME)
-    dotDir = ".config/zsh";
-    oh-my-zsh = {
-      enable = true;
-      theme = "";
-      plugins = [
-        "git"
-        "sudo"
-        "extract"
-        "colored-man-pages"
-        "command-not-found"
-        "history"
-        "docker"
-        "kubectl"
-      ];
-    };
-    autosuggestion.enable = true;
-    syntaxHighlighting.enable = true;
+  enable = true;
+  enableCompletion = true;
+  autocd = true;
+  # Optional but recommended: keep zsh config in one dir (relative to $HOME)
+  dotDir = ".config/zsh";
+  oh-my-zsh = {
+  enable = true;
+  theme = "";
+  plugins = [
+    "git"
+    "sudo"
+    "extract"
+    "colored-man-pages"
+    "command-not-found"
+    "history"
+    "docker"
+    "kubectl"
+  ];
+  };
+  autosuggestion.enable = true;
+  syntaxHighlighting.enable = true;
   };
 }
 
-
-

19.22. Starship

+
+

19.22. Starship

The configuration mentioned in ./assets/conf/dev/terminal/starship.toml will be added to enabled shells @@ -3646,10 +3667,10 @@ in xdg.enable = true; programs.starship = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - enableFishIntegration = true; + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + enableFishIntegration = true; }; # Force the *actual conflicting option* (home.file."<abs path>".source) @@ -3660,18 +3681,18 @@ in

-
-

19.23. Other Settings

+
+

19.23. Other Settings

Some repeated info from the configuration.

-
-

19.23.1. Home User

+
+

19.23.1. Home User

-
home.username = "${user.username}";
+
home.username = "${user.username}";
 home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}";
 home.stateVersion = user.stateVersion;
 
@@ -3680,8 +3701,8 @@ home.stateVersion = user.stateVersion;
-
-

20. Emacs

+
+

20. Emacs

I practically live inside emacs. The configuration for it is a mix between init.el and the nix configuration. @@ -3692,76 +3713,76 @@ Comments describe the emacs package and what it does.

{ pkgs, ... }:
 {
-  programs.emacs = {
-    enable = true;
-    # install with tree sitter enabled
-    package = (pkgs.emacs-pgtk.override { withTreeSitter = true; });
-    extraPackages = epkgs: [
-      # also install all tree sitter grammars
-      epkgs.manualPackages.treesit-grammars.with-all-grammars
-      epkgs.nerd-icons               # nerd fonts support
-      epkgs.doom-modeline            # model line
-      epkgs.diminish                 # hides modes from modeline
-      epkgs.eldoc                    # doc support
-      epkgs.pulsar                   # pulses the cursor when jumping about
-      epkgs.which-key                # help porcelain
-      epkgs.expreg                   # expand region
-      epkgs.vundo                    # undo tree
-      epkgs.puni                     # structured editing
-      epkgs.avy                      # jumping utility
-      epkgs.consult                  # emacs right click
-      epkgs.vertico                  # minibuffer completion
-      epkgs.marginalia               # annotations for completions
-      epkgs.crux                     # utilities
-      epkgs.magit                    # git porcelain
-      epkgs.nerd-icons-corfu         # nerd icons for completion
-      epkgs.corfu                    # completion
-      epkgs.cape                     # completion extensions
-      epkgs.orderless                # search paradigm
-      epkgs.yasnippet                # snippets support
-      epkgs.yasnippet-snippets       # commonly used snippets
-      epkgs.rg                       # ripgrep
-      epkgs.exec-path-from-shell     # load env and path
-      epkgs.eat                      # better shell
-      epkgs.rust-mode                # rust mode (when rust-ts doesn't cut it)
-      epkgs.rustic                   # more rust things
-      epkgs.nix-mode                 # nix lang
-      epkgs.hcl-mode                 # hashicorp file mode
-      epkgs.shell-pop                # quick shell popup
-      epkgs.envrc                    # support for loading .envrc
-      epkgs.nixpkgs-fmt              # format nix files
-      epkgs.f                        # string + file utilities
-      epkgs.gptel                    # llm chat (mainly claude)
-      epkgs.catppuccin-theme         # catppuccin theme
-      epkgs.eldoc-box                # docs in a box
-      epkgs.sideline                 # 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
-    ];
-  };
-  home.sessionVariables = {
-    EDITOR = "emacs";
-    XDG_SCREENSHOTS_DIR = "~/screenshots";
-  };
-  home.file = {
-    emacs-init = {
-      source = ./early-init.el;
-      target = ".emacs.d/early-init.el";
-    };
-    emacs = {
-      source = ./init.el;
-      target = ".emacs.d/init.el";
-    };
-  };
-  services.nextcloud-client = {
-  enable = true;
-  };
+programs.emacs = {
+enable = true;
+# install with tree sitter enabled
+package = (pkgs.emacs-pgtk.override { withTreeSitter = true; });
+extraPackages = epkgs: [
+  # also install all tree sitter grammars
+  epkgs.manualPackages.treesit-grammars.with-all-grammars
+  epkgs.nerd-icons     # nerd fonts support
+  epkgs.doom-modeline    # model line
+  epkgs.diminish       # hides modes from modeline
+  epkgs.eldoc        # doc support
+  epkgs.pulsar       # pulses the cursor when jumping about
+  epkgs.which-key      # help porcelain
+  epkgs.expreg       # expand region
+  epkgs.vundo        # undo tree
+  epkgs.puni       # structured editing
+  epkgs.avy        # jumping utility
+  epkgs.consult      # emacs right click
+  epkgs.vertico      # minibuffer completion
+  epkgs.marginalia     # annotations for completions
+  epkgs.crux       # utilities
+  epkgs.magit        # git porcelain
+  epkgs.nerd-icons-corfu   # nerd icons for completion
+  epkgs.corfu        # completion
+  epkgs.cape       # completion extensions
+  epkgs.orderless      # search paradigm
+  epkgs.yasnippet      # snippets support
+  epkgs.yasnippet-snippets   # commonly used snippets
+  epkgs.rg         # ripgrep
+  epkgs.exec-path-from-shell   # load env and path
+  epkgs.eat        # better shell
+  epkgs.rust-mode      # rust mode (when rust-ts doesn't cut it)
+  epkgs.rustic       # more rust things
+  epkgs.nix-mode       # nix lang
+  epkgs.hcl-mode       # hashicorp file mode
+  epkgs.shell-pop      # quick shell popup
+  epkgs.envrc        # support for loading .envrc
+  epkgs.nixpkgs-fmt      # format nix files
+  epkgs.f        # string + file utilities
+  epkgs.gptel        # llm chat (mainly claude)
+  epkgs.catppuccin-theme   # catppuccin theme
+  epkgs.eldoc-box      # docs in a box
+  epkgs.sideline       # 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
+];
+};
+home.sessionVariables = {
+EDITOR = "emacs";
+XDG_SCREENSHOTS_DIR = "~/screenshots";
+};
+home.file = {
+emacs-init = {
+  source = ./early-init.el;
+  target = ".emacs.d/early-init.el";
+};
+emacs = {
+  source = ./init.el;
+  target = ".emacs.d/init.el";
+};
+};
+services.nextcloud-client = {
+enable = true;
+};
 }
 
-
-

20.1. Early Initialization

+
+

20.1. Early Initialization

There are some emacs settings that can be configured before the gui shows up. @@ -3770,531 +3791,531 @@ These are listed here.

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

20.2. Initialization

+
+

20.2. Initialization

Now starts the main emacs configuration.

-
  ;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-
+
;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-
 
-  ;;; Commentary:
-  ;;; Simple Emacs setup I carry everywhere
+;;; Commentary:
+;;; Simple Emacs setup I carry everywhere
 
-  ;;; Code:
+;;; Code:
 (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)
 (package-initialize)
 
 (defun reset-custom-vars ()
-  "Resets the custom variables that were set to crazy numbers"
-  (setopt gc-cons-threshold (* 1024 1024 100))
-  (setopt garbage-collection-messages t))
+"Resets the custom variables that were set to crazy numbers"
+(setopt gc-cons-threshold (* 1024 1024 100))
+(setopt garbage-collection-messages t))
 
 (use-package emacs
-  :custom
-  (native-comp-async-query-on-exit t)
-  (read-answer-short t)
-  (use-short-answers t)
-  (enable-recursive-minibuffers t)
-  (which-func-update-delay 1.0)
-  (visible-bell nil)
-  (custom-buffer-done-kill t)
-  (whitespace-line-column nil)
-  (x-underline-at-descent-line t)
-  (imenu-auto-rescan t)
-  (uniquify-buffer-name-style 'forward)
-  (confirm-nonexistent-file-or-buffer nil)
-  (create-lockfiles nil)
-  (make-backup-files nil)
-  (kill-do-not-save-duplicates t)
-  (sentence-end-double-space nil)
-  (treesit-enabled-modes t)
-  :init
-  ;; base visual
-  (menu-bar-mode -1)                   ;; no menu bar
-  (toggle-scroll-bar -1)               ;; no scroll bar
-  (tool-bar-mode -1)                   ;; no tool bar either
-  (blink-cursor-mode -1)               ;; stop blinking
+:custom
+(native-comp-async-query-on-exit t)
+(read-answer-short t)
+(use-short-answers t)
+(enable-recursive-minibuffers t)
+(which-func-update-delay 1.0)
+(visible-bell nil)
+(custom-buffer-done-kill t)
+(whitespace-line-column nil)
+(x-underline-at-descent-line t)
+(imenu-auto-rescan t)
+(uniquify-buffer-name-style 'forward)
+(confirm-nonexistent-file-or-buffer nil)
+(create-lockfiles nil)
+(make-backup-files nil)
+(kill-do-not-save-duplicates t)
+(sentence-end-double-space nil)
+(treesit-enabled-modes t)
+:init
+;; base visual
+(menu-bar-mode -1)       ;; no menu bar
+(toggle-scroll-bar -1)     ;; no scroll bar
+(tool-bar-mode -1)       ;; no tool bar either
+(blink-cursor-mode -1)     ;; stop blinking
 
-  ;; font of the century
-  (set-frame-font "Aporetic Sans Mono 12" nil t)
+;; font of the century
+(set-frame-font "Aporetic Sans Mono 12" nil t)
 
-  :bind
-  (("C-<wheel-up>"   . pixel-scroll-precision) ; dont zoom in please, just scroll
-   ("C-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
-   ("C-x k"          . kill-current-buffer))   ; kill the buffer, dont ask
-  :hook
-  (text-mode . delete-trailing-whitespace-mode)
-  (prog-mode . delete-trailing-whitespace-mode)
-  (after-init . global-display-line-numbers-mode) ;; always show line numbers
-  (after-init . column-number-mode)               ;; column number in the mode line
-  (after-init . size-indication-mode)             ;; file size in the mode line
-  (after-init . pixel-scroll-precision-mode)      ;; smooth mouse scroll
-  (after-init . electric-pair-mode)               ;; i mean ... parens should auto create
-  (after-init . reset-custom-vars)
-  )
+:bind
+(("C-<wheel-up>" . pixel-scroll-precision) ; dont zoom in please, just scroll
+ ("C-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
+ ("C-x k"    . kill-current-buffer)) ; kill the buffer, dont ask
+:hook
+(text-mode . delete-trailing-whitespace-mode)
+(prog-mode . delete-trailing-whitespace-mode)
+(after-init . global-display-line-numbers-mode) ;; always show line numbers
+(after-init . column-number-mode)     ;; column number in the mode line
+(after-init . size-indication-mode)     ;; file size in the mode line
+(after-init . pixel-scroll-precision-mode)  ;; smooth mouse scroll
+(after-init . electric-pair-mode)     ;; i mean ... parens should auto create
+(after-init . reset-custom-vars)
+)
 
 (use-package autorevert
-  :ensure nil
-  :custom
-  (auto-revert-interval 3)
-  (auto-revert-remote-files nil)
-  (auto-revert-use-notify t)
-  (auto-revert-avoid-polling nil)
-  (auto-revert-verbose t)
-  :hook
-  (after-init . global-auto-revert-mode))
+:ensure nil
+:custom
+(auto-revert-interval 3)
+(auto-revert-remote-files nil)
+(auto-revert-use-notify t)
+(auto-revert-avoid-polling nil)
+(auto-revert-verbose t)
+:hook
+(after-init . global-auto-revert-mode))
 
 (use-package recentf
-  :ensure nil
-  :commands (recentf-mode recentf-cleanup)
-  :hook
-  (after-init . recentf-mode)
-  :custom
-  (recentf-auto-cleanup 'never)
-  (recentf-exclude
-   (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
-         "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
-         "\\.7z$" "\\.rar$"
-         "COMMIT_EDITMSG\\'"
-         "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
-         "-autoloads\\.el$" "autoload\\.el$"))
+:ensure nil
+:commands (recentf-mode recentf-cleanup)
+:hook
+(after-init . recentf-mode)
+:custom
+(recentf-auto-cleanup 'never)
+(recentf-exclude
+ (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
+   "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
+   "\\.7z$" "\\.rar$"
+   "COMMIT_EDITMSG\\'"
+   "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
+   "-autoloads\\.el$" "autoload\\.el$"))
 
-  :config
-  ;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
-  ;; `recentf-save-list', allowing stale entries to be removed before the list
-  ;; is saved by `recentf-save-list', which is automatically added to
-  ;; `kill-emacs-hook' by `recentf-mode'.
-  (add-hook 'kill-emacs-hook #'recentf-cleanup -90))
+:config
+;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
+;; `recentf-save-list', allowing stale entries to be removed before the list
+;; is saved by `recentf-save-list', which is automatically added to
+;; `kill-emacs-hook' by `recentf-mode'.
+(add-hook 'kill-emacs-hook #'recentf-cleanup -90))
 
 (use-package savehist
-  :ensure nil
-  :commands (savehist-mode savehist-save)
-  :hook
-  (after-init . savehist-mode)
-  :custom
-  (savehist-autosave-interval 600)
-  (savehist-additional-variables
-   '(kill-ring                        ; clipboard
-     register-alist                   ; macros
-     mark-ring global-mark-ring       ; marks
-     search-ring regexp-search-ring)))
+:ensure nil
+:commands (savehist-mode savehist-save)
+:hook
+(after-init . savehist-mode)
+:custom
+(savehist-autosave-interval 600)
+(savehist-additional-variables
+ '(kill-ring        ; clipboard
+ register-alist       ; macros
+ mark-ring global-mark-ring   ; marks
+ search-ring regexp-search-ring)))
 
 (use-package hl-line
-  :ensure nil
-  :custom
-  (hl-line-sticky-flag nil)
-  (global-hl-line-sticky-flag nil)
-  :hook
-  (after-init . global-hl-line-mode))
+:ensure nil
+:custom
+(hl-line-sticky-flag nil)
+(global-hl-line-sticky-flag nil)
+:hook
+(after-init . global-hl-line-mode))
 
 (use-package saveplace
-  :ensure nil
-  :commands (save-place-mode save-place-local-mode)
-  :hook
-  (after-init . save-place-mode)
-  :custom
-  (save-place-limit 400))
+:ensure nil
+:commands (save-place-mode save-place-local-mode)
+:hook
+(after-init . save-place-mode)
+:custom
+(save-place-limit 400))
 
 (use-package nerd-icons
-  :custom
-  ;; disable bright icon colors
-  (nerd-icons-color-icons nil))hells.nix
+:custom
+;; disable bright icon colors
+(nerd-icons-color-icons nil))hells.nix
 
 (use-package doom-modeline
-  :custom
-  (inhibit-compacting-font-caches t)    ;; speed
-  (doom-modeline-buffer-file-name-style 'relative-from-project)
-  (doom-modeline-major-mode-icon nil)   ;; distracting icons, no thank you
-  (doom-modeline-buffer-encoding nil)   ;; everything is utf-8 anyway
-  (doom-modeline-buffer-state-icon nil) ;; the filename already shows me
-  (doom-modeline-lsp nil)               ;; lsp state is too distracting, too often
-  :hook (after-init . doom-modeline-mode))
+:custom
+(inhibit-compacting-font-caches t)  ;; speed
+(doom-modeline-buffer-file-name-style 'relative-from-project)
+(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you
+(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway
+(doom-modeline-buffer-state-icon nil) ;; the filename already shows me
+(doom-modeline-lsp nil)     ;; lsp state is too distracting, too often
+:hook (after-init . doom-modeline-mode))
 
 (load-theme 'catppuccin :no-confirm)
 
-(use-package diminish :demand t)         ;; declutter the modeline
+(use-package diminish :demand t)   ;; declutter the modeline
 (use-package eldoc
-  :diminish eldoc-mode
-  :custom
-  (eldoc-echo-area-use-multiline-p nil)) ;; docs for everything
+:diminish eldoc-mode
+:custom
+(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything
 
 (use-package eldoc-box
-  :defer t
-  :config
-  (set-face-background 'eldoc-box-border (catppuccin-color 'green))
-  (set-face-background 'eldoc-box-body (catppuccin-color 'base))
-  :bind
-  (("M-h" . eldoc-box-help-at-point)))
+:defer t
+:config
+(set-face-background 'eldoc-box-border (catppuccin-color 'green))
+(set-face-background 'eldoc-box-body (catppuccin-color 'base))
+:bind
+(("M-h" . eldoc-box-help-at-point)))
 
 (use-package pulsar
-  :commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
-  :init
-  (defface pulsar-catppuccin
-    `((default :extend t)
-      (((class color) (min-colors 88) (background light))
-       :background ,(catppuccin-color 'sapphire))
-      (((class color) (min-colors 88) (background dark))
-       :background ,(catppuccin-color 'sapphire))
-      (t :inverse-video t))
-    "Alternative nord face for `pulsar-face'."
-    :group 'pulsar-faces)
-  :custom
-  (pulsar-face 'pulsar-catppuccin)
-  :hook
-  (after-init . pulsar-global-mode))
+:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
+:init
+(defface pulsar-catppuccin
+`((default :extend t)
+  (((class color) (min-colors 88) (background light))
+ :background ,(catppuccin-color 'sapphire))
+  (((class color) (min-colors 88) (background dark))
+ :background ,(catppuccin-color 'sapphire))
+  (t :inverse-video t))
+"Alternative nord face for `pulsar-face'."
+:group 'pulsar-faces)
+:custom
+(pulsar-face 'pulsar-catppuccin)
+:hook
+(after-init . pulsar-global-mode))
 
 (use-package which-key
-  :commands which-key-mode
-  :diminish which-key-mode
-  :hook
-  (after-init . which-key-mode))
+:commands which-key-mode
+:diminish which-key-mode
+:hook
+(after-init . which-key-mode))
 
 (use-package expreg
-  :bind ("M-m" . expreg-expand))
+:bind ("M-m" . expreg-expand))
 
 (use-package vundo) ;; undo tree
 
 ;; better structured editing
 (use-package puni
-  :commands puni-global-mode
-  :hook
-  (after-init . puni-global-mode))
+:commands puni-global-mode
+:hook
+(after-init . puni-global-mode))
 
 (use-package avy
-  :bind
-  ("M-i" . avy-goto-char-2)
-  :custom
-  (avy-background t))
+:bind
+("M-i" . avy-goto-char-2)
+:custom
+(avy-background t))
 
 (use-package consult
-  :bind
-  ("C-x b"   . consult-buffer)     ;; orig. switch-to-buffer
-  ("M-y"     . consult-yank-pop)   ;; orig. yank-pop
-  ("M-g M-g" . consult-goto-line)  ;; orig. goto-line
-  ("M-g i"   . consult-imenu)      ;; consult version is interactive
-  ("M-g r"   . consult-ripgrep)    ;; find in project also works
-  :custom
-  (consult-narrow-key "<"))
+:bind
+("C-x b" . consult-buffer)   ;; orig. switch-to-buffer
+("M-y"   . consult-yank-pop) ;; orig. yank-pop
+("M-g M-g" . consult-goto-line)  ;; orig. goto-line
+("M-g i" . consult-imenu)  ;; consult version is interactive
+("M-g r" . consult-ripgrep)  ;; find in project also works
+:custom
+(consult-narrow-key "<"))
 
 (use-package vertico
-  :commands vertico-mode
-  :custom
-  (read-file-name-completion-ignore-case t)
-  (read-buffer-completion-ignore-case t)
-  (completion-ignore-case t)
-  (enable-recursive-minibuffers t)
-  (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
-  :init
-  (vertico-mode)
-  :hook
-  (minibuffer-setup-hook . cursor-intangible-mode))
+:commands vertico-mode
+:custom
+(read-file-name-completion-ignore-case t)
+(read-buffer-completion-ignore-case t)
+(completion-ignore-case t)
+(enable-recursive-minibuffers t)
+(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
+:init
+(vertico-mode)
+:hook
+(minibuffer-setup-hook . cursor-intangible-mode))
 
 (use-package marginalia
-  :commands marginalia-mode
-  :hook (after-init . marginalia-mode))
+:commands marginalia-mode
+:hook (after-init . marginalia-mode))
 
 (use-package crux
-  :bind
-  ("C-c M-e" . crux-find-user-init-file)
-  ("C-c C-w" . crux-transpose-windows)
-  ("C-c M-d" . crux-find-current-directory-dir-locals-file)
-  ("C-a"     . crux-move-beginning-of-line))
+:bind
+("C-c M-e" . crux-find-user-init-file)
+("C-c C-w" . crux-transpose-windows)
+("C-c M-d" . crux-find-current-directory-dir-locals-file)
+("C-a"   . crux-move-beginning-of-line))
 
 (use-package magit
-  :bind (("C-M-g" . magit-status)))
+:bind (("C-M-g" . magit-status)))
 
 (use-package nerd-icons-corfu
-  :commands nerd-icons-corfu-formatter
-  :defines corfu-margin-formatters)
+:commands nerd-icons-corfu-formatter
+:defines corfu-margin-formatters)
 
 (use-package corfu
-  :commands global-corfu-mode
-  :custom
-  (corfu-cycle t)
-  (corfu-auto t)
-  (corfu-auto-delay  1)
-  (corfu-auto-prefix 3)
-  (corfu-separator ?_)
-  :hook
-  (after-init . global-corfu-mode)
-  :config
-  (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
+:commands global-corfu-mode
+:custom
+(corfu-cycle t)
+(corfu-auto t)
+(corfu-auto-delay  1)
+(corfu-auto-prefix 3)
+(corfu-separator ?_)
+:hook
+(after-init . global-corfu-mode)
+:config
+(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
 
 (use-package cape)
 
 (use-package orderless
-  :custom
-  (completion-styles '(orderless partial-completion basic))
-  (completion-category-defaults nil)
-  (completion-category-overrides nil))
+:custom
+(completion-styles '(orderless partial-completion basic))
+(completion-category-defaults nil)
+(completion-category-overrides nil))
 
 (use-package yasnippet
-  :commands yas-global-mode
-  :diminish yas-minor-mode
-  :hook
-  (after-init . yas-global-mode))
+:commands yas-global-mode
+:diminish yas-minor-mode
+:hook
+(after-init . yas-global-mode))
 
 (use-package yasnippet-snippets :after yasnippet)
 
 (use-package exec-path-from-shell
-  :commands exec-path-from-shell-initialize
-  :custom
-  (exec-path-from-shell-arguments nil)
-  :hook
-  (after-init . exec-path-from-shell-initialize))
+:commands exec-path-from-shell-initialize
+:custom
+(exec-path-from-shell-arguments nil)
+:hook
+(after-init . exec-path-from-shell-initialize))
 
 (use-package nixpkgs-fmt
-  :custom
-  (nixpkgs-fmt-command "nixfmt"))
+:custom
+(nixpkgs-fmt-command "nixfmt"))
 
 (use-package eat
-  :bind
-  (("C-c e p" . eat-project)
-   ("C-c e t" . eat)))
+:bind
+(("C-c e p" . eat-project)
+ ("C-c e t" . eat)))
 
 (use-package f :demand t)
 
 (use-package envrc
-  :commands envrc-global-mode
-  :hook
-  (after-init . envrc-global-mode))
+:commands envrc-global-mode
+:hook
+(after-init . envrc-global-mode))
 
 (use-package gptel
-  :commands gptel-make-anthropic f-read-text
-  :config
-  (gptel-make-anthropic "Claude"
-    :stream t :key (f-read-text "/run/secrets/claude_key")))
+:commands gptel-make-anthropic f-read-text
+:config
+(gptel-make-anthropic "Claude"
+:stream t :key (f-read-text "/run/secrets/claude_key")))
 
 (use-package sideline-flymake)
 (use-package sideline-eglot)
 (use-package sideline
-  :custom
-  (sideline-backends-right '(sideline-flymake sideline-eglot))
-  :hook
-  (eglot-managed-mode . sideline-mode)
-  (flymake-mode . sideline-mode))
+:custom
+(sideline-backends-right '(sideline-flymake sideline-eglot))
+:hook
+(eglot-managed-mode . sideline-mode)
+(flymake-mode . sideline-mode))
 
 (use-package eglot
-  :custom
-  (eglot-extend-to-xref t)
-  (eglot-ignored-server-capabilities '(:inlayHintProvider))
-  (jsonrpc-event-hook nil)
-  :hook
-  (eglot-managed-mode . eldoc-box-hover-mode)
-  (before-save . eldoc-format-buffer)
-  :bind
-  (:map eglot-mode-map
-        ("C-c l a" . eglot-code-actions)
-        ("C-c l r" . eglot-rename)
-        ("C-c l h" . eldoc)
-        ("C-c l g" . xref-find-references)
-        ("C-c l w" . eglot-reconnect)))
+:custom
+(eglot-extend-to-xref t)
+(eglot-ignored-server-capabilities '(:inlayHintProvider))
+(jsonrpc-event-hook nil)
+:hook
+(eglot-managed-mode . eldoc-box-hover-mode)
+(before-save . eldoc-format-buffer)
+:bind
+(:map eglot-mode-map
+  ("C-c l a" . eglot-code-actions)
+  ("C-c l r" . eglot-rename)
+  ("C-c l h" . eldoc)
+  ("C-c l g" . xref-find-references)
+  ("C-c l w" . eglot-reconnect)))
 
 (use-package proced
-  :custom
-  (proced-auto-update-flag t)
-  (proced-auto-update-interval 3)
-  (proced-enable-color-flag t)
-  (proced-show-remote-processes t))
+:custom
+(proced-auto-update-flag t)
+(proced-auto-update-interval 3)
+(proced-enable-color-flag t)
+(proced-show-remote-processes t))
 
 (use-package org
-  :ensure t
-  :defer t
-  :commands (org-mode org-capture org-agenda)
-  :init
-  (defvar org-journal-file "~/nextcloud/org/journal.org")
-  (defvar org-archive-file "~/nextcloud/org/archive.org")
-  (defvar org-notes-file "~/nextcloud/org/notes.org")
-  (defvar org-inbox-file "~/nextcloud/org/inbox.org")
-  (defvar org-work-file "~/nextcloud/org/work.org")
-  (defun my/org-capture-project-target-heading ()
-    "Determine Org target headings from the current file's project path.
+:ensure t
+:defer t
+:commands (org-mode org-capture org-agenda)
+:init
+(defvar org-journal-file "~/nextcloud/org/journal.org")
+(defvar org-archive-file "~/nextcloud/org/archive.org")
+(defvar org-notes-file "~/nextcloud/org/notes.org")
+(defvar org-inbox-file "~/nextcloud/org/inbox.org")
+(defvar org-work-file "~/nextcloud/org/work.org")
+(defun my/org-capture-project-target-heading ()
+"Determine Org target headings from the current file's project path.
 
-    This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
-    It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
-    for an Org capture template.
+This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
+It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
+for an Org capture template.
 
-    If the current buffer is not visi
+If the current buffer is not visi
 ting a file within such a
-    project structure, it returns nil, causing capture to default to
-    the top of the file."
-    (when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
-      (let ((path-parts (split-string path "/" t " ")))
-        (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
-                    (company      (nth (+ 1 projects-pos) path-parts))
-                    (project      (nth (+ 2 projects-pos) path-parts)))
-          ;; Return a list of headlines for Org to find or create.
-          (list company project)))))
-  :bind
-  (("C-c c" . org-capture)
-   ("C-c i" . org-store-link)
-   ("C-c a" . org-agenda)
-   :map org-mode-map
-   ("C-c t" . org-toggle-inline-images)
-   ("C-c l" . org-toggle-link-display))
-  :custom
-  (org-agenda-files (list org-inbox-file org-journal-file))
-  (org-directory "~/nextcloud/org")
-  (org-default-notes-file org-inbox-file)
-  (org-archive-location (concat org-archive-file "::* From %s"))
-  (org-log-done 'time)
-  (org-log-into-drawer t)
-  (org-hide-emphasis-markers t)
-  (org-src-fontify-natively t)
-  (org-src-tab-acts-natively t)
-  (org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
-                            "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
-                           ("j" "Journal" entry (file+olp+datetree org-journal-file)
-                            "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
-                           ("n" "Note" entry (file org-notes-file)
-                            "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
-                           ("p" "Project Task" item
-                            (file+function org-work-file my/org-capture-project-target-heading)
-                            "* TODO %? \n  CLOCK: %U"
-                            ))
-                         )
-  :config
-  ;; Enable syntax highlighting in code blocks
-  (add-hook 'org-mode-hook 'turn-on-font-lock)
-  (add-hook 'org-mode-hook 'org-indent-mode))
+project structure, it returns nil, causing capture to default to
+the top of the file."
+(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
+  (let ((path-parts (split-string path "/" t " ")))
+  (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
+      (company  (nth (+ 1 projects-pos) path-parts))
+      (project  (nth (+ 2 projects-pos) path-parts)))
+  ;; Return a list of headlines for Org to find or create.
+  (list company project)))))
+:bind
+(("C-c c" . org-capture)
+ ("C-c i" . org-store-link)
+ ("C-c a" . org-agenda)
+ :map org-mode-map
+ ("C-c t" . org-toggle-inline-images)
+ ("C-c l" . org-toggle-link-display))
+:custom
+(org-agenda-files (list org-inbox-file org-journal-file))
+(org-directory "~/nextcloud/org")
+(org-default-notes-file org-inbox-file)
+(org-archive-location (concat org-archive-file "::* From %s"))
+(org-log-done 'time)
+(org-log-into-drawer t)
+(org-hide-emphasis-markers t)
+(org-src-fontify-natively t)
+(org-src-tab-acts-natively t)
+(org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
+        "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
+         ("j" "Journal" entry (file+olp+datetree org-journal-file)
+        "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
+         ("n" "Note" entry (file org-notes-file)
+        "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
+         ("p" "Project Task" item
+        (file+function org-work-file my/org-capture-project-target-heading)
+        "* TODO %? \n  CLOCK: %U"
+        ))
+       )
+:config
+;; Enable syntax highlighting in code blocks
+(add-hook 'org-mode-hook 'turn-on-font-lock)
+(add-hook 'org-mode-hook 'org-indent-mode))
 
 ;; extras
 (use-package comp-run
-  :ensure nil
-  :config
-  (push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
-  (push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))
+:ensure nil
+:config
+(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
+(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))
 
 (use-package rustic
-  :custom
-  (rustic-lsp-client 'eglot))
+:custom
+(rustic-lsp-client 'eglot))
 
 (provide 'init)
 
-  ;;; init.el ends here
+;;; init.el ends here
 
-
-

21. Machines

+
+

21. Machines

Only a few more things left. Specifically the machine level extra settings.

-
-

21.1. Traveldroid

+
+

21.1. Traveldroid

The configuration for the laptop does not change much. Most changes are because the hardware is different.

-
-

21.1.1. System Level

+
+

21.1.1. System Level

Nothing specific for the laptop. @@ -4303,17 +4324,17 @@ Nothing specific for the laptop.

{ user, ... } : {
   imports =
-    [
-      ./hardware-configuration.nix
-      ../../configuration
-    ];
+  [
+  ./hardware-configuration.nix
+  ../../configuration
+  ];
 }
 
-
-

21.1.2. Hardware

+
+

21.1.2. Hardware

This is the most different. Mostly taken from hardware-configuration.nix setup at first install. @@ -4321,19 +4342,19 @@ This is the most different. Mostly taken from hardware-configuration.nix setup a

{
-  hostname,
-  pkgs,
-  lib,
-  modulesPath,
-  user,
-  config,
-  ...
+hostname,
+pkgs,
+lib,
+modulesPath,
+user,
+config,
+...
 }:
 {
-  imports = [
-    (modulesPath + "/installer/scan/not-detected.nix")
-    ../../hardware/hardware.nix
-  ];
+imports = [
+(modulesPath + "/installer/scan/not-detected.nix")
+../../hardware/hardware.nix
+];
 
 boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
 boot.initrd.kernelModules = [ ];
@@ -4341,19 +4362,19 @@ boot.kernelModules = [ "kvm-intel" ];
 boot.extraModulePackages = [ ];
 
 fileSystems."/" =
-  { device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2";
-    fsType = "ext4";
-  };
+{ device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2";
+fsType = "ext4";
+};
 
 fileSystems."/boot" =
-  { device = "/dev/disk/by-uuid/811D-0676";
-    fsType = "vfat";
-    options = [ "fmask=0077" "dmask=0077" ];
-  };
+{ device = "/dev/disk/by-uuid/811D-0676";
+fsType = "vfat";
+options = [ "fmask=0077" "dmask=0077" ];
+};
 
 swapDevices =
-  [ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; }
-  ];
+[ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; }
+];
 
 nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
 hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
@@ -4363,8 +4384,8 @@ hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistr
 
-
-

21.1.3. Home

+
+

21.1.3. Home

This is mostly about configuring the monitor. And laptop specific utilities. @@ -4373,16 +4394,16 @@ This is mostly about configuring the monitor. And laptop specific utilities.

{ pkgs, ... }:
 {
   imports = [
-    ../../home
+  ../../home
   ];
   home.packages = with pkgs; [
-    brightnessctl
+  brightnessctl
   ];
   wayland.windowManager.hyprland = {
-    extraConfig = ''
-      # Default portable monitor rule
-      monitor=DP-1,3840x1080@144,1920x0,1
-    '';
+  extraConfig = ''
+  # Default portable monitor rule
+  monitor=DP-1,3840x1080@144,1920x0,1
+  '';
   };
 }
 
@@ -4391,26 +4412,26 @@ This is mostly about configuring the monitor. And laptop specific utilities.
-
-

22. README Utils

+
+

22. README Utils

-
-

22.0.1. Headers

+
+

22.0.1. Headers

This script adds a DO NOT MODIFY header to all the generated nix files.

-
(progn
-  (defun add-tangle-headers ()
-    (message "running in %s" (buffer-file-name))
-    (when (string= (file-name-extension (buffer-file-name)) "nix")
-      (goto-char (point-min))
-      (insert "# WARNING : This file was generated by README.org\n# DO NOT MODIFY THIS FILE!\n# Any changes made here will be overwritten.\n")
-      (save-buffer))
-    (save-buffer))
-  (add-hook 'org-babel-post-tangle-hook 'add-tangle-headers))
+
(progn
+(defun add-tangle-headers ()
+(message "running in %s" (buffer-file-name))
+(when (string= (file-name-extension (buffer-file-name)) "nix")
+  (goto-char (point-min))
+  (insert "# WARNING : This file was generated by README.org\n# DO NOT MODIFY THIS FILE!\n# Any changes made here will be overwritten.\n")
+  (save-buffer))
+(save-buffer))
+(add-hook 'org-babel-post-tangle-hook 'add-tangle-headers))
 
@@ -4419,7 +4440,7 @@ This script adds a DO NOT MODIFY header to all the generated nix fi

Author: henrov

-

Created: 2026-02-28 za 18:24

+

Created: 2026-03-01 zo 17:23

Validate

diff --git a/henrovnix_ok/README.org b/henrovnix_ok/README.org index 0ec32f060..4a6d3a8a0 100755 --- a/henrovnix_ok/README.org +++ b/henrovnix_ok/README.org @@ -1,29 +1,29 @@ -gf#+OPTIONS: toc:nil broken-links:t +f#+OPTIONS: toc:nil broken-links:t #+PROPERTY: header-args :noweb yes :results silent :mkdirp yes #+HTML:
-#+HTML:
-#+HTML: NixOS -#+HTML: Emacs -#+HTML:
-#+HTML:
-#+HTML:

Henrov's Literate System Configuration

-#+HTML: +#+HTML:
+#+HTML: NixOS +#+HTML: Emacs +#+HTML:
+#+HTML:
+#+HTML:

Henrov's Literate System Configuration

+#+HTML: #+HTML:
* Introduction @@ -359,15 +359,15 @@ This separation maintains clarity between system-level packages and user-facing 3. Replace ** in all files with =YOUR_USER= #+begin_src bash :tangle no block find ~/Repos/nixos/henrovnix_ok \ - -type d -name ".*" -prune -o \ - -type f -print0 \ + -type d -name ".*" -prune -o \ + -type f -print0 \ | xargs -0 sed -i 's/==/YOUR_USER/g' #+end_src 4. Replace *machine1* in all files with =YOUR_HOSTNAME= #+begin_src bash :tangle no block find ~/Repos/nixos/henrovnix_ok \ - -type d -name ".*" -prune -o \ - -type f -print0 \ + -type d -name ".*" -prune -o \ + -type f -print0 \ | xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g' #+end_src 5. Rename the folder ./machines/machine1 to your hostname @@ -484,11 +484,11 @@ The tree below shows the full repository layout, with the standardized internal │   │   │   │   │   ├── config.ron │   │   │   │   │   └── styles.css │   │   │   │   └── scripts -│   │   │   │   ├── hyprscrolling-per-monitor.sh -│   │   │   │   ├── hyprscroll-overflow.sh -│   │   │   │   ├── lid-lock.sh -│   │   │   │   ├── lid-restore.sh -│   │   │   │   └── powermenu.sh +│   │   │   │   ├── hyprscrolling-per-monitor.sh +│   │   │   │   ├── hyprscroll-overflow.sh +│   │   │   │   ├── lid-lock.sh +│   │   │   │   ├── lid-restore.sh +│   │   │   │   └── powermenu.sh │   │   │   ├── wallpaper │   │   │   │   ├── gif │   │   │   │   ├── pictures @@ -506,20 +506,20 @@ The tree below shows the full repository layout, with the standardized internal │   │   │   │   │   └── white_blobs_small.mp4 │   │   │   │   └── wallpaper.conf │   │   │   └── waybar -│   │   │   ├── config.jsonc -│   │   │   └── style.css +│   │   │   ├── config.jsonc +│   │   │   └── style.css │   │   ├── dev │   │   │   └── terminal -│   │   │   ├── alacritty.toml -│   │   │   ├── aliases.conf -│   │   │   ├── Catppuccin-Mocha.conf -│   │   │   ├── enabled_shells.conf -│   │   │   ├── kitty.conf -│   │   │   ├── starship.toml -│   │   │   └── zsh.conf +│   │   │   ├── alacritty.toml +│   │   │   ├── aliases.conf +│   │   │   ├── Catppuccin-Mocha.conf +│   │   │   ├── enabled_shells.conf +│   │   │   ├── kitty.conf +│   │   │   ├── starship.toml +│   │   │   └── zsh.conf │   │   ├── security │   │   │   └── ssh -│   │   │   └── ssh-client.conf +│   │   │   └── ssh-client.conf │   │   └── services │   ├── lock.png │   └── scripts @@ -542,7 +542,7 @@ The tree below shows the full repository layout, with the standardized internal │   ├── dev │   │   └── terminal.nix │   └── services -│   └── services.nix +│   └── services.nix ├── flake.lock ├── flake.nix ├── hardware @@ -567,22 +567,22 @@ The tree below shows the full repository layout, with the standardized internal │   │   ├── waybar.nix │   │   └── workspace_wallpaper.nix │   └── dev -│   ├── alacritty.nix -│   ├── dev.nix -│   ├── emacs -│   │   ├── default.nix -│   │   ├── early-init.el -│   │   └── init.el -│   ├── kitty.nix -│   ├── shells.nix -│   ├── starship.nix -│   └── zsh.nix +│   ├── alacritty.nix +│   ├── dev.nix +│   ├── emacs +│   │   ├── default.nix +│   │   ├── early-init.el +│   │   └── init.el +│   ├── kitty.nix +│   ├── shells.nix +│   ├── starship.nix +│   └── zsh.nix ├── LICENSE ├── machines │   └── traveldroid -│   ├── configuration.nix -│   ├── hardware-configuration.nix -│   └── home.nix +│   ├── configuration.nix +│   ├── hardware-configuration.nix +│   └── home.nix ├── README.html ├── README.org └── user.nix @@ -599,10 +599,10 @@ The tree below shows the full repository layout, with the standardized internal I use [[https://nixos.wiki/wiki/Flakes][nix flakes]] which means that the entry point for the nix evaluation is a file called ~flake.nix~ which has two parts (among other things) #+begin_src nix - { - inputs: # describes the function input, consisting mainly of package sources - outputs: # what the function outputs, a nixos configuration in our case - } + { + inputs: # describes the function input, consisting mainly of package sources + outputs: # what the function outputs, a nixos configuration in our case + } #+end_src Nix flakes is still behind an ~experimental~ flag, but it is de facto the standard by most of the community. @@ -611,18 +611,18 @@ The tree below shows the full repository layout, with the standardized internal * TLDR App List -| Window Manager | [[https://hyprland.org/][Hyprland]] | -| Bar | [[https://github.com/Alexays/Waybar][Waybar]] | -| Application Launcher | [[https://github.com/abenz1267/walker][Walker]] | -| Terminal Emulator | [[https://alacritty.org/][Alacritty]] | -| Shell | [[https://ohmyz.sh/][Zsh]] and [[https://starship.rs/][Starship]] | -| Text Editor | [[https://www.gnu.org/software/emacs/][Emacs]] | -| File Manager | [[https://docs.xfce.org/xfce/thunar/start][Thunar]] | -| Fonts | [[https://protesilaos.com/codelog/2025-02-12-aporetic-fonts-version-1-1-0/][Aporeti]] | -| Colors | [[https://catppuccin.com/][Catppuccin]] | -| Icons | [[https://nix.catppuccin.com/][Catppuccin Nix ]] | -| Lock Screen | [[https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/][Hyprlock]] | -| Wallpapers | [[https://github.com/hyprwm/hyprpaper][Hyprpaper]] | +| Window Manager | [[https://hyprland.org/][Hyprland]] | +| Bar | [[https://github.com/Alexays/Waybar][Waybar]] | +| Application Launcher | [[https://github.com/abenz1267/walker][Walker]] | +| Terminal Emulator | [[https://alacritty.org/][Alacritty]] | +| Shell | [[https://ohmyz.sh/][Zsh]] and [[https://starship.rs/][Starship]] | +| Text Editor | [[https://www.gnu.org/software/emacs/][Emacs]] | +| File Manager | [[https://docs.xfce.org/xfce/thunar/start][Thunar]] | +| Fonts | [[https://protesilaos.com/codelog/2025-02-12-aporetic-fonts-version-1-1-0/][Aporeti]] | +| Colors | [[https://catppuccin.com/][Catppuccin]] | +| Icons | [[https://nix.catppuccin.com/][Catppuccin Nix ]] | +| Lock Screen | [[https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/][Hyprlock]] | +| Wallpapers | [[https://github.com/hyprwm/hyprpaper][Hyprpaper]] | * Configuration Variables I have a bunch of constant strings that I would rather put in a file. Thats what ~user.nix~ is. @@ -639,34 +639,34 @@ The values are imported at the beginning and are available to almost all the fun * Flake Inputs The inputs for my system's configuration are very simple 1. [[https://search.nixos.org/packages][nixpkgs]] - the main nix repository of packages. Its huge and growing. Pinned to the unstable release channel. - Sometimes pinned to a specific commit because unstable broke something and the fix hasn't made it into the release yet. + Sometimes pinned to a specific commit because unstable broke something and the fix hasn't made it into the release yet. 2. [[https://nix-community.github.io/home-manager/][home-manager]] - a nix module that helps keep track of user specific dotfiles and configurations as part of my nix config. 3. [[https://github.com/nix-community/emacs-overlay][emacs-overlay]] - this has more configuration options and generally a newer emacs available provided by the community. 4. [[https://nix.catppuccin.com/][catppuccin]] - nix module that allows everything to be catppuccin themed. #+begin_src nix :tangle flake.nix :noweb tangle { - description = "Henrov's nixos configuration"; - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - home-manager = { - url = "github:nix-community/home-manager"; - 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"; - }; + description = "Henrov's nixos configuration"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager = { + url = "github:nix-community/home-manager"; + 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"; + }; + }; + <> } #+end_src @@ -677,109 +677,109 @@ We also add a devshell that makes editing this repository easier in emacs. #+name: flake-outputs #+begin_src nix :noweb no-export outputs = inputs@{ - nixpkgs, - home-manager, - emacs-overlay, - catppuccin, - ... + nixpkgs, + home-manager, + emacs-overlay, + catppuccin, + ... }: - let - user = import ./user.nix; - lib = nixpkgs.lib; - machines = [ - "traveldroid" + 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 = [ + <> + <> + <> + catppuccin.nixosModules.catppuccin # theme ]; - pkgs = import nixpkgs { - inherit (user) system; - }; - in - { - nixosConfigurations = builtins.listToAttrs ( - builtins.map (machine: { - name = machine; - value = lib.nixosSystem { - modules = [ - <> - <> - <> - 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 - ]; - }; + specialArgs = { + hostname = machine; + inherit user; + inherit inputs; + flakeRoot = inputs.self; }; + }; + }) machines + ); + + devShells.${user.system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nil + nixfmt-rfc-style + ]; + }; + }; #+end_src Lets look at the individual modules 1. Emacs - The first is the emacs overlay so that it uses the nix-community emacs overlay from the inputs instead of the nixpkgs one. - Overlays are a special nix way to override existing packages within a repository. + The first is the emacs overlay so that it uses the nix-community emacs overlay from the inputs instead of the nixpkgs one. + Overlays are a special nix way to override existing packages within a repository. - #+name: flake-emacs-module + #+name: flake-emacs-module #+begin_src nix - ({ ... }: { - nixpkgs.overlays = [ emacs-overlay.overlays.default ]; - }) + ({ ... }: { + nixpkgs.overlays = [ emacs-overlay.overlays.default ]; + }) #+end_src 2. Then the machine specific configuration, in this case, just "traveldroid". - #+name: flake-config-module + #+name: flake-config-module #+begin_src nix - ./machines/${machine}/configuration.nix + ./machines/${machine}/configuration.nix #+end_src 3. And finally the home-manager module. - This can be initialized and managed on its own but I'd rather use the ~nixos-rebuild~ command to build everything instead of managing userland dotfiles separately. + This can be initialized and managed on its own but I'd rather use the ~nixos-rebuild~ command to build everything instead of managing userland dotfiles separately. - #+name: flake-home-module + #+name: flake-home-module #+begin_src nix :noweb no-export - home-manager.nixosModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; - home-manager.extraSpecialArgs = { - inherit user inputs; - flakeRoot = inputs.self; - }; + home-manager.extraSpecialArgs = { + inherit user inputs; + flakeRoot = inputs.self; + }; - <> - <> - } + <> + <> + } #+end_src - - Home-Manager will not overwrite existing configuration files and that is good in most cases, but when everything is declarative like it is here, I'd rather that home-manager create a ~.backup~ and replace the file. - #+name: flake-home-backup - #+begin_src nix - home-manager.backupFileExtension = "backup"; - #+end_src + - Home-Manager will not overwrite existing configuration files and that is good in most cases, but when everything is declarative like it is here, I'd rather that home-manager create a ~.backup~ and replace the file. + #+name: flake-home-backup + #+begin_src nix + home-manager.backupFileExtension = "backup"; + #+end_src - - Finally I pull in the machine specific home configuration. Along with the overrides from catppuccin. - #+name: flake-home-config - #+begin_src nix - home-manager.users.${user.username} = { - imports = [ - ./machines/${machine}/home.nix - catppuccin.homeModules.catppuccin - ]; - }; - #+end_src + - Finally I pull in the machine specific home configuration. Along with the overrides from catppuccin. + #+name: flake-home-config + #+begin_src nix + home-manager.users.${user.username} = { + imports = [ + ./machines/${machine}/home.nix + catppuccin.homeModules.catppuccin + ]; + }; + #+end_src ** Envrc + Direnv Editing this file will be much nicer if we have the dev environment configured. @@ -792,7 +792,7 @@ This tells [[https://direnv.net/][direnv]] to load the devshell in the flake. watch_file .envrc.private if [[ -f .envrc.private ]]; then - source_env .envrc.private + source_env .envrc.private fi #+end_src @@ -828,26 +828,26 @@ I'll let the code comments explain the file here. #+begin_src nix :tangle hardware/hardware.nix :noweb tangle :mkdirp yes { pkgs, lib, user, config, ...} : { - nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu + nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu - # update cpu microcode with firmware that allows redistribution - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + # update cpu microcode with firmware that allows redistribution + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - hardware = { - # always enable bluetooth - bluetooth.enable = true; + hardware = { + # always enable bluetooth + bluetooth.enable = true; - # always enable graphics drivers and enable a bunch of layers for it (including vulkan validation) - graphics = { - enable = true; - extraPackages = with pkgs; [ - vulkan-validation-layers # helps catch and debug vulkan crashes - ]; - }; - }; + # always enable graphics drivers and enable a bunch of layers for it (including vulkan validation) + graphics = { + enable = true; + extraPackages = with pkgs; [ + 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 } #+end_src @@ -858,35 +858,35 @@ This section describes the main system configuration for the computers that I ha { pkgs, user, ... } : { imports = [ - ./apps/install_flatpaks.nix - ./apps/install_packages.nix - ./core/files.nix - ./core/locale.nix - ./core/networking.nix - ./core/nix-settings.nix - #./core/login-tuigreeter.nix - ./core/login-lightdm.nix - ./desktop/audio.nix - ./desktop/hyprland.nix - ./dev/terminal.nix - ./core/boot.nix - ./services/services.nix - ]; + ./apps/install_flatpaks.nix + ./apps/install_packages.nix + ./core/files.nix + ./core/locale.nix + ./core/networking.nix + ./core/nix-settings.nix + #./core/login-tuigreeter.nix + ./core/login-lightdm.nix + ./desktop/audio.nix + ./desktop/hyprland.nix + ./dev/terminal.nix + ./core/boot.nix + ./services/services.nix + ]; - <> + <> - <> + <> - <> + <> - <> + <> - # enable the catppuccin theme for everything with mocha + blue accents - catppuccin.enable = true; - catppuccin.flavor = "mocha"; - catppuccin.accent = "blue"; + # enable the catppuccin theme for everything with mocha + blue accents + catppuccin.enable = true; + catppuccin.flavor = "mocha"; + catppuccin.accent = "blue"; - system.stateVersion = user.stateVersion; + system.stateVersion = user.stateVersion; } #+end_src @@ -903,40 +903,40 @@ let rawLines = lib.splitString "\n" raw; # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw _guard = assert !( - builtins.stringLength raw > 1 && - builtins.length rawLines == builtins.stringLength raw + builtins.stringLength raw > 1 && + builtins.length rawLines == builtins.stringLength raw ); true; cleanLine = l: - let - noCR = lib.replaceStrings [ "\r" ] [ "" ] l; - noInlineComment = lib.head (lib.splitString "#" noCR); - in - lib.strings.trim noInlineComment; + let + noCR = lib.replaceStrings [ "\r" ] [ "" ] l; + noInlineComment = lib.head (lib.splitString "#" noCR); + in + lib.strings.trim noInlineComment; entries = - builtins.filter (l: l != "") - (map cleanLine rawLines); + builtins.filter (l: l != "") + (map cleanLine rawLines); resolvePkg = name: - let - parts = lib.splitString "." name; - found = lib.attrByPath parts null pkgs; - in - if found == null then - throw '' - install_packages.nix: package not found in pkgs - Token : ${builtins.toJSON name} - packages.conf : ${toString packagesConfPath} - Hint : check the attribute name on search.nixos.org/packages - '' - else - found; + let + parts = lib.splitString "." name; + found = lib.attrByPath parts null pkgs; + in + if found == null then + throw '' + install_packages.nix: package not found in pkgs + Token : ${builtins.toJSON name} + packages.conf : ${toString packagesConfPath} + Hint : check the attribute name on search.nixos.org/packages + '' + else + found; packages = builtins.seq _guard (map resolvePkg entries); zenBrowser = - inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default; + inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default; in { environment.systemPackages = - packages - ++ [ zenBrowser ]; + packages + ++ [ zenBrowser ]; } #+end_src @@ -952,99 +952,99 @@ let # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw _guard = assert !( - builtins.stringLength raw > 1 && - builtins.length rawLines == builtins.stringLength raw + builtins.stringLength raw > 1 && + builtins.length rawLines == builtins.stringLength raw ); true; cleanLine = l: - let - noCR = lib.replaceStrings [ "\r" ] [ "" ] l; - noInlineComment = lib.head (lib.splitString "#" noCR); - in - lib.strings.trim noInlineComment; + let + noCR = lib.replaceStrings [ "\r" ] [ "" ] l; + noInlineComment = lib.head (lib.splitString "#" noCR); + in + lib.strings.trim noInlineComment; entries = - builtins.filter (l: l != "") - (map cleanLine rawLines); + builtins.filter (l: l != "") + (map cleanLine rawLines); # 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. dotCount = s: builtins.length (lib.splitString "." s) - 1; 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 = - builtins.seq _guard ( - builtins.map (id: - if isValidId id then true else - throw '' - ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots) + builtins.seq _guard ( + builtins.map (id: + if isValidId id then true else + throw '' + ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots) - Token : ${builtins.toJSON id} - flatpaks.conf : ${toString flatpakConfPath} + Token : ${builtins.toJSON id} + flatpaks.conf : ${toString flatpakConfPath} - Fix: remove stray tokens/headers, or comment them out with '#'. - '' - ) entries - ); + Fix: remove stray tokens/headers, or comment them out with '#'. + '' + ) entries + ); # Use validated entries flatpakApps = builtins.seq _validate entries; syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" '' - set -euo pipefail + set -euo pipefail - # Use the deployed config path (matches environment.etc below) - CONF="/etc/flatpak/flatpaks.conf" - if [[ -f "$CONF" ]]; then - echo "flatpak-sync: using $CONF" - else - echo "flatpak-sync: WARNING: $CONF not found, using embedded list" - fi + # Use the deployed config path (matches environment.etc below) + CONF="/etc/flatpak/flatpaks.conf" + if [[ -f "$CONF" ]]; then + echo "flatpak-sync: using $CONF" + else + echo "flatpak-sync: WARNING: $CONF not found, using embedded list" + fi - if ! flatpak remotes --system --columns=name | grep -qx flathub; then - flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - fi + if ! flatpak remotes --system --columns=name | grep -qx flathub; then + flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + fi - desired_apps=( - ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)} - ) + desired_apps=( + ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)} + ) - for app in "''${desired_apps[@]}"; do - if ! flatpak info --system "$app" >/dev/null 2>&1; then - flatpak install --system -y --noninteractive flathub "$app" - fi - done + for app in "''${desired_apps[@]}"; do + if ! flatpak info --system "$app" >/dev/null 2>&1; then + flatpak install --system -y --noninteractive flathub "$app" + fi + done ''; in { services.flatpak.enable = true; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-hyprland - xdg-desktop-portal-gtk - ]; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + xdg-desktop-portal-gtk + ]; }; # 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 = { - description = "Install Flatpak apps listed in flatpaks.conf"; - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; + description = "Install Flatpak apps listed in flatpaks.conf"; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = syncFlatpaks; - }; + serviceConfig = { + Type = "oneshot"; + ExecStart = syncFlatpaks; + }; - restartTriggers = [ flatpakConfPath ]; - path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; + restartTriggers = [ flatpakConfPath ]; + path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; }; } #+end_src @@ -1056,41 +1056,41 @@ These are global nix settings that configure the settings for the actual tool. #+begin_src nix :tangle configuration/core/nix-settings.nix :noweb tangle :mkdirp yes { pkgs, user, ... } : { - nix.settings = { - # enable flakes - experimental-features = ["nix-command" "flakes"]; + nix.settings = { + # enable flakes + experimental-features = ["nix-command" "flakes"]; - # add a cache that speed up new applications by downloading binaries - # from the trusted cache instead of compiling from sourcer - substituters = [ - "https://nix-community.cachix.org" - ]; - # trust the cache public key - trusted-public-keys = [ - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - }; + # add a cache that speed up new applications by downloading binaries + # from the trusted cache instead of compiling from sourcer + substituters = [ + "https://nix-community.cachix.org" + ]; + # trust the cache public key + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + }; - # allow proprietary software on this machine. I'm not a purist. - nixpkgs.config.allowUnfree = true; - # unityhub depends on this... for now - nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ]; + # allow proprietary software on this machine. I'm not a purist. + nixpkgs.config.allowUnfree = true; + # unityhub depends on this... for now + nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ]; - # this declares how often old configurations are cleared up. - # i cleanup anything older than a week, every week. - nix.gc = { - automatic = true; - options = "--delete-older-than 7d"; - dates = "weekly"; - }; + # this declares how often old configurations are cleared up. + # i cleanup anything older than a week, every week. + nix.gc = { + automatic = true; + options = "--delete-older-than 7d"; + dates = "weekly"; + }; - programs = { - # command line utility that makes applying changes easy and pretty - nh = { - enable = true; - flake = "/home/${user.username}/system"; - }; - }; + programs = { + # command line utility that makes applying changes easy and pretty + nh = { + enable = true; + flake = "/home/${user.username}/system"; + }; + }; } #+end_src @@ -1101,28 +1101,28 @@ This file has most of the settings the control how the computer boots up. { pkgs, ... } : { boot = { - initrd = { - verbose = false; # its a lot of logs. dont need it, unless we do. - kernelModules = [ ]; # no kernel modules on boot - }; + initrd = { + verbose = false; # its a lot of logs. dont need it, unless we do. + kernelModules = [ ]; # no kernel modules on boot + }; - extraModulePackages = [ ]; # no extra packages on boot either - kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel - kernelParams = [ "silent" ]; # quiet those logs + extraModulePackages = [ ]; # no extra packages on boot either + kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel + kernelParams = [ "silent" ]; # quiet those logs - consoleLogLevel = 0; # quiten more logs - plymouth.enable = true; # graphical boot animation instead + consoleLogLevel = 0; # quiten more logs + plymouth.enable = true; # graphical boot animation instead - supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows) + supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows) - loader = { - systemd-boot.enable = true; # systemd-boot - systemd-boot.configurationLimit = 10; - efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader + loader = { + systemd-boot.enable = true; # systemd-boot + systemd-boot.configurationLimit = 10; + 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 + }; }; } #+end_src @@ -1136,17 +1136,17 @@ Doesn't match the rest of the aesthetic of the system (with hyprland), but I lik #+begin_src nix :tangle configuration/core/login-tuigreeter.nix :noweb tangle :mkdirp yes { pkgs, user, ... } : { - environment.systemPackages = with pkgs; [ - tuigreet - ]; - services.greetd = { - enable = true; - settings = { - default_session = { - command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'"; - }; - }; + environment.systemPackages = with pkgs; [ + tuigreet + ]; + services.greetd = { + enable = true; + settings = { + default_session = { + command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'"; }; + }; + }; } #+end_src @@ -1156,40 +1156,40 @@ Doesn't match the rest of the aesthetic of the system (with hyprland), but I lik let lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf; - lockPng = ../../assets/lock.png; + lockPng = ../../assets/lock.png; greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf; - greeterRaw = builtins.readFile greeterConfPath; + greeterRaw = builtins.readFile greeterConfPath; # Extract "key = value" from the greeter conf. # Returns null if not found. getIniValue = key: - let - lines = lib.splitString "\n" greeterRaw; + let + lines = lib.splitString "\n" greeterRaw; - # 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). - m = - let - ms = builtins.filter (x: x != null) (map (line: - builtins.match - ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") - line - ) lines); - in - if ms == [] then null else builtins.elemAt ms 0; + # 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). + m = + let + ms = builtins.filter (x: x != null) (map (line: + builtins.match + ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") + line + ) lines); 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. themePkgKey = getIniValue "theme-name"; - iconPkgKey = getIniValue "icon-theme-name"; + iconPkgKey = getIniValue "icon-theme-name"; cursorPkgKey = getIniValue "cursor-theme-name"; cursorSizeStr = getIniValue "cursor-theme-size"; cursorSize = - if cursorSizeStr == null then null - else lib.toInt (lib.strings.trim cursorSizeStr); + if cursorSizeStr == null then null + else lib.toInt (lib.strings.trim cursorSizeStr); # Map package-keys (from greeter.conf) -> { package, name } # @@ -1197,98 +1197,98 @@ let # - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons. # - "package" is the Nixpkgs derivation providing it. pkgMap = { - catppuccinThemePkg = { - package = pkgs.catppuccin-gtk.override { - accents = [ "blue" ]; - variant = "mocha"; - size = "standard"; - tweaks = [ ]; - }; - name = "Catppuccin-Mocha-Standard-Blue-Dark"; - }; + catppuccinThemePkg = { + package = pkgs.catppuccin-gtk.override { + accents = [ "blue" ]; + variant = "mocha"; + size = "standard"; + tweaks = [ ]; + }; + name = "Catppuccin-Mocha-Standard-Blue-Dark"; + }; - papirus-icon-theme = { - package = pkgs.papirus-icon-theme; - name = "Papirus-Dark"; - }; + papirus-icon-theme = { + package = pkgs.papirus-icon-theme; + name = "Papirus-Dark"; + }; - bibata-cursors = { - package = pkgs.bibata-cursors; - name = "Bibata-Modern-Ice"; - }; + bibata-cursors = { + package = pkgs.bibata-cursors; + name = "Bibata-Modern-Ice"; + }; }; pick = key: - if key == null then - throw "lightdm: missing required key in ${toString greeterConfPath}" - else if !(pkgMap ? "${key}") then - throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" - else - pkgMap."${key}"; + if key == null then + throw "lightdm: missing required key in ${toString greeterConfPath}" + else if !(pkgMap ? "${key}") then + throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" + else + pkgMap."${key}"; themeSel = pick themePkgKey; - iconSel = pick iconPkgKey; + iconSel = pick iconPkgKey; cursorSel = pick cursorPkgKey; # Rewrite greeter.conf so LightDM sees REAL names, not package keys. # Also force background to lockPng. - greeterFixed = - '' - [greeter] - theme-name = ${themeSel.name} - icon-theme-name = ${iconSel.name} - cursor-theme-name = ${cursorSel.name} - ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} - '' - + "\n" - + greeterRaw; + greeterFixed = + '' + [greeter] + theme-name = ${themeSel.name} + icon-theme-name = ${iconSel.name} + cursor-theme-name = ${cursorSel.name} + ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} + '' + + "\n" + + greeterRaw; in { services.greetd.enable = false; services.xserver = { + enable = true; + desktopManager.xterm.enable = false; + + displayManager.lightdm = { + enable = true; + background = lockPng; + + greeters.gtk = { enable = true; - desktopManager.xterm.enable = false; - displayManager.lightdm = { - enable = true; - background = lockPng; - - 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; + 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; + }; }; programs.hyprland.enable = true; # Optional: make them available system-wide as well environment.systemPackages = [ - themeSel.package - iconSel.package - cursorSel.package + themeSel.package + iconSel.package + cursorSel.package ]; } @@ -1316,30 +1316,30 @@ Along with that, a few other utilities like zip and enabling services to automou { pkgs, user, config, ... }: { environment.systemPackages = with pkgs; [ - zip - unzip - p7zip - usbutils - udiskie - file-roller + zip + unzip + p7zip + usbutils + udiskie + file-roller ]; programs.thunar = { - enable = true; - plugins = with pkgs; [ - thunar-archive-plugin - thunar-media-tags-plugin - thunar-volman - thunar-vcs-plugin - ]; + enable = true; + plugins = with pkgs; [ + thunar-archive-plugin + thunar-media-tags-plugin + thunar-volman + thunar-vcs-plugin + ]; }; programs.xfconf.enable = true; # to save thunar settings services = { - gvfs.enable = true; # Mount, trash, and other functionalities - tumbler.enable = true; # Thumbnail support for images - udisks2.enable = true; # Auto mount usb drives + gvfs.enable = true; # Mount, trash, and other functionalities + tumbler.enable = true; # Thumbnail support for images + udisks2.enable = true; # Auto mount usb drives }; } #+end_src @@ -1349,27 +1349,27 @@ I live in Netherlands and would like all my locale and timezone settings to matc #+begin_src nix :tangle configuration/core/locale.nix :noweb tangle :mkdirp yes { user, ... } : let - locale = user.locale; - defaultLocale = "nl_NL.UTF-8"; + locale = user.locale; + defaultLocale = "nl_NL.UTF-8"; in { - # Set your time zone. - time.timeZone = "Europe/Amsterdam"; + # Set your time zone. + time.timeZone = "Europe/Amsterdam"; - # Select internationalisation properties. - i18n.defaultLocale = defaultLocale; + # Select internationalisation properties. + i18n.defaultLocale = defaultLocale; - i18n.extraLocaleSettings = { - LC_ADDRESS = locale; - LC_IDENTIFICATION = locale; - LC_MEASUREMENT = locale; - LC_MONETARY = locale; - LC_NAME = locale; - LC_NUMERIC = locale; - LC_PAPER = locale; - LC_TELEPHONE = locale; - LC_TIME = defaultLocale; - }; + i18n.extraLocaleSettings = { + LC_ADDRESS = locale; + LC_IDENTIFICATION = locale; + LC_MEASUREMENT = locale; + LC_MONETARY = locale; + LC_NAME = locale; + LC_NUMERIC = locale; + LC_PAPER = locale; + LC_TELEPHONE = locale; + LC_TIME = defaultLocale; + }; } #+end_src @@ -1379,21 +1379,21 @@ Not much to see here. I want networking to be enabled. I want firewall as well. { pkgs, lib, ... }: { networking = { - useDHCP = lib.mkDefault true; - networkmanager.enable = true; - networkmanager.wifi.backend = "iwd"; - wireless.iwd.enable = true; - wireless.userControlled.enable = true; - firewall = { - enable = true; - # KDE Connect: discovery + encrypted connections - allowedTCPPortRanges = [ - { from = 1714; to = 1764; } - ]; - allowedUDPPortRanges = [ - { from = 1714; to = 1764; } - ]; - }; + useDHCP = lib.mkDefault true; + networkmanager.enable = true; + networkmanager.wifi.backend = "iwd"; + wireless.iwd.enable = true; + wireless.userControlled.enable = true; + firewall = { + enable = true; + # KDE Connect: discovery + encrypted connections + allowedTCPPortRanges = [ + { from = 1714; to = 1764; } + ]; + allowedUDPPortRanges = [ + { from = 1714; to = 1764; } + ]; + }; }; environment.systemPackages = with pkgs; [ impala ]; } @@ -1406,56 +1406,56 @@ The configuration is done in the home manager section. { pkgs, ... }: { nix.settings = { - substituters = [ "https://hyprland.cachix.org" ]; - trusted-public-keys = [ - "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" - ]; + substituters = [ "https://hyprland.cachix.org" ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + ]; }; services.dbus.enable = true; security.polkit.enable = true; services.flatpak.enable = true; services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - wireplumber.enable = true; + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + wireplumber.enable = true; }; services.gvfs.enable = true; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-hyprland - xdg-desktop-portal-gtk - ]; - config.common.default = [ "hyprland" "gtk" ]; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + xdg-desktop-portal-gtk + ]; + config.common.default = [ "hyprland" "gtk" ]; }; environment.systemPackages = with pkgs; [ - walker - uwsm - hyprland-qtutils - hyprpolkitagent - grimblast + walker + uwsm + hyprland-qtutils + hyprpolkitagent + grimblast ]; programs = { - uwsm.enable = true; - uwsm.waylandCompositors.hyprland = { - prettyName = "Hyprland"; - comment = "Hyprland compositor managed by UWSM"; - binPath = "/run/current-system/sw/bin/Hyprland"; - }; - hyprland = { - withUWSM = true; - enable = true; - xwayland.enable = true; - }; + uwsm.enable = true; + uwsm.waylandCompositors.hyprland = { + prettyName = "Hyprland"; + comment = "Hyprland compositor managed by UWSM"; + binPath = "/run/current-system/sw/bin/Hyprland"; + }; + hyprland = { + withUWSM = true; + enable = true; + xwayland.enable = true; + }; }; environment.sessionVariables = { - XDG_SESSION_TYPE = "wayland"; - XDG_CURRENT_DESKTOP = "Hyprland"; - XDG_SESSION_DESKTOP = "Hyprland"; - NIXOS_OZONE_WL = "1"; - XCURSOR_SIZE = "24"; + XDG_SESSION_TYPE = "wayland"; + XDG_CURRENT_DESKTOP = "Hyprland"; + XDG_SESSION_DESKTOP = "Hyprland"; + NIXOS_OZONE_WL = "1"; + XCURSOR_SIZE = "24"; }; security.pam.services.hyprlock = { }; # Optional; GNOME-specific (keep only if you really use gnome-keyring integration) @@ -1470,26 +1470,26 @@ These are some of the services that I enable at the system level. Explanation in #+begin_src nix :tangle configuration/services/services.nix :noweb tangle :mkdirp yes { user, ...} : { - services = { - blueman.enable = true; # bluetooth manager - fwupd.enable = true; # firmware updating service - fstrim.enable = true; # ssd maintenance service - thermald.enable = true; # thermal regulation service - printing.enable = true; # printing services, cups - gnome.gnome-keyring.enable = true; # keyring - flatpak.enable = true; # allow installing things from flatpaks - #flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + services = { + blueman.enable = true; # bluetooth manager + fwupd.enable = true; # firmware updating service + fstrim.enable = true; # ssd maintenance service + thermald.enable = true; # thermal regulation service + printing.enable = true; # printing services, cups + gnome.gnome-keyring.enable = true; # keyring + flatpak.enable = true; # allow installing things from flatpaks + #flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo - # printer discovery - avahi = { - enable = true; - nssmdns4 = true; - openFirewall = true; - }; - }; + # printer discovery + avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + }; - virtualisation.docker.enable = true; # enable docker - users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group + virtualisation.docker.enable = true; # enable docker + users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group } #+end_src @@ -1499,21 +1499,21 @@ These are some of the services that I enable at the system level. Explanation in { environment.systemPackages = with pkgs; [ - pipewire - wireplumber - alsa-utils - pulseaudio - pamixer - pavucontrol + pipewire + wireplumber + alsa-utils + pulseaudio + pamixer + pavucontrol ]; services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - wireplumber.enable = true; + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber.enable = true; }; security.rtkit.enable = true; @@ -1523,46 +1523,46 @@ These are some of the services that I enable at the system level. Explanation in # Prefer analog over HDMI/DP in a machine-agnostic way services.pipewire.wireplumber.extraConfig."51-audio-priorities" = { - "monitor.alsa.rules" = [ - # De-prioritize HDMI / DisplayPort sinks - { - matches = [ - { "node.name" = "~alsa_output\\..*HDMI.*"; } - { "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; - }; - } + "monitor.alsa.rules" = [ + # De-prioritize HDMI / DisplayPort sinks + { + matches = [ + { "node.name" = "~alsa_output\\..*HDMI.*"; } + { "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; + }; + } + ]; }; # Optional: clear "sticky" user-selected defaults so priority rules win 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" ]; - partOf = [ "wireplumber.service" ]; - wantedBy = [ "default.target" ]; + after = [ "wireplumber.service" ]; + partOf = [ "wireplumber.service" ]; + wantedBy = [ "default.target" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes"; - }; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes"; + }; }; } #+end_src @@ -1572,8 +1572,8 @@ Nothing much to see here. I love [[https://protesilaos.com/codelog/2025-02-12-ap #+name: config-fonts #+begin_src nix fonts.packages = with pkgs; [ - aporetic - nerd-fonts.iosevka + aporetic + nerd-fonts.iosevka ]; #+end_src @@ -1582,14 +1582,14 @@ This creates the user profile that I login with. Initially created during instal #+name: config-user #+begin_src nix users.users.${user.username} = { - isNormalUser = true; - description = "henrov"; - extraGroups = [ - "networkmanager" # allow editing network connections - "wheel" # can do sudo - "scanner" # access to the network scanner - "lp" # access to the printer - ]; + isNormalUser = true; + description = "henrov"; + extraGroups = [ + "networkmanager" # allow editing network connections + "wheel" # can do sudo + "scanner" # access to the network scanner + "lp" # access to the printer + ]; }; #+end_src @@ -1604,36 +1604,36 @@ This module will import all necessities. #+begin_src nix :tangle home/default.nix :noweb tangle :mkdirp yes { pkgs, user, ... } : { - imports = [ - ./apps/ollama.nix - #./apps/default-apps.nix - ./apps/theme.nix - ./desktop/hypridle.nix - ./desktop/hyprland.nix - ./desktop/hyprexpo.nix - ./desktop/hyprlock.nix - ./desktop/hyprscrolling.nix - ./desktop/hyprshell.nix - ./desktop/ncsway.nix - ./desktop/powermenu.nix - #./desktop/animated_wallpaper.nix - #./desktop/rotating_wallpaper.nix - ./desktop/workspace_wallpaper.nix - ./desktop/waybar.nix - ./desktop/walker.nix - ./dev/dev.nix - ./dev/kitty.nix - ./dev/shells.nix - ./dev/starship.nix - ./dev/zsh.nix - ./dev/emacs - ]; + imports = [ + ./apps/ollama.nix + #./apps/default-apps.nix + ./apps/theme.nix + ./desktop/hypridle.nix + ./desktop/hyprland.nix + ./desktop/hyprexpo.nix + ./desktop/hyprlock.nix + ./desktop/hyprscrolling.nix + ./desktop/hyprshell.nix + ./desktop/ncsway.nix + ./desktop/powermenu.nix + #./desktop/animated_wallpaper.nix + #./desktop/rotating_wallpaper.nix + ./desktop/workspace_wallpaper.nix + ./desktop/waybar.nix + ./desktop/walker.nix + ./dev/dev.nix + ./dev/kitty.nix + ./dev/shells.nix + ./dev/starship.nix + ./dev/zsh.nix + ./dev/emacs + ]; - <> + <> - <> + <> - programs.home-manager.enable = true; + programs.home-manager.enable = true; } #+end_src @@ -1650,9 +1650,9 @@ in { services.ollama = { - enable = true; - package = pkgs.ollama; - environmentVariables = envVars; + enable = true; + package = pkgs.ollama; + environmentVariables = envVars; }; } @@ -1665,14 +1665,15 @@ Creates a script for a powermenu { config, lib, pkgs, flakeRoot, ... }: let repoScript = - flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh"; + flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh"; targetRel = "hypr/scripts/powermenu.sh"; in { # Ensure script exists in ~/.config/hypr/scripts/ xdg.configFile."${targetRel}" = { - source = repoScript; - executable = true; + source = lib.mkForce repoScript; + backup = lib.mkForce false; + executable = true; }; } #+end_src @@ -1690,45 +1691,45 @@ let userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4"; # (keep your existing approach: sync the repo wallpaper dir to the user dir) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: true; + src = repoWallpaperDir; + filter = path: type: true; }; in { home.packages = [ - pkgs.mpvpaper - pkgs.mpv + pkgs.mpvpaper + pkgs.mpv ]; # Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; systemd.user.services.mpvpaper-wallpaper = { - Unit = { - Description = "Video wallpaper (mpvpaper)"; - After = [ "graphical-session.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - Service = { - Type = "simple"; - # -p auto-pause saves resources when the wallpaper surface is hidden. - # '*' applies to all outputs. - # Stretch-to-fill (cover) behavior: - # --panscan=1.0 fills the entire output by cropping (no letterboxing). - # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. - ExecStart = '' - ${pkgs.mpvpaper}/bin/mpvpaper \ - -p \ - -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ - '*' "${userVideoPath}" - ''; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Video wallpaper (mpvpaper)"; + After = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "simple"; + # -p auto-pause saves resources when the wallpaper surface is hidden. + # '*' applies to all outputs. + # Stretch-to-fill (cover) behavior: + # --panscan=1.0 fills the entire output by cropping (no letterboxing). + # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. + ExecStart = '' + ${pkgs.mpvpaper}/bin/mpvpaper \ + -p \ + -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ + '*' "${userVideoPath}" + ''; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; } #+end_src @@ -1747,37 +1748,37 @@ let userConfPath = "${userAbsRoot}/wallpaper.conf"; # Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: - (builtins.baseNameOf path) != "wallpaper.conf"; + src = repoWallpaperDir; + filter = path: type: + (builtins.baseNameOf path) != "wallpaper.conf"; }; in { home.packages = [ pkgs.wpaperd ]; # Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; # Now safely overwrite the config every activation (no HM collision) home.activation.wallpaperConfForce = - lib.hm.dag.entryAfter [ "writeBoundary" ] '' - set -euo pipefail - mkdir -p "${userAbsRoot}" - install -m 0644 "${repoWallpaperConf}" "${userConfPath}" - ''; + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + set -euo pipefail + mkdir -p "${userAbsRoot}" + install -m 0644 "${repoWallpaperConf}" "${userConfPath}" + ''; systemd.user.services.wpaperd = { - Unit = { - Description = "wpaperd wallpaper daemon"; - After = [ "default.target" ]; - }; - Service = { - Type = "simple"; - ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install.WantedBy = [ "default.target" ]; + Unit = { + Description = "wpaperd wallpaper daemon"; + After = [ "default.target" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install.WantedBy = [ "default.target" ]; ; #+end_src @@ -1793,198 +1794,201 @@ let # (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper"; repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: true; + src = repoWallpaperDir; + filter = path: type: true; }; daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh"; - setRel = "hypr/scripts/set-wallpaper.sh"; + setRel = "hypr/scripts/set-wallpaper.sh"; in { home.packages = [ - pkgs.hyprpaper - pkgs.socat - pkgs.jq - pkgs.findutils - pkgs.coreutils - pkgs.gnused - pkgs.gawk + pkgs.hyprpaper + pkgs.socat + pkgs.jq + pkgs.findutils + pkgs.coreutils + pkgs.gnused + pkgs.gawk ]; # Keep your existing "sync wallpapers into a writable dir" pattern home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; # Hyprpaper config (hyprpaper reads this; it does NOT need to write it) # `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0} - xdg.configFile."hypr/hyprpaper.conf".text = '' - ipc = true - splash = false + xdg.configFile."hypr/hyprpaper.conf".text = lib.mkForce '' + ipc = true + splash = false ''; + xdg.configFile."hypr/hyprpaper.conf".backup = lib.mkForce false; # Workspace wallpaper daemon: listens to socket2, applies w-=... mapping # Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1} xdg.configFile."${daemonRel}" = { - executable = true; - text = '' - #!/usr/bin/env bash - set -euo pipefail - : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" - : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" - SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" - [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } - PICTURES_DIR="''${1:-${picturesDir}}" - FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2} - HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" - MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" - focused_monitor() { - hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 - } - map_file_for_monitor() { - local mon="''${1}" - echo "''${MAP_ROOT}/''${mon}/defaults.conf" - } - ensure_map_file() { - local mon="''${1}" - local f - f="$(map_file_for_monitor "''${mon}")" - mkdir -p "$(dirname "''${f}")" - if [[ ! -f "''${f}" ]]; then - # Seed with 1..9 from picturesDir if present, else empty entries - { - 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)" - echo "w-''${i}= ''${seed}" - done - } > "''${f}" - fi - echo "''${f}" - } - get_wall_for_ws() { - local mon="''${1}" - local wsid="''${2}" - local f key val - f="$(ensure_map_file "''${mon}")" - key="w-''${wsid}" - # accept "w-1=/path" or "w-1= /path" - val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)" - echo "''${val}" - } - apply_wallpaper() { - local mon="''${1}" - local wsid="''${2}" - local file - file="$(get_wall_for_ws "''${mon}" "''${wsid}")" - [[ -n "''${file}" ]] || return 0 - [[ -f "''${file}" ]] || return 0 - # Apply via IPC - # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3} - hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null - } - # Initial apply on startup - mon="$(focused_monitor || true)" - wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - handle() { - local line="''${1}" - case "''${line}" in - workspacev2* ) - # workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4} - local payload wsid - payload="''${line#*>>}" - wsid="''${payload%%,*}" - mon="$(focused_monitor || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - ;; - focusedmon* ) - # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5} - # When monitor focus changes, re-apply for the active workspace id. - mon="$(focused_monitor || true)" - wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - ;; - esac - } - socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do - handle "''${line}" || true - done - ''; + executable = true; + text = lib.mkForce '' + #!/usr/bin/env bash + set -euo pipefail + : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" + : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" + SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" + [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } + PICTURES_DIR="''${1:-${picturesDir}}" + FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2} + HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" + MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" + focused_monitor() { + hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 + } + map_file_for_monitor() { + local mon="''${1}" + echo "''${MAP_ROOT}/''${mon}/defaults.conf" + } + ensure_map_file() { + local mon="''${1}" + local f + f="$(map_file_for_monitor "''${mon}")" + mkdir -p "$(dirname "''${f}")" + if [[ ! -f "''${f}" ]]; then + # Seed with 1..9 from picturesDir if present, else empty entries + { + 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)" + echo "w-''${i}= ''${seed}" + done + } > "''${f}" + fi + echo "''${f}" + } + get_wall_for_ws() { + local mon="''${1}" + local wsid="''${2}" + local f key val + f="$(ensure_map_file "''${mon}")" + key="w-''${wsid}" + # accept "w-1=/path" or "w-1= /path" + val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)" + echo "''${val}" + } + apply_wallpaper() { + local mon="''${1}" + local wsid="''${2}" + local file + file="$(get_wall_for_ws "''${mon}" "''${wsid}")" + [[ -n "''${file}" ]] || return 0 + [[ -f "''${file}" ]] || return 0 + # Apply via IPC + # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3} + hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null + } + # Initial apply on startup + mon="$(focused_monitor || true)" + wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + handle() { + local line="''${1}" + case "''${line}" in + workspacev2* ) + # workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4} + local payload wsid + payload="''${line#*>>}" + wsid="''${payload%%,*}" + mon="$(focused_monitor || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + ;; + focusedmon* ) + # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5} + # When monitor focus changes, re-apply for the active workspace id. + mon="$(focused_monitor || true)" + wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + ;; + esac + } + socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do + handle "''${line}" || true + done + ''; + backup = lib.mkForce false; }; # CLI setter in the style of your inspiration script. # Usage: set-wallpaper.sh [wallpaper] xdg.configFile."${setRel}" = { - executable = true; - text = '' - #!/usr/bin/env bash - set -euo pipefail + executable = true; + text = lib.mkForce '' + #!/usr/bin/env bash + set -euo pipefail - HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" - MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" + HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" + MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" - usage() { - echo "Usage: set-wallpaper.sh [wallpaper_path]" - } + usage() { + echo "Usage: set-wallpaper.sh [wallpaper_path]" + } - wsid="''${1:-}" - mon="''${2:-}" - wp="''${3:-}" + wsid="''${1:-}" + mon="''${2:-}" + wp="''${3:-}" - [[ -n "''${wsid}" ]] || { usage; exit 1; } - [[ -n "''${mon}" ]] || { usage; exit 1; } + [[ -n "''${wsid}" ]] || { usage; exit 1; } + [[ -n "''${mon}" ]] || { usage; exit 1; } - cfg="''${MAP_ROOT}/''${mon}/defaults.conf" - mkdir -p "$(dirname "''${cfg}")" - [[ -f "''${cfg}" ]] || touch "''${cfg}" + cfg="''${MAP_ROOT}/''${mon}/defaults.conf" + mkdir -p "$(dirname "''${cfg}")" + [[ -f "''${cfg}" ]] || touch "''${cfg}" - if [[ -z "''${wp}" ]]; then - # 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)" - [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } - fi + if [[ -z "''${wp}" ]]; then + # 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)" + [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } + fi - # Ensure key exists; if not, append it - key="w-''${wsid}" - if ! grep -q "^''${key}=" "''${cfg}"; then - echo "''${key}=" >> "''${cfg}" - fi + # Ensure key exists; if not, append it + key="w-''${wsid}" + if ! grep -q "^''${key}=" "''${cfg}"; then + echo "''${key}=" >> "''${cfg}" + fi - # Set mapping - ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}" + # Set mapping + ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}" - # 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)" - if [[ "''${curws}" == "''${wsid}" ]]; then - hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null - fi - ''; + # 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)" + if [[ "''${curws}" == "''${wsid}" ]]; then + hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null + fi + ''; + backup = lib.mkForce false; }; # Services systemd.user.services.hyprpaper = { - Unit = { - Description = "hyprpaper wallpaper daemon"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Unit = { + Description = "hyprpaper wallpaper daemon"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; }; systemd.user.services.hyprpaper-ws-daemon = { - Unit = { - Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" "hyprpaper.service" ]; - }; - Service = { - ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Unit = { + Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" "hyprpaper.service" ]; + }; + Service = { + ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; }; } #+end_src @@ -2002,14 +2006,16 @@ in programs.waybar.enable = true; # Ensure config matches repo (HM-managed symlink, not user-editable) xdg.configFile."waybar/config" = { - source = repoWaybarDir + "/config.jsonc"; - force = true; + source = lib.mkForce repoWaybarDir + "/config.jsonc"; + backup = lib.mkForce false; + force = true; }; # Override HM's internally-generated waybar-style.css derivation # and use your repo file instead. xdg.configFile."waybar/style.css" = { - source = lib.mkForce (repoWaybarDir + "/style.css"); - force = true; + source = lib.mkForce (repoWaybarDir + "/style.css"); + backup = lib.mkForce false; + force = true; }; # 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) @@ -2024,13 +2030,15 @@ They are configured below. #+begin_src nix :tangle home/desktop/hyprlock.nix :noweb tangle :mkdirp yes {config, lib, pkgs, flakeRoot, ... }: let - lockPngSrc = flakeRoot + "/assets/lock.png"; + lockPngSrc = flakeRoot + "/assets/lock.png"; hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf"; in { home.packages = [ pkgs.hyprlock ]; - xdg.configFile."hypr/lock.png".source = lockPngSrc; - xdg.configFile."hypr/hyprlock.conf".source = hyprlockConf; + xdg.configFile."hypr/lock.png".source = lib.mkForce lockPngSrc; + 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; } #+end_src @@ -2043,7 +2051,8 @@ let in { 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 ; } #+end_src @@ -2063,38 +2072,41 @@ let targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh"; # Facilitate switching between scrolling and dwindle 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"; in { # Ensure deps for the script exist at runtime # (hyprctl comes with Hyprland; jq is often not installed by default) home.packages = with pkgs; [ - jq + jq ]; wayland.windowManager.hyprland = { - enable = true; - plugins = [ - pkgs.hyprlandPlugins.hyprscrolling - ]; - extraConfig = '' - source = ~/.config/${targetRel} - ''; + enable = true; + plugins = [ + pkgs.hyprlandPlugins.hyprscrolling + ]; + extraConfig = '' + source = ~/.config/${targetRel} + ''; }; # 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}" = { - source = repoOverflowScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoOverflowScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetPerMonitor}" = { - source = repoPerMonitorScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoPerMonitorScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetSwitchScript}" = { - source = repoSwitchScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoSwitchScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; } #+end_src @@ -2113,23 +2125,25 @@ in xdg.enable = true; home.packages = [ pkgs.hyprshell ]; # Link repo -> ~/.config/hyprshell/... - xdg.configFile."hyprshell/config.ron".source = cfgRon; - xdg.configFile."hyprshell/styles.css".source = cssFile; + xdg.configFile."hyprshell/config.ron".source = lib.mkForce cfgRon; + 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) systemd.user.services.hyprshell = { - Unit = { - Description = "Hyprshell (window switcher / launcher)"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Hyprshell (window switcher / launcher)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; } #+end_src @@ -2140,42 +2154,43 @@ This configures the desktop environment along with the peripherals. The comments #+begin_src nix :tangle home/desktop/hyprland.nix :noweb tangle :mkdirp yes. { config, lib, pkgs, flakeRoot, ... }: 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"; in { wayland.windowManager.hyprland = { - enable = true; - # Load base config + bindings from repo files - extraConfig = - (builtins.readFile hyprConf) - + "\n\n# --- Repo keybindings ---\n" - + (builtins.readFile bindingsConf) - + "\n"; - settings = { - windowrule = [ - "match:class nm-connection-editor, float 1, center 1, size 900 700" - ]; - }; + enable = true; + # Load base config + bindings from repo files + extraConfig = + (builtins.readFile hyprConf) + + "\n\n# --- Repo keybindings ---\n" + + (builtins.readFile bindingsConf) + + "\n"; + settings = { + windowrule = [ + "match:class nm-connection-editor, float 1, center 1, size 900 700" + ]; + }; }; xdg.configFile."hypr/scripts/lid-lock.sh" = { - source = flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh"; - executable = true; + source = lib.mkForce flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh"; + backup = lib.mkForce false; + executable = true; }; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-gtk - xdg-desktop-portal-hyprland - ]; - # GTK als algemene backend (OpenURI is daar betrouwbaar) - config.common.default = [ "gtk" ]; - # Hyprland alleen voor screensharing / remote desktop - config.hyprland = { - "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ]; - "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ]; - }; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-gtk + xdg-desktop-portal-hyprland + ]; + # GTK als algemene backend (OpenURI is daar betrouwbaar) + config.common.default = [ "gtk" ]; + # Hyprland alleen voor screensharing / remote desktop + config.hyprland = { + "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ]; + "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ]; + }; }; } #+end_src @@ -2186,13 +2201,13 @@ in { config, pkgs, lib, flakeRoot, inputs ? null, ... }: let walkerPkg = - if inputs != null && inputs ? walker - then inputs.walker.packages.${pkgs.system}.default - else pkgs.walker; + if inputs != null && inputs ? walker + then inputs.walker.packages.${pkgs.system}.default + else pkgs.walker; elephantPkg = - if inputs != null && inputs ? elephant - then inputs.elephant.packages.${pkgs.system}.default - else pkgs.elephant; + if inputs != null && inputs ? elephant + then inputs.elephant.packages.${pkgs.system}.default + else pkgs.elephant; sessionTarget = "graphical-session.target"; # All theme files now live here repoThemesDir = flakeRoot + "/assets/conf/desktop/walker"; @@ -2201,13 +2216,17 @@ in xdg.enable = true; home.packages = [ walkerPkg elephantPkg ]; # ~/.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".backup = lib.mkForce false; 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) systemd.user.services.elephant = { /* ... your existing service ... */ }; - systemd.user.services.walker = { /* ... your existing service ... */ }; + systemd.user.services.walker = { /* ... your existing service ... */ }; } #+end_src @@ -2217,25 +2236,25 @@ You'll notice the color values in multiple places outside this as well. #+begin_src nix :tangle home/apps/theme.nix :noweb tangle :mkdirp yes. { pkgs, ...}: { - gtk = { - enable = true; - colorScheme = "dark"; - theme = { - name = "Catppuccin-GTK-Grey-Dark-Compact"; - package = (pkgs.magnetic-catppuccin-gtk.override { - accent = [ "grey" ]; - shade = "dark"; - tweaks = [ "black" ]; - size = "compact"; - }); - }; - iconTheme.name = "Papirus-Dark"; - }; - catppuccin.enable = true; - catppuccin.flavor = "mocha"; - catppuccin.accent = "blue"; - catppuccin.gtk.icon.enable = true; - catppuccin.cursors.enable = true; + gtk = { + enable = true; + colorScheme = "dark"; + theme = { + name = "Catppuccin-GTK-Grey-Dark-Compact"; + package = (pkgs.magnetic-catppuccin-gtk.override { + accent = [ "grey" ]; + shade = "dark"; + tweaks = [ "black" ]; + size = "compact"; + }); + }; + iconTheme.name = "Papirus-Dark"; + }; + catppuccin.enable = true; + catppuccin.flavor = "mocha"; + catppuccin.accent = "blue"; + catppuccin.gtk.icon.enable = true; + catppuccin.cursors.enable = true; } #+end_src @@ -2246,9 +2265,9 @@ This is where you can set defaults { xdg.mimeApps.enable = true; xdg.mimeApps.defaultApplications = { - "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; - "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; - "text/html" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; + "text/html" = [ "app.zen_browser.zen.desktop" ]; }; } #+end_src @@ -2259,29 +2278,29 @@ hyprexpo gets installed and configured { config, lib, pkgs, ... }: { wayland.windowManager.hyprland = { - # Load the Hyprexpo plugin (from nixpkgs) - plugins = [ - pkgs.hyprlandPlugins.hyprexpo - ]; + # Load the Hyprexpo plugin (from nixpkgs) + plugins = [ + pkgs.hyprlandPlugins.hyprexpo + ]; - # Append plugin config + keybind after your existing hyprland.conf - extraConfig = lib.mkAfter '' - ############################ - # Hyprexpo (workspace/window overview) - ############################ + # Append plugin config + keybind after your existing hyprland.conf + extraConfig = lib.mkAfter '' + ############################ + # Hyprexpo (workspace/window overview) + ############################ - # Basic plugin config (tweak as you like) - plugin { - hyprexpo { - columns = 3 - gaps_in = 5 - gaps_out = 20 + # Basic plugin config (tweak as you like) + plugin { + hyprexpo { + columns = 3 + gaps_in = 5 + gaps_out = 20 - # Optional; comment out if you don't want it - # workspace_method = center current - } - } - ''; + # Optional; comment out if you don't want it + # workspace_method = center current + } + } + ''; }; } @@ -2299,6 +2318,7 @@ in programs.alacritty.enable = true; # Override the config generated by programs.alacritty xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf; + xdg.configFile."alacritty/alacritty.toml".backup = lib.mkForce false catppuccin.alacritty.enable = true; catppuccin.alacritty.flavor = "mocha"; } @@ -2310,43 +2330,43 @@ All the miscellaneous dev tools on this computer. { config, pkgs, lib, ... }: { programs = { - vscode.enable = true; - vim.enable = true; - ripgrep.enable = true; - btop.enable = true; - fzf = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - zoxide = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - eza = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - direnv = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - nix-direnv.enable = true; - }; - # Zsh-specific config belongs here - zsh = { + vscode.enable = true; + vim.enable = true; + ripgrep.enable = true; + btop.enable = true; + fzf = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + zoxide = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + eza = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + direnv = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + nix-direnv.enable = true; + }; + # Zsh-specific config belongs here + zsh = { # for emacs-eat package - initContent = lib.mkOrder 1200 '' - [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \ - source "$EAT_SHELL_INTEGRATION_DIR/zsh" - ''; - }; - git = { - enable = true; - lfs.enable = true; - }; + initContent = lib.mkOrder 1200 '' + [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \ + source "$EAT_SHELL_INTEGRATION_DIR/zsh" + ''; + }; + git = { + enable = true; + lfs.enable = true; + }; }; } #+end_src @@ -2357,30 +2377,31 @@ Kitty gets installed and configured { config, pkgs, lib, flakeRoot, ... }: let 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) repoKittyConfText = - builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf"); + builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf"); in { xdg.enable = true; # 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 = { - enable = true; - # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order: - # 1) include theme - # 2) your repo config (keymaps etc.) - # 3) force opacity LAST so it always wins - extraConfig = '' - # 1) Theme first (stable path) - include themes/Catppuccin-Mocha.conf - # 2) Your repo config (may also include theme; harmless if duplicated) - ${repoKittyConfText} - # 3) Force transparency last (wins) - #background_opacity 0.60 - #dynamic_background_opacity yes - ''; + enable = true; + # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order: + # 1) include theme + # 2) your repo config (keymaps etc.) + # 3) force opacity LAST so it always wins + extraConfig = '' + # 1) Theme first (stable path) + include themes/Catppuccin-Mocha.conf + # 2) Your repo config (may also include theme; harmless if duplicated) + ${repoKittyConfText} + # 3) Force transparency last (wins) + #background_opacity 0.60 + #dynamic_background_opacity yes + ''; }; } #+end_src @@ -2391,8 +2412,8 @@ The aliases mentioned in ./assets/conf/dev/terminal/shells.conf will be added to # shells.nix — Home-Manager module # # Reads: -# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf -# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf +# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf +# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf # # For each enabled shell in [enabled_shells]: # - installs/enables shell (where HM has an enable option) @@ -2413,53 +2434,53 @@ let readMaybe = p: if builtins.pathExists p then builtins.readFile p else ""; normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l); parseSections = text: - let - lines = map normalizeLine (lib.splitString "\n" text); - isHeader = l: - let s = l; - in lib.hasPrefix "[" s - && lib.hasSuffix "]" s - && builtins.stringLength s >= 3; - nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l); - folded = - builtins.foldl' - (st: l: - if l == "" then st else - if isHeader l then st // { current = nameOf l; } - else - let - cur = st.current; - prev = st.sections.${cur} or []; - in - st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; } - ) - { current = "__root__"; sections = {}; } - lines; - in - folded.sections; + let + lines = map normalizeLine (lib.splitString "\n" text); + isHeader = l: + let s = l; + in lib.hasPrefix "[" s + && lib.hasSuffix "]" s + && builtins.stringLength s >= 3; + nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l); + folded = + builtins.foldl' + (st: l: + if l == "" then st else + if isHeader l then st // { current = nameOf l; } + else + let + cur = st.current; + prev = st.sections.${cur} or []; + in + st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; } + ) + { current = "__root__"; sections = {}; } + lines; + in + folded.sections; enabledSections = parseSections (readMaybe enabledFile); - aliasSections = parseSections (readMaybe aliasesFile); + aliasSections = parseSections (readMaybe aliasesFile); # [enabled_shells] lines: key = yes/no enabledShells = - let - raw = enabledSections.enabled_shells or []; - parseKV = l: - let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l; - in if m == null then null else { - k = trim (builtins.elemAt m 0); - v = lib.toLower (trim (builtins.elemAt m 1)); - }; - kvs = builtins.filter (x: x != null) (map parseKV raw); - in - map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs); + let + raw = enabledSections.enabled_shells or []; + parseKV = l: + let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l; + in if m == null then null else { + k = trim (builtins.elemAt m 0); + v = lib.toLower (trim (builtins.elemAt m 1)); + }; + kvs = builtins.filter (x: x != null) (map parseKV raw); + in + map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs); shellEnabled = shell: builtins.elem shell enabledShells; # ---------- per-shell repo config file (.conf) ---------- shellConfPath = shell: terminalDir + "/${shell}.conf"; shellConfExists = shell: builtins.pathExists (shellConfPath shell); sourceIfExistsSh = p: '' - if [ -f "${toString p}" ]; then - source "${toString p}" - fi + if [ -f "${toString p}" ]; then + source "${toString p}" + fi ''; # ---------- aliases section helpers ---------- secLines = name: aliasSections.${name} or []; @@ -2470,55 +2491,55 @@ let fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish"; # Seeds (created once; user can edit afterwards) bashSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - # - ${secText "bash_zsh"} - ${secText "bash_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + # + ${secText "bash_zsh"} + ${secText "bash_specific"} + ''; zshSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - ${secText "bash_zsh"} - ${secText "zsh_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + ${secText "bash_zsh"} + ${secText "zsh_specific"} + ''; # Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is parsePosixAlias = l: + let + m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l; + in + if m == null then null else 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 - if m == null then null else - 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; }; + { inherit name; cmd = unquote; }; escapeForFish = s: - lib.replaceStrings - [ "\\" "\"" "$" "`" ] - [ "\\\\" "\\\"" "\\$" "\\`" ] - s; + lib.replaceStrings + [ "\\" "\"" "$" "`" ] + [ "\\\\" "\\\"" "\\$" "\\`" ] + s; fishTranslated = - let - parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh")); - in - lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed); + let + parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh")); + in + lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed); fishSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - status is-interactive; or exit - # Translated from [bash_zsh]: - ${fishTranslated} - # From [fish_specific]: - ${secText "fish_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + status is-interactive; or exit + # Translated from [bash_zsh]: + ${fishTranslated} + # From [fish_specific]: + ${secText "fish_specific"} + ''; in { xdg.enable = true; @@ -2527,71 +2548,71 @@ in programs.zsh.enable = shellEnabled "zsh"; programs.fish.enable = shellEnabled "fish"; home.packages = - (lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++ - (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]); + (lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++ + (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]); # Source per-shell repo config (if present) AND source the user alias file (if it exists). # Important: define each option only ONCE. programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))} - if [ -f "${bashAliasesPath}" ]; then - source "${bashAliasesPath}" - fi + ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))} + if [ -f "${bashAliasesPath}" ]; then + source "${bashAliasesPath}" + fi ''); programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))} - if [ -f "${zshAliasesPath}" ]; then - source "${zshAliasesPath}" - fi + ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))} + if [ -f "${zshAliasesPath}" ]; then + source "${zshAliasesPath}" + fi ''); programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "fish") '' - if test -f "${toString (shellConfPath "fish")}" - source "${toString (shellConfPath "fish")}" - end - ''} - if test -f "${fishAliasesPath}" - source "${fishAliasesPath}" - end + ${lib.optionalString (shellConfExists "fish") '' + if test -f "${toString (shellConfPath "fish")}" + source "${toString (shellConfPath "fish")}" + end + ''} + if test -f "${fishAliasesPath}" + source "${fishAliasesPath}" + end ''); # Create/remove alias files based on enabled shells home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] '' set -euo pipefail # bash ------------------------------------------------------- if ${if shellEnabled "bash" then "true" else "false"}; then - cat > "${bashAliasesPath}" <<'EOF' + cat > "${bashAliasesPath}" <<'EOF' ${bashSeed} EOF else - rm -f "${bashAliasesPath}" + rm -f "${bashAliasesPath}" fi # zsh ------------------------------------------------------- if ${if shellEnabled "zsh" then "true" else "false"}; then - cat > "${zshAliasesPath}" <<'EOF' + cat > "${zshAliasesPath}" <<'EOF' ${zshSeed} EOF else - rm -f "${zshAliasesPath}" + rm -f "${zshAliasesPath}" fi # fish ------------------------------------------------------- if ${if shellEnabled "fish" then "true" else "false"}; then - mkdir -p "$(dirname "${fishAliasesPath}")" - cat > "${fishAliasesPath}" <<'EOF' + mkdir -p "$(dirname "${fishAliasesPath}")" + cat > "${fishAliasesPath}" <<'EOF' ${fishSeed} EOF else - rm -f "${fishAliasesPath}" + rm -f "${fishAliasesPath}" fi - # fish - if ${if shellEnabled "fish" then "true" else "false"}; then - mkdir -p "$(dirname "${fishAliasesPath}")" - if [ ! -f "${fishAliasesPath}" ]; then - cat > "${fishAliasesPath}" <<'EOF' + # fish + if ${if shellEnabled "fish" then "true" else "false"}; then + mkdir -p "$(dirname "${fishAliasesPath}")" + if [ ! -f "${fishAliasesPath}" ]; then + cat > "${fishAliasesPath}" <<'EOF' ${fishSeed} EOF - fi - else - rm -f "${fishAliasesPath}" - fi + fi + else + rm -f "${fishAliasesPath}" + fi ''; } #+end_src @@ -2602,27 +2623,27 @@ Zsh gets installed and configured { config, pkgs, lib, flakeRoot, ... }: { programs.zsh = { - enable = true; - enableCompletion = true; - autocd = true; - # Optional but recommended: keep zsh config in one dir (relative to $HOME) - dotDir = ".config/zsh"; - oh-my-zsh = { - enable = true; - theme = ""; - plugins = [ - "git" - "sudo" - "extract" - "colored-man-pages" - "command-not-found" - "history" - "docker" - "kubectl" - ]; - }; - autosuggestion.enable = true; - syntaxHighlighting.enable = true; + enable = true; + enableCompletion = true; + autocd = true; + # Optional but recommended: keep zsh config in one dir (relative to $HOME) + dotDir = ".config/zsh"; + oh-my-zsh = { + enable = true; + theme = ""; + plugins = [ + "git" + "sudo" + "extract" + "colored-man-pages" + "command-not-found" + "history" + "docker" + "kubectl" + ]; + }; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; }; } #+end_src @@ -2642,10 +2663,10 @@ in xdg.enable = true; programs.starship = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - enableFishIntegration = true; + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + enableFishIntegration = true; }; # Force the *actual conflicting option* (home.file."".source) @@ -2672,70 +2693,70 @@ Comments describe the emacs package and what it does. #+begin_src nix :tangle home/dev/emacs/default.nix :noweb tangle :mkdirp yes { pkgs, ... }: { - programs.emacs = { - enable = true; - # install with tree sitter enabled - package = (pkgs.emacs-pgtk.override { withTreeSitter = true; }); - extraPackages = epkgs: [ - # also install all tree sitter grammars - epkgs.manualPackages.treesit-grammars.with-all-grammars - epkgs.nerd-icons # nerd fonts support - epkgs.doom-modeline # model line - epkgs.diminish # hides modes from modeline - epkgs.eldoc # doc support - epkgs.pulsar # pulses the cursor when jumping about - epkgs.which-key # help porcelain - epkgs.expreg # expand region - epkgs.vundo # undo tree - epkgs.puni # structured editing - epkgs.avy # jumping utility - epkgs.consult # emacs right click - epkgs.vertico # minibuffer completion - epkgs.marginalia # annotations for completions - epkgs.crux # utilities - epkgs.magit # git porcelain - epkgs.nerd-icons-corfu # nerd icons for completion - epkgs.corfu # completion - epkgs.cape # completion extensions - epkgs.orderless # search paradigm - epkgs.yasnippet # snippets support - epkgs.yasnippet-snippets # commonly used snippets - epkgs.rg # ripgrep - epkgs.exec-path-from-shell # load env and path - epkgs.eat # better shell - epkgs.rust-mode # rust mode (when rust-ts doesn't cut it) - epkgs.rustic # more rust things - epkgs.nix-mode # nix lang - epkgs.hcl-mode # hashicorp file mode - epkgs.shell-pop # quick shell popup - epkgs.envrc # support for loading .envrc - epkgs.nixpkgs-fmt # format nix files - epkgs.f # string + file utilities - epkgs.gptel # llm chat (mainly claude) - epkgs.catppuccin-theme # catppuccin theme - epkgs.eldoc-box # docs in a box - epkgs.sideline # 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 - ]; - }; - home.sessionVariables = { - EDITOR = "emacs"; - XDG_SCREENSHOTS_DIR = "~/screenshots"; - }; - home.file = { - emacs-init = { - source = ./early-init.el; - target = ".emacs.d/early-init.el"; - }; - emacs = { - source = ./init.el; - target = ".emacs.d/init.el"; - }; - }; - services.nextcloud-client = { - enable = true; - }; + programs.emacs = { + enable = true; + # install with tree sitter enabled + package = (pkgs.emacs-pgtk.override { withTreeSitter = true; }); + extraPackages = epkgs: [ + # also install all tree sitter grammars + epkgs.manualPackages.treesit-grammars.with-all-grammars + epkgs.nerd-icons # nerd fonts support + epkgs.doom-modeline # model line + epkgs.diminish # hides modes from modeline + epkgs.eldoc # doc support + epkgs.pulsar # pulses the cursor when jumping about + epkgs.which-key # help porcelain + epkgs.expreg # expand region + epkgs.vundo # undo tree + epkgs.puni # structured editing + epkgs.avy # jumping utility + epkgs.consult # emacs right click + epkgs.vertico # minibuffer completion + epkgs.marginalia # annotations for completions + epkgs.crux # utilities + epkgs.magit # git porcelain + epkgs.nerd-icons-corfu # nerd icons for completion + epkgs.corfu # completion + epkgs.cape # completion extensions + epkgs.orderless # search paradigm + epkgs.yasnippet # snippets support + epkgs.yasnippet-snippets # commonly used snippets + epkgs.rg # ripgrep + epkgs.exec-path-from-shell # load env and path + epkgs.eat # better shell + epkgs.rust-mode # rust mode (when rust-ts doesn't cut it) + epkgs.rustic # more rust things + epkgs.nix-mode # nix lang + epkgs.hcl-mode # hashicorp file mode + epkgs.shell-pop # quick shell popup + epkgs.envrc # support for loading .envrc + epkgs.nixpkgs-fmt # format nix files + epkgs.f # string + file utilities + epkgs.gptel # llm chat (mainly claude) + epkgs.catppuccin-theme # catppuccin theme + epkgs.eldoc-box # docs in a box + epkgs.sideline # 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 + ]; + }; + home.sessionVariables = { + EDITOR = "emacs"; + XDG_SCREENSHOTS_DIR = "~/screenshots"; + }; + home.file = { + emacs-init = { + source = ./early-init.el; + target = ".emacs.d/early-init.el"; + }; + emacs = { + source = ./init.el; + target = ".emacs.d/init.el"; + }; + }; + services.nextcloud-client = { + enable = true; + }; } #+end_src @@ -2751,498 +2772,498 @@ These are listed here. ;;; Code: (set-language-environment "UTF-8") (setq-default - default-frame-alist - '((background-color . "#1e1e2e") - (bottom-divider-width . 1) ; Thin horizontal window divider - (foreground-color . "#bac2de") ; Default foreground color - (fullscreen . maximized) ; Maximize the window by default - (horizontal-scroll-bars . nil) ; No horizontal scroll-bars - (left-fringe . 8) ; Thin left fringe - (menu-bar-lines . 0) ; No menu bar - (right-divider-width . 1) ; Thin vertical window divider - (right-fringe . 8) ; Thin right fringe - (tool-bar-lines . 0) ; No tool bar - (undecorated . t) ; Remove extraneous X decorations - (vertical-scroll-bars . nil)) ; No vertical scroll-bars - user-full-name "Henrov henrov" ; ME! - ;; memory configuration - ;; Higher garbage collection threshold, prevents frequent gc locks, reset later - gc-cons-threshold most-positive-fixnum - ;; Ignore warnings for (obsolete) elisp compilations - byte-compile-warnings '(not obsolete) - ;; And other log types completely - warning-suppress-log-types '((comp) (bytecomp)) - ;; Large files are okay in the new millenium. - large-file-warning-threshold 100000000 - ;; dont show garbage collection messages at startup, will reset later - garbage-collection-messages nil - ;; native compilation - package-native-compile t - native-comp-warning-on-missing-source nil - native-comp-async-report-warnings-errors 'silent - ;; Read more based on system pipe capacity - read-process-output-max (max (* 10240 10240) read-process-output-max) - ;; scroll configuration - scroll-margin 0 ; Lets scroll to the end of the margin - scroll-conservatively 100000 ; Never recenter the window - scroll-preserve-screen-position 1 ; Scrolling back and forth - ;; frame config - ;; Improve emacs startup time by not resizing to adjust for custom settings - frame-inhibit-implied-resize t - ;; Dont resize based on character height / width but to exact pixels - frame-resize-pixelwise t - ;; backups & files - backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter - backup-by-copying t ; Don't clobber symlinks - create-lockfiles nil ; Don't have temp files - delete-old-versions t ; Cleanup automatically - kept-new-versions 6 ; Update every few times - kept-old-versions 2 ; And cleanup even more - version-control t ; Version them backups - delete-by-moving-to-trash t ; Dont delete, send to trash instead - ;; startup - inhibit-startup-screen t ; I have already done the tutorial. Twice - inhibit-startup-message t ; I know I am ready - inhibit-startup-echo-area-message t ; Yep, still know it - initial-scratch-message nil ; I know it is the scratch buffer! - initial-buffer-choice nil - inhibit-startup-buffer-menu t - inhibit-x-resources t - initial-major-mode 'fundamental-mode - pgtk-wait-for-event-timeout 0.001 ; faster child frames - ad-redefinition-action 'accept ; dont care about legacy things being redefined - inhibit-compacting-font-caches t - ;; tabs - tab-width 4 ; Always tab 4 spaces. - indent-tabs-mode nil ; Never use actual tabs. - ;; rendering - cursor-in-non-selected-windows nil ; dont render cursors other windows - ;; packages - use-package-always-defer t - load-prefer-newer t - default-input-method nil - use-dialog-box nil - use-file-dialog nil - use-package-expand-minimally t - package-enable-at-startup nil - use-package-enable-imenu-support t - auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist. - package-archives '(("melpa" . "https://melpa.org/packages/") - ("gnu" . "https://elpa.gnu.org/packages/") - ("nongnu" . "https://elpa.nongnu.org/nongnu/") - ("melpa-stable" . "https://stable.melpa.org/packages/")) - package-archive-priorities '(("gnu" . 99) - ("nongnu" . 80) - ("melpa" . 70) - ("melpa-stable" . 50)) - ) - ;;; early-init.el ends here + default-frame-alist + '((background-color . "#1e1e2e") + (bottom-divider-width . 1) ; Thin horizontal window divider + (foreground-color . "#bac2de") ; Default foreground color + (fullscreen . maximized) ; Maximize the window by default + (horizontal-scroll-bars . nil) ; No horizontal scroll-bars + (left-fringe . 8) ; Thin left fringe + (menu-bar-lines . 0) ; No menu bar + (right-divider-width . 1) ; Thin vertical window divider + (right-fringe . 8) ; Thin right fringe + (tool-bar-lines . 0) ; No tool bar + (undecorated . t) ; Remove extraneous X decorations + (vertical-scroll-bars . nil)) ; No vertical scroll-bars + user-full-name "Henrov henrov" ; ME! + ;; memory configuration + ;; Higher garbage collection threshold, prevents frequent gc locks, reset later + gc-cons-threshold most-positive-fixnum + ;; Ignore warnings for (obsolete) elisp compilations + byte-compile-warnings '(not obsolete) + ;; And other log types completely + warning-suppress-log-types '((comp) (bytecomp)) + ;; Large files are okay in the new millenium. + large-file-warning-threshold 100000000 + ;; dont show garbage collection messages at startup, will reset later + garbage-collection-messages nil + ;; native compilation + package-native-compile t + native-comp-warning-on-missing-source nil + native-comp-async-report-warnings-errors 'silent + ;; Read more based on system pipe capacity + read-process-output-max (max (* 10240 10240) read-process-output-max) + ;; scroll configuration + scroll-margin 0 ; Lets scroll to the end of the margin + scroll-conservatively 100000 ; Never recenter the window + scroll-preserve-screen-position 1 ; Scrolling back and forth + ;; frame config + ;; Improve emacs startup time by not resizing to adjust for custom settings + frame-inhibit-implied-resize t + ;; Dont resize based on character height / width but to exact pixels + frame-resize-pixelwise t + ;; backups & files + backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter + backup-by-copying t ; Don't clobber symlinks + create-lockfiles nil ; Don't have temp files + delete-old-versions t ; Cleanup automatically + kept-new-versions 6 ; Update every few times + kept-old-versions 2 ; And cleanup even more + version-control t ; Version them backups + delete-by-moving-to-trash t ; Dont delete, send to trash instead + ;; startup + inhibit-startup-screen t ; I have already done the tutorial. Twice + inhibit-startup-message t ; I know I am ready + inhibit-startup-echo-area-message t ; Yep, still know it + initial-scratch-message nil ; I know it is the scratch buffer! + initial-buffer-choice nil + inhibit-startup-buffer-menu t + inhibit-x-resources t + initial-major-mode 'fundamental-mode + pgtk-wait-for-event-timeout 0.001 ; faster child frames + ad-redefinition-action 'accept ; dont care about legacy things being redefined + inhibit-compacting-font-caches t + ;; tabs + tab-width 4 ; Always tab 4 spaces. + indent-tabs-mode nil ; Never use actual tabs. + ;; rendering + cursor-in-non-selected-windows nil ; dont render cursors other windows + ;; packages + use-package-always-defer t + load-prefer-newer t + default-input-method nil + use-dialog-box nil + use-file-dialog nil + use-package-expand-minimally t + package-enable-at-startup nil + use-package-enable-imenu-support t + auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist. + package-archives '(("melpa" . "https://melpa.org/packages/") + ("gnu" . "https://elpa.gnu.org/packages/") + ("nongnu" . "https://elpa.nongnu.org/nongnu/") + ("melpa-stable" . "https://stable.melpa.org/packages/")) + package-archive-priorities '(("gnu" . 99) + ("nongnu" . 80) + ("melpa" . 70) + ("melpa-stable" . 50)) + ) + ;;; early-init.el ends here #+end_src ** Initialization Now starts the main emacs configuration. #+begin_src emacs-lisp :tangle home/dev/emacs/init.el :mkdirp yes - ;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*- + ;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*- - ;;; Commentary: - ;;; Simple Emacs setup I carry everywhere + ;;; Commentary: + ;;; Simple Emacs setup I carry everywhere - ;;; Code: + ;;; Code: (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) (package-initialize) (defun reset-custom-vars () - "Resets the custom variables that were set to crazy numbers" - (setopt gc-cons-threshold (* 1024 1024 100)) - (setopt garbage-collection-messages t)) + "Resets the custom variables that were set to crazy numbers" + (setopt gc-cons-threshold (* 1024 1024 100)) + (setopt garbage-collection-messages t)) (use-package emacs - :custom - (native-comp-async-query-on-exit t) - (read-answer-short t) - (use-short-answers t) - (enable-recursive-minibuffers t) - (which-func-update-delay 1.0) - (visible-bell nil) - (custom-buffer-done-kill t) - (whitespace-line-column nil) - (x-underline-at-descent-line t) - (imenu-auto-rescan t) - (uniquify-buffer-name-style 'forward) - (confirm-nonexistent-file-or-buffer nil) - (create-lockfiles nil) - (make-backup-files nil) - (kill-do-not-save-duplicates t) - (sentence-end-double-space nil) - (treesit-enabled-modes t) - :init - ;; base visual - (menu-bar-mode -1) ;; no menu bar - (toggle-scroll-bar -1) ;; no scroll bar - (tool-bar-mode -1) ;; no tool bar either - (blink-cursor-mode -1) ;; stop blinking + :custom + (native-comp-async-query-on-exit t) + (read-answer-short t) + (use-short-answers t) + (enable-recursive-minibuffers t) + (which-func-update-delay 1.0) + (visible-bell nil) + (custom-buffer-done-kill t) + (whitespace-line-column nil) + (x-underline-at-descent-line t) + (imenu-auto-rescan t) + (uniquify-buffer-name-style 'forward) + (confirm-nonexistent-file-or-buffer nil) + (create-lockfiles nil) + (make-backup-files nil) + (kill-do-not-save-duplicates t) + (sentence-end-double-space nil) + (treesit-enabled-modes t) + :init + ;; base visual + (menu-bar-mode -1) ;; no menu bar + (toggle-scroll-bar -1) ;; no scroll bar + (tool-bar-mode -1) ;; no tool bar either + (blink-cursor-mode -1) ;; stop blinking - ;; font of the century - (set-frame-font "Aporetic Sans Mono 12" nil t) + ;; font of the century + (set-frame-font "Aporetic Sans Mono 12" nil t) - :bind - (("C-" . pixel-scroll-precision) ; dont zoom in please, just scroll - ("C-" . pixel-scroll-precision) ; dont zoom in either, just scroll - ("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask - :hook - (text-mode . delete-trailing-whitespace-mode) - (prog-mode . delete-trailing-whitespace-mode) - (after-init . global-display-line-numbers-mode) ;; always show line numbers - (after-init . column-number-mode) ;; column number in the mode line - (after-init . size-indication-mode) ;; file size in the mode line - (after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll - (after-init . electric-pair-mode) ;; i mean ... parens should auto create - (after-init . reset-custom-vars) - ) + :bind + (("C-" . pixel-scroll-precision) ; dont zoom in please, just scroll + ("C-" . pixel-scroll-precision) ; dont zoom in either, just scroll + ("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask + :hook + (text-mode . delete-trailing-whitespace-mode) + (prog-mode . delete-trailing-whitespace-mode) + (after-init . global-display-line-numbers-mode) ;; always show line numbers + (after-init . column-number-mode) ;; column number in the mode line + (after-init . size-indication-mode) ;; file size in the mode line + (after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll + (after-init . electric-pair-mode) ;; i mean ... parens should auto create + (after-init . reset-custom-vars) + ) (use-package autorevert - :ensure nil - :custom - (auto-revert-interval 3) - (auto-revert-remote-files nil) - (auto-revert-use-notify t) - (auto-revert-avoid-polling nil) - (auto-revert-verbose t) - :hook - (after-init . global-auto-revert-mode)) + :ensure nil + :custom + (auto-revert-interval 3) + (auto-revert-remote-files nil) + (auto-revert-use-notify t) + (auto-revert-avoid-polling nil) + (auto-revert-verbose t) + :hook + (after-init . global-auto-revert-mode)) (use-package recentf - :ensure nil - :commands (recentf-mode recentf-cleanup) - :hook - (after-init . recentf-mode) - :custom - (recentf-auto-cleanup 'never) - (recentf-exclude - (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$" - "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$" - "\\.7z$" "\\.rar$" - "COMMIT_EDITMSG\\'" - "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$" - "-autoloads\\.el$" "autoload\\.el$")) + :ensure nil + :commands (recentf-mode recentf-cleanup) + :hook + (after-init . recentf-mode) + :custom + (recentf-auto-cleanup 'never) + (recentf-exclude + (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$" + "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$" + "\\.7z$" "\\.rar$" + "COMMIT_EDITMSG\\'" + "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$" + "-autoloads\\.el$" "autoload\\.el$")) - :config - ;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before - ;; `recentf-save-list', allowing stale entries to be removed before the list - ;; is saved by `recentf-save-list', which is automatically added to - ;; `kill-emacs-hook' by `recentf-mode'. - (add-hook 'kill-emacs-hook #'recentf-cleanup -90)) + :config + ;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before + ;; `recentf-save-list', allowing stale entries to be removed before the list + ;; is saved by `recentf-save-list', which is automatically added to + ;; `kill-emacs-hook' by `recentf-mode'. + (add-hook 'kill-emacs-hook #'recentf-cleanup -90)) (use-package savehist - :ensure nil - :commands (savehist-mode savehist-save) - :hook - (after-init . savehist-mode) - :custom - (savehist-autosave-interval 600) - (savehist-additional-variables - '(kill-ring ; clipboard - register-alist ; macros - mark-ring global-mark-ring ; marks - search-ring regexp-search-ring))) + :ensure nil + :commands (savehist-mode savehist-save) + :hook + (after-init . savehist-mode) + :custom + (savehist-autosave-interval 600) + (savehist-additional-variables + '(kill-ring ; clipboard + register-alist ; macros + mark-ring global-mark-ring ; marks + search-ring regexp-search-ring))) (use-package hl-line - :ensure nil - :custom - (hl-line-sticky-flag nil) - (global-hl-line-sticky-flag nil) - :hook - (after-init . global-hl-line-mode)) + :ensure nil + :custom + (hl-line-sticky-flag nil) + (global-hl-line-sticky-flag nil) + :hook + (after-init . global-hl-line-mode)) (use-package saveplace - :ensure nil - :commands (save-place-mode save-place-local-mode) - :hook - (after-init . save-place-mode) - :custom - (save-place-limit 400)) + :ensure nil + :commands (save-place-mode save-place-local-mode) + :hook + (after-init . save-place-mode) + :custom + (save-place-limit 400)) (use-package nerd-icons - :custom - ;; disable bright icon colors - (nerd-icons-color-icons nil))hells.nix + :custom + ;; disable bright icon colors + (nerd-icons-color-icons nil))hells.nix (use-package doom-modeline - :custom - (inhibit-compacting-font-caches t) ;; speed - (doom-modeline-buffer-file-name-style 'relative-from-project) - (doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you - (doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway - (doom-modeline-buffer-state-icon nil) ;; the filename already shows me - (doom-modeline-lsp nil) ;; lsp state is too distracting, too often - :hook (after-init . doom-modeline-mode)) + :custom + (inhibit-compacting-font-caches t) ;; speed + (doom-modeline-buffer-file-name-style 'relative-from-project) + (doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you + (doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway + (doom-modeline-buffer-state-icon nil) ;; the filename already shows me + (doom-modeline-lsp nil) ;; lsp state is too distracting, too often + :hook (after-init . doom-modeline-mode)) (load-theme 'catppuccin :no-confirm) - (use-package diminish :demand t) ;; declutter the modeline + (use-package diminish :demand t) ;; declutter the modeline (use-package eldoc - :diminish eldoc-mode - :custom - (eldoc-echo-area-use-multiline-p nil)) ;; docs for everything + :diminish eldoc-mode + :custom + (eldoc-echo-area-use-multiline-p nil)) ;; docs for everything (use-package eldoc-box - :defer t - :config - (set-face-background 'eldoc-box-border (catppuccin-color 'green)) - (set-face-background 'eldoc-box-body (catppuccin-color 'base)) - :bind - (("M-h" . eldoc-box-help-at-point))) + :defer t + :config + (set-face-background 'eldoc-box-border (catppuccin-color 'green)) + (set-face-background 'eldoc-box-body (catppuccin-color 'base)) + :bind + (("M-h" . eldoc-box-help-at-point))) (use-package pulsar - :commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry - :init - (defface pulsar-catppuccin - `((default :extend t) - (((class color) (min-colors 88) (background light)) - :background ,(catppuccin-color 'sapphire)) - (((class color) (min-colors 88) (background dark)) - :background ,(catppuccin-color 'sapphire)) - (t :inverse-video t)) - "Alternative nord face for `pulsar-face'." - :group 'pulsar-faces) - :custom - (pulsar-face 'pulsar-catppuccin) - :hook - (after-init . pulsar-global-mode)) + :commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry + :init + (defface pulsar-catppuccin + `((default :extend t) + (((class color) (min-colors 88) (background light)) + :background ,(catppuccin-color 'sapphire)) + (((class color) (min-colors 88) (background dark)) + :background ,(catppuccin-color 'sapphire)) + (t :inverse-video t)) + "Alternative nord face for `pulsar-face'." + :group 'pulsar-faces) + :custom + (pulsar-face 'pulsar-catppuccin) + :hook + (after-init . pulsar-global-mode)) (use-package which-key - :commands which-key-mode - :diminish which-key-mode - :hook - (after-init . which-key-mode)) + :commands which-key-mode + :diminish which-key-mode + :hook + (after-init . which-key-mode)) (use-package expreg - :bind ("M-m" . expreg-expand)) + :bind ("M-m" . expreg-expand)) (use-package vundo) ;; undo tree ;; better structured editing (use-package puni - :commands puni-global-mode - :hook - (after-init . puni-global-mode)) + :commands puni-global-mode + :hook + (after-init . puni-global-mode)) (use-package avy - :bind - ("M-i" . avy-goto-char-2) - :custom - (avy-background t)) + :bind + ("M-i" . avy-goto-char-2) + :custom + (avy-background t)) (use-package consult - :bind - ("C-x b" . consult-buffer) ;; orig. switch-to-buffer - ("M-y" . consult-yank-pop) ;; orig. yank-pop - ("M-g M-g" . consult-goto-line) ;; orig. goto-line - ("M-g i" . consult-imenu) ;; consult version is interactive - ("M-g r" . consult-ripgrep) ;; find in project also works - :custom - (consult-narrow-key "<")) + :bind + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g i" . consult-imenu) ;; consult version is interactive + ("M-g r" . consult-ripgrep) ;; find in project also works + :custom + (consult-narrow-key "<")) (use-package vertico - :commands vertico-mode - :custom - (read-file-name-completion-ignore-case t) - (read-buffer-completion-ignore-case t) - (completion-ignore-case t) - (enable-recursive-minibuffers t) - (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) - :init - (vertico-mode) - :hook - (minibuffer-setup-hook . cursor-intangible-mode)) + :commands vertico-mode + :custom + (read-file-name-completion-ignore-case t) + (read-buffer-completion-ignore-case t) + (completion-ignore-case t) + (enable-recursive-minibuffers t) + (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) + :init + (vertico-mode) + :hook + (minibuffer-setup-hook . cursor-intangible-mode)) (use-package marginalia - :commands marginalia-mode - :hook (after-init . marginalia-mode)) + :commands marginalia-mode + :hook (after-init . marginalia-mode)) (use-package crux - :bind - ("C-c M-e" . crux-find-user-init-file) - ("C-c C-w" . crux-transpose-windows) - ("C-c M-d" . crux-find-current-directory-dir-locals-file) - ("C-a" . crux-move-beginning-of-line)) + :bind + ("C-c M-e" . crux-find-user-init-file) + ("C-c C-w" . crux-transpose-windows) + ("C-c M-d" . crux-find-current-directory-dir-locals-file) + ("C-a" . crux-move-beginning-of-line)) (use-package magit - :bind (("C-M-g" . magit-status))) + :bind (("C-M-g" . magit-status))) (use-package nerd-icons-corfu - :commands nerd-icons-corfu-formatter - :defines corfu-margin-formatters) + :commands nerd-icons-corfu-formatter + :defines corfu-margin-formatters) (use-package corfu - :commands global-corfu-mode - :custom - (corfu-cycle t) - (corfu-auto t) - (corfu-auto-delay 1) - (corfu-auto-prefix 3) - (corfu-separator ?_) - :hook - (after-init . global-corfu-mode) - :config - (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) + :commands global-corfu-mode + :custom + (corfu-cycle t) + (corfu-auto t) + (corfu-auto-delay 1) + (corfu-auto-prefix 3) + (corfu-separator ?_) + :hook + (after-init . global-corfu-mode) + :config + (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (use-package cape) (use-package orderless - :custom - (completion-styles '(orderless partial-completion basic)) - (completion-category-defaults nil) - (completion-category-overrides nil)) + :custom + (completion-styles '(orderless partial-completion basic)) + (completion-category-defaults nil) + (completion-category-overrides nil)) (use-package yasnippet - :commands yas-global-mode - :diminish yas-minor-mode - :hook - (after-init . yas-global-mode)) + :commands yas-global-mode + :diminish yas-minor-mode + :hook + (after-init . yas-global-mode)) (use-package yasnippet-snippets :after yasnippet) (use-package exec-path-from-shell - :commands exec-path-from-shell-initialize - :custom - (exec-path-from-shell-arguments nil) - :hook - (after-init . exec-path-from-shell-initialize)) + :commands exec-path-from-shell-initialize + :custom + (exec-path-from-shell-arguments nil) + :hook + (after-init . exec-path-from-shell-initialize)) (use-package nixpkgs-fmt - :custom - (nixpkgs-fmt-command "nixfmt")) + :custom + (nixpkgs-fmt-command "nixfmt")) (use-package eat - :bind - (("C-c e p" . eat-project) - ("C-c e t" . eat))) + :bind + (("C-c e p" . eat-project) + ("C-c e t" . eat))) (use-package f :demand t) (use-package envrc - :commands envrc-global-mode - :hook - (after-init . envrc-global-mode)) + :commands envrc-global-mode + :hook + (after-init . envrc-global-mode)) (use-package gptel - :commands gptel-make-anthropic f-read-text - :config - (gptel-make-anthropic "Claude" - :stream t :key (f-read-text "/run/secrets/claude_key"))) + :commands gptel-make-anthropic f-read-text + :config + (gptel-make-anthropic "Claude" + :stream t :key (f-read-text "/run/secrets/claude_key"))) (use-package sideline-flymake) (use-package sideline-eglot) (use-package sideline - :custom - (sideline-backends-right '(sideline-flymake sideline-eglot)) - :hook - (eglot-managed-mode . sideline-mode) - (flymake-mode . sideline-mode)) + :custom + (sideline-backends-right '(sideline-flymake sideline-eglot)) + :hook + (eglot-managed-mode . sideline-mode) + (flymake-mode . sideline-mode)) (use-package eglot - :custom - (eglot-extend-to-xref t) - (eglot-ignored-server-capabilities '(:inlayHintProvider)) - (jsonrpc-event-hook nil) - :hook - (eglot-managed-mode . eldoc-box-hover-mode) - (before-save . eldoc-format-buffer) - :bind - (:map eglot-mode-map - ("C-c l a" . eglot-code-actions) - ("C-c l r" . eglot-rename) - ("C-c l h" . eldoc) - ("C-c l g" . xref-find-references) - ("C-c l w" . eglot-reconnect))) + :custom + (eglot-extend-to-xref t) + (eglot-ignored-server-capabilities '(:inlayHintProvider)) + (jsonrpc-event-hook nil) + :hook + (eglot-managed-mode . eldoc-box-hover-mode) + (before-save . eldoc-format-buffer) + :bind + (:map eglot-mode-map + ("C-c l a" . eglot-code-actions) + ("C-c l r" . eglot-rename) + ("C-c l h" . eldoc) + ("C-c l g" . xref-find-references) + ("C-c l w" . eglot-reconnect))) (use-package proced - :custom - (proced-auto-update-flag t) - (proced-auto-update-interval 3) - (proced-enable-color-flag t) - (proced-show-remote-processes t)) + :custom + (proced-auto-update-flag t) + (proced-auto-update-interval 3) + (proced-enable-color-flag t) + (proced-show-remote-processes t)) (use-package org - :ensure t - :defer t - :commands (org-mode org-capture org-agenda) - :init - (defvar org-journal-file "~/nextcloud/org/journal.org") - (defvar org-archive-file "~/nextcloud/org/archive.org") - (defvar org-notes-file "~/nextcloud/org/notes.org") - (defvar org-inbox-file "~/nextcloud/org/inbox.org") - (defvar org-work-file "~/nextcloud/org/work.org") - (defun my/org-capture-project-target-heading () - "Determine Org target headings from the current file's project path. + :ensure t + :defer t + :commands (org-mode org-capture org-agenda) + :init + (defvar org-journal-file "~/nextcloud/org/journal.org") + (defvar org-archive-file "~/nextcloud/org/archive.org") + (defvar org-notes-file "~/nextcloud/org/notes.org") + (defvar org-inbox-file "~/nextcloud/org/inbox.org") + (defvar org-work-file "~/nextcloud/org/work.org") + (defun my/org-capture-project-target-heading () + "Determine Org target headings from the current file's project path. - This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'. - It extracts 'COMPANY' and 'PROJECT' to use as nested headlines - for an Org capture template. + This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'. + It extracts 'COMPANY' and 'PROJECT' to use as nested headlines + for an Org capture template. - If the current buffer is not visi + If the current buffer is not visi ting a file within such a - project structure, it returns nil, causing capture to default to - the top of the file." - (when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer - (let ((path-parts (split-string path "/" t " "))) - (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=)) - (company (nth (+ 1 projects-pos) path-parts)) - (project (nth (+ 2 projects-pos) path-parts))) - ;; Return a list of headlines for Org to find or create. - (list company project))))) - :bind - (("C-c c" . org-capture) - ("C-c i" . org-store-link) - ("C-c a" . org-agenda) - :map org-mode-map - ("C-c t" . org-toggle-inline-images) - ("C-c l" . org-toggle-link-display)) - :custom - (org-agenda-files (list org-inbox-file org-journal-file)) - (org-directory "~/nextcloud/org") - (org-default-notes-file org-inbox-file) - (org-archive-location (concat org-archive-file "::* From %s")) - (org-log-done 'time) - (org-log-into-drawer t) - (org-hide-emphasis-markers t) - (org-src-fontify-natively t) - (org-src-tab-acts-natively t) - (org-capture-templates '(("t" "Todo" entry (file org-inbox-file) - "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)") - ("j" "Journal" entry (file+olp+datetree org-journal-file) - "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") - ("n" "Note" entry (file org-notes-file) - "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") - ("p" "Project Task" item - (file+function org-work-file my/org-capture-project-target-heading) - "* TODO %? \n CLOCK: %U" - )) - ) - :config - ;; Enable syntax highlighting in code blocks - (add-hook 'org-mode-hook 'turn-on-font-lock) - (add-hook 'org-mode-hook 'org-indent-mode)) + project structure, it returns nil, causing capture to default to + the top of the file." + (when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer + (let ((path-parts (split-string path "/" t " "))) + (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=)) + (company (nth (+ 1 projects-pos) path-parts)) + (project (nth (+ 2 projects-pos) path-parts))) + ;; Return a list of headlines for Org to find or create. + (list company project))))) + :bind + (("C-c c" . org-capture) + ("C-c i" . org-store-link) + ("C-c a" . org-agenda) + :map org-mode-map + ("C-c t" . org-toggle-inline-images) + ("C-c l" . org-toggle-link-display)) + :custom + (org-agenda-files (list org-inbox-file org-journal-file)) + (org-directory "~/nextcloud/org") + (org-default-notes-file org-inbox-file) + (org-archive-location (concat org-archive-file "::* From %s")) + (org-log-done 'time) + (org-log-into-drawer t) + (org-hide-emphasis-markers t) + (org-src-fontify-natively t) + (org-src-tab-acts-natively t) + (org-capture-templates '(("t" "Todo" entry (file org-inbox-file) + "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)") + ("j" "Journal" entry (file+olp+datetree org-journal-file) + "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") + ("n" "Note" entry (file org-notes-file) + "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") + ("p" "Project Task" item + (file+function org-work-file my/org-capture-project-target-heading) + "* TODO %? \n CLOCK: %U" + )) + ) + :config + ;; Enable syntax highlighting in code blocks + (add-hook 'org-mode-hook 'turn-on-font-lock) + (add-hook 'org-mode-hook 'org-indent-mode)) ;; extras (use-package comp-run - :ensure nil - :config - (push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list) - (push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list)) + :ensure nil + :config + (push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list) + (push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list)) (use-package rustic - :custom - (rustic-lsp-client 'eglot)) + :custom + (rustic-lsp-client 'eglot)) (provide 'init) - ;;; init.el ends here + ;;; init.el ends here #+end_src * Machines @@ -3255,10 +3276,10 @@ Nothing specific for the laptop. #+begin_src nix :tangle machines/traveldroid/configuration.nix :noweb tangle :mkdirp yes { user, ... } : { imports = - [ - ./hardware-configuration.nix - ../../configuration - ]; + [ + ./hardware-configuration.nix + ../../configuration + ]; } #+end_src @@ -3267,19 +3288,19 @@ This is the most different. Mostly taken from hardware-configuration.nix setup a #+begin_src nix :tangle machines/traveldroid/hardware-configuration.nix :noweb tangle :mkdirp yes { - hostname, - pkgs, - lib, - modulesPath, - user, - config, - ... + hostname, + pkgs, + lib, + modulesPath, + user, + config, + ... }: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ../../hardware/hardware.nix - ]; + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ../../hardware/hardware.nix + ]; boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ]; boot.initrd.kernelModules = [ ]; @@ -3287,19 +3308,19 @@ This is the most different. Mostly taken from hardware-configuration.nix setup a boot.extraModulePackages = [ ]; fileSystems."/" = - { device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2"; - fsType = "ext4"; - }; + { device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2"; + fsType = "ext4"; + }; fileSystems."/boot" = - { device = "/dev/disk/by-uuid/811D-0676"; - fsType = "vfat"; - options = [ "fmask=0077" "dmask=0077" ]; - }; + { device = "/dev/disk/by-uuid/811D-0676"; + fsType = "vfat"; + options = [ "fmask=0077" "dmask=0077" ]; + }; swapDevices = - [ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; } - ]; + [ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; } + ]; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; @@ -3313,16 +3334,16 @@ This is mostly about configuring the monitor. And laptop specific utilities. { pkgs, ... }: { imports = [ - ../../home + ../../home ]; home.packages = with pkgs; [ - brightnessctl + brightnessctl ]; wayland.windowManager.hyprland = { - extraConfig = '' - # Default portable monitor rule - monitor=DP-1,3840x1080@144,1920x0,1 - ''; + extraConfig = '' + # Default portable monitor rule + monitor=DP-1,3840x1080@144,1920x0,1 + ''; }; } #+end_src @@ -3333,14 +3354,14 @@ This script adds a =DO NOT MODIFY= header to all the generated nix files. #+NAME: startup #+BEGIN_SRC emacs-lisp (progn - (defun add-tangle-headers () - (message "running in %s" (buffer-file-name)) - (when (string= (file-name-extension (buffer-file-name)) "nix") - (goto-char (point-min)) - (insert "# WARNING : This file was generated by README.org\n# DO NOT MODIFY THIS FILE!\n# Any changes made here will be overwritten.\n") - (save-buffer)) - (save-buffer)) - (add-hook 'org-babel-post-tangle-hook 'add-tangle-headers)) + (defun add-tangle-headers () + (message "running in %s" (buffer-file-name)) + (when (string= (file-name-extension (buffer-file-name)) "nix") + (goto-char (point-min)) + (insert "# WARNING : This file was generated by README.org\n# DO NOT MODIFY THIS FILE!\n# Any changes made here will be overwritten.\n") + (save-buffer)) + (save-buffer)) + (add-hook 'org-babel-post-tangle-hook 'add-tangle-headers)) #+END_SRC # Local Variables: diff --git a/henrovnix_ok/configuration/apps/install_flatpaks.nix b/henrovnix_ok/configuration/apps/install_flatpaks.nix index 14e9ece7f..e109eb5af 100644 --- a/henrovnix_ok/configuration/apps/install_flatpaks.nix +++ b/henrovnix_ok/configuration/apps/install_flatpaks.nix @@ -8,98 +8,98 @@ let # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw _guard = assert !( - builtins.stringLength raw > 1 && - builtins.length rawLines == builtins.stringLength raw + builtins.stringLength raw > 1 && + builtins.length rawLines == builtins.stringLength raw ); true; cleanLine = l: - let - noCR = lib.replaceStrings [ "\r" ] [ "" ] l; - noInlineComment = lib.head (lib.splitString "#" noCR); - in - lib.strings.trim noInlineComment; + let + noCR = lib.replaceStrings [ "\r" ] [ "" ] l; + noInlineComment = lib.head (lib.splitString "#" noCR); + in + lib.strings.trim noInlineComment; entries = - builtins.filter (l: l != "") - (map cleanLine rawLines); + builtins.filter (l: l != "") + (map cleanLine rawLines); # 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. dotCount = s: builtins.length (lib.splitString "." s) - 1; 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 = - builtins.seq _guard ( - builtins.map (id: - if isValidId id then true else - throw '' - ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots) + builtins.seq _guard ( + builtins.map (id: + if isValidId id then true else + throw '' + ${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots) - Token : ${builtins.toJSON id} - flatpaks.conf : ${toString flatpakConfPath} + Token : ${builtins.toJSON id} + flatpaks.conf : ${toString flatpakConfPath} - Fix: remove stray tokens/headers, or comment them out with '#'. - '' - ) entries - ); + Fix: remove stray tokens/headers, or comment them out with '#'. + '' + ) entries + ); # Use validated entries flatpakApps = builtins.seq _validate entries; syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" '' - set -euo pipefail + set -euo pipefail - # Use the deployed config path (matches environment.etc below) - CONF="/etc/flatpak/flatpaks.conf" - if [[ -f "$CONF" ]]; then - echo "flatpak-sync: using $CONF" - else - echo "flatpak-sync: WARNING: $CONF not found, using embedded list" - fi + # Use the deployed config path (matches environment.etc below) + CONF="/etc/flatpak/flatpaks.conf" + if [[ -f "$CONF" ]]; then + echo "flatpak-sync: using $CONF" + else + echo "flatpak-sync: WARNING: $CONF not found, using embedded list" + fi - if ! flatpak remotes --system --columns=name | grep -qx flathub; then - flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - fi + if ! flatpak remotes --system --columns=name | grep -qx flathub; then + flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + fi - desired_apps=( - ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)} - ) + desired_apps=( + ${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)} + ) - for app in "''${desired_apps[@]}"; do - if ! flatpak info --system "$app" >/dev/null 2>&1; then - flatpak install --system -y --noninteractive flathub "$app" - fi - done + for app in "''${desired_apps[@]}"; do + if ! flatpak info --system "$app" >/dev/null 2>&1; then + flatpak install --system -y --noninteractive flathub "$app" + fi + done ''; in { services.flatpak.enable = true; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-hyprland - xdg-desktop-portal-gtk - ]; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + xdg-desktop-portal-gtk + ]; }; # 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 = { - description = "Install Flatpak apps listed in flatpaks.conf"; - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; + description = "Install Flatpak apps listed in flatpaks.conf"; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = syncFlatpaks; - }; + serviceConfig = { + Type = "oneshot"; + ExecStart = syncFlatpaks; + }; - restartTriggers = [ flatpakConfPath ]; - path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; + restartTriggers = [ flatpakConfPath ]; + path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; }; } diff --git a/henrovnix_ok/configuration/apps/install_packages.nix b/henrovnix_ok/configuration/apps/install_packages.nix index 52c4dd6bb..8ece7c04c 100644 --- a/henrovnix_ok/configuration/apps/install_packages.nix +++ b/henrovnix_ok/configuration/apps/install_packages.nix @@ -6,38 +6,38 @@ let rawLines = lib.splitString "\n" raw; # Guard: if we accidentally split into characters, rawLines length ~= stringLength raw _guard = assert !( - builtins.stringLength raw > 1 && - builtins.length rawLines == builtins.stringLength raw + builtins.stringLength raw > 1 && + builtins.length rawLines == builtins.stringLength raw ); true; cleanLine = l: - let - noCR = lib.replaceStrings [ "\r" ] [ "" ] l; - noInlineComment = lib.head (lib.splitString "#" noCR); - in - lib.strings.trim noInlineComment; + let + noCR = lib.replaceStrings [ "\r" ] [ "" ] l; + noInlineComment = lib.head (lib.splitString "#" noCR); + in + lib.strings.trim noInlineComment; entries = - builtins.filter (l: l != "") - (map cleanLine rawLines); + builtins.filter (l: l != "") + (map cleanLine rawLines); resolvePkg = name: - let - parts = lib.splitString "." name; - found = lib.attrByPath parts null pkgs; - in - if found == null then - throw '' - install_packages.nix: package not found in pkgs - Token : ${builtins.toJSON name} - packages.conf : ${toString packagesConfPath} - Hint : check the attribute name on search.nixos.org/packages - '' - else - found; + let + parts = lib.splitString "." name; + found = lib.attrByPath parts null pkgs; + in + if found == null then + throw '' + install_packages.nix: package not found in pkgs + Token : ${builtins.toJSON name} + packages.conf : ${toString packagesConfPath} + Hint : check the attribute name on search.nixos.org/packages + '' + else + found; packages = builtins.seq _guard (map resolvePkg entries); zenBrowser = - inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default; + inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default; in { environment.systemPackages = - packages - ++ [ zenBrowser ]; + packages + ++ [ zenBrowser ]; } diff --git a/henrovnix_ok/configuration/core/boot.nix b/henrovnix_ok/configuration/core/boot.nix index 5a9c13188..7f4da717c 100644 --- a/henrovnix_ok/configuration/core/boot.nix +++ b/henrovnix_ok/configuration/core/boot.nix @@ -1,27 +1,27 @@ { pkgs, ... } : { boot = { - initrd = { - verbose = false; # its a lot of logs. dont need it, unless we do. - kernelModules = [ ]; # no kernel modules on boot - }; + initrd = { + verbose = false; # its a lot of logs. dont need it, unless we do. + kernelModules = [ ]; # no kernel modules on boot + }; - extraModulePackages = [ ]; # no extra packages on boot either - kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel - kernelParams = [ "silent" ]; # quiet those logs + extraModulePackages = [ ]; # no extra packages on boot either + kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel + kernelParams = [ "silent" ]; # quiet those logs - consoleLogLevel = 0; # quiten more logs - plymouth.enable = true; # graphical boot animation instead + consoleLogLevel = 0; # quiten more logs + plymouth.enable = true; # graphical boot animation instead - supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows) + supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows) - loader = { - systemd-boot.enable = true; # systemd-boot - systemd-boot.configurationLimit = 10; - efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader + loader = { + systemd-boot.enable = true; # systemd-boot + systemd-boot.configurationLimit = 10; + 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 + }; }; } diff --git a/henrovnix_ok/configuration/core/files.nix b/henrovnix_ok/configuration/core/files.nix index c1938e05c..94fa5a344 100644 --- a/henrovnix_ok/configuration/core/files.nix +++ b/henrovnix_ok/configuration/core/files.nix @@ -1,29 +1,29 @@ { pkgs, user, config, ... }: { environment.systemPackages = with pkgs; [ - zip - unzip - p7zip - usbutils - udiskie - file-roller + zip + unzip + p7zip + usbutils + udiskie + file-roller ]; programs.thunar = { - enable = true; - plugins = with pkgs; [ - thunar-archive-plugin - thunar-media-tags-plugin - thunar-volman - thunar-vcs-plugin - ]; + enable = true; + plugins = with pkgs; [ + thunar-archive-plugin + thunar-media-tags-plugin + thunar-volman + thunar-vcs-plugin + ]; }; programs.xfconf.enable = true; # to save thunar settings services = { - gvfs.enable = true; # Mount, trash, and other functionalities - tumbler.enable = true; # Thumbnail support for images - udisks2.enable = true; # Auto mount usb drives + gvfs.enable = true; # Mount, trash, and other functionalities + tumbler.enable = true; # Thumbnail support for images + udisks2.enable = true; # Auto mount usb drives }; } diff --git a/henrovnix_ok/configuration/core/locale.nix b/henrovnix_ok/configuration/core/locale.nix index 532dd7097..3d3efd098 100644 --- a/henrovnix_ok/configuration/core/locale.nix +++ b/henrovnix_ok/configuration/core/locale.nix @@ -1,24 +1,24 @@ { user, ... } : let - locale = user.locale; - defaultLocale = "nl_NL.UTF-8"; +locale = user.locale; +defaultLocale = "nl_NL.UTF-8"; in { - # Set your time zone. - time.timeZone = "Europe/Amsterdam"; +# Set your time zone. +time.timeZone = "Europe/Amsterdam"; - # Select internationalisation properties. - i18n.defaultLocale = defaultLocale; +# Select internationalisation properties. +i18n.defaultLocale = defaultLocale; - i18n.extraLocaleSettings = { - LC_ADDRESS = locale; - LC_IDENTIFICATION = locale; - LC_MEASUREMENT = locale; - LC_MONETARY = locale; - LC_NAME = locale; - LC_NUMERIC = locale; - LC_PAPER = locale; - LC_TELEPHONE = locale; - LC_TIME = defaultLocale; - }; +i18n.extraLocaleSettings = { +LC_ADDRESS = locale; +LC_IDENTIFICATION = locale; +LC_MEASUREMENT = locale; +LC_MONETARY = locale; +LC_NAME = locale; +LC_NUMERIC = locale; +LC_PAPER = locale; +LC_TELEPHONE = locale; +LC_TIME = defaultLocale; +}; } diff --git a/henrovnix_ok/configuration/core/login-lightdm.nix b/henrovnix_ok/configuration/core/login-lightdm.nix index 33887e31e..d9b51ef15 100644 --- a/henrovnix_ok/configuration/core/login-lightdm.nix +++ b/henrovnix_ok/configuration/core/login-lightdm.nix @@ -2,40 +2,40 @@ let lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf; - lockPng = ../../assets/lock.png; + lockPng = ../../assets/lock.png; greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf; - greeterRaw = builtins.readFile greeterConfPath; + greeterRaw = builtins.readFile greeterConfPath; # Extract "key = value" from the greeter conf. # Returns null if not found. getIniValue = key: - let - lines = lib.splitString "\n" greeterRaw; + let + lines = lib.splitString "\n" greeterRaw; - # 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). - m = - let - ms = builtins.filter (x: x != null) (map (line: - builtins.match - ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") - line - ) lines); - in - if ms == [] then null else builtins.elemAt ms 0; + # 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). + m = + let + ms = builtins.filter (x: x != null) (map (line: + builtins.match + ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") + line + ) lines); 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. themePkgKey = getIniValue "theme-name"; - iconPkgKey = getIniValue "icon-theme-name"; + iconPkgKey = getIniValue "icon-theme-name"; cursorPkgKey = getIniValue "cursor-theme-name"; cursorSizeStr = getIniValue "cursor-theme-size"; cursorSize = - if cursorSizeStr == null then null - else lib.toInt (lib.strings.trim cursorSizeStr); + if cursorSizeStr == null then null + else lib.toInt (lib.strings.trim cursorSizeStr); # 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. # - "package" is the Nixpkgs derivation providing it. pkgMap = { - catppuccinThemePkg = { - package = pkgs.catppuccin-gtk.override { - accents = [ "blue" ]; - variant = "mocha"; - size = "standard"; - tweaks = [ ]; - }; - name = "Catppuccin-Mocha-Standard-Blue-Dark"; - }; + catppuccinThemePkg = { + package = pkgs.catppuccin-gtk.override { + accents = [ "blue" ]; + variant = "mocha"; + size = "standard"; + tweaks = [ ]; + }; + name = "Catppuccin-Mocha-Standard-Blue-Dark"; + }; - papirus-icon-theme = { - package = pkgs.papirus-icon-theme; - name = "Papirus-Dark"; - }; + papirus-icon-theme = { + package = pkgs.papirus-icon-theme; + name = "Papirus-Dark"; + }; - bibata-cursors = { - package = pkgs.bibata-cursors; - name = "Bibata-Modern-Ice"; - }; + bibata-cursors = { + package = pkgs.bibata-cursors; + name = "Bibata-Modern-Ice"; + }; }; pick = key: - if key == null then - throw "lightdm: missing required key in ${toString greeterConfPath}" - else if !(pkgMap ? "${key}") then - throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" - else - pkgMap."${key}"; + if key == null then + throw "lightdm: missing required key in ${toString greeterConfPath}" + else if !(pkgMap ? "${key}") then + throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" + else + pkgMap."${key}"; themeSel = pick themePkgKey; - iconSel = pick iconPkgKey; + iconSel = pick iconPkgKey; cursorSel = pick cursorPkgKey; # Rewrite greeter.conf so LightDM sees REAL names, not package keys. # Also force background to lockPng. - greeterFixed = - '' - [greeter] - theme-name = ${themeSel.name} - icon-theme-name = ${iconSel.name} - cursor-theme-name = ${cursorSel.name} - ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} - '' - + "\n" - + greeterRaw; + greeterFixed = + '' + [greeter] + theme-name = ${themeSel.name} + icon-theme-name = ${iconSel.name} + cursor-theme-name = ${cursorSel.name} + ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} + '' + + "\n" + + greeterRaw; in { services.greetd.enable = false; services.xserver = { + enable = true; + desktopManager.xterm.enable = false; + + displayManager.lightdm = { + enable = true; + background = lockPng; + + greeters.gtk = { enable = true; - desktopManager.xterm.enable = false; - displayManager.lightdm = { - enable = true; - background = lockPng; - - 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; + 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; + }; }; programs.hyprland.enable = true; # Optional: make them available system-wide as well environment.systemPackages = [ - themeSel.package - iconSel.package - cursorSel.package + themeSel.package + iconSel.package + cursorSel.package ]; } diff --git a/henrovnix_ok/configuration/core/login-tuigreeter.nix b/henrovnix_ok/configuration/core/login-tuigreeter.nix index 1fbc1d8b8..f2b8d6ff6 100644 --- a/henrovnix_ok/configuration/core/login-tuigreeter.nix +++ b/henrovnix_ok/configuration/core/login-tuigreeter.nix @@ -1,14 +1,14 @@ { pkgs, user, ... } : { - environment.systemPackages = with pkgs; [ - tuigreet - ]; - services.greetd = { - enable = true; - settings = { - default_session = { - command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'"; - }; - }; +environment.systemPackages = with pkgs; [ +tuigreet +]; +services.greetd = { +enable = true; +settings = { + default_session = { + command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'"; }; +}; +}; } diff --git a/henrovnix_ok/configuration/core/networking.nix b/henrovnix_ok/configuration/core/networking.nix index b85f82be8..1ba7ff740 100644 --- a/henrovnix_ok/configuration/core/networking.nix +++ b/henrovnix_ok/configuration/core/networking.nix @@ -1,21 +1,21 @@ { pkgs, lib, ... }: { networking = { - useDHCP = lib.mkDefault true; - networkmanager.enable = true; - networkmanager.wifi.backend = "iwd"; - wireless.iwd.enable = true; - wireless.userControlled.enable = true; - firewall = { - enable = true; - # KDE Connect: discovery + encrypted connections - allowedTCPPortRanges = [ - { from = 1714; to = 1764; } - ]; - allowedUDPPortRanges = [ - { from = 1714; to = 1764; } - ]; - }; + useDHCP = lib.mkDefault true; + networkmanager.enable = true; + networkmanager.wifi.backend = "iwd"; + wireless.iwd.enable = true; + wireless.userControlled.enable = true; + firewall = { + enable = true; + # KDE Connect: discovery + encrypted connections + allowedTCPPortRanges = [ + { from = 1714; to = 1764; } + ]; + allowedUDPPortRanges = [ + { from = 1714; to = 1764; } + ]; + }; }; environment.systemPackages = with pkgs; [ impala ]; } diff --git a/henrovnix_ok/configuration/core/nix-settings.nix b/henrovnix_ok/configuration/core/nix-settings.nix index 7b82abf7d..2d3013d0d 100644 --- a/henrovnix_ok/configuration/core/nix-settings.nix +++ b/henrovnix_ok/configuration/core/nix-settings.nix @@ -1,38 +1,38 @@ { pkgs, user, ... } : { - nix.settings = { - # enable flakes - experimental-features = ["nix-command" "flakes"]; +nix.settings = { +# enable flakes +experimental-features = ["nix-command" "flakes"]; - # add a cache that speed up new applications by downloading binaries - # from the trusted cache instead of compiling from sourcer - substituters = [ - "https://nix-community.cachix.org" - ]; - # trust the cache public key - trusted-public-keys = [ - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - }; +# add a cache that speed up new applications by downloading binaries +# from the trusted cache instead of compiling from sourcer +substituters = [ + "https://nix-community.cachix.org" +]; +# trust the cache public key +trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" +]; +}; - # allow proprietary software on this machine. I'm not a purist. - nixpkgs.config.allowUnfree = true; - # unityhub depends on this... for now - nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ]; +# allow proprietary software on this machine. I'm not a purist. +nixpkgs.config.allowUnfree = true; +# unityhub depends on this... for now +nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ]; - # this declares how often old configurations are cleared up. - # i cleanup anything older than a week, every week. - nix.gc = { - automatic = true; - options = "--delete-older-than 7d"; - dates = "weekly"; - }; +# this declares how often old configurations are cleared up. +# i cleanup anything older than a week, every week. +nix.gc = { +automatic = true; +options = "--delete-older-than 7d"; +dates = "weekly"; +}; - programs = { - # command line utility that makes applying changes easy and pretty - nh = { - enable = true; - flake = "/home/${user.username}/system"; - }; - }; +programs = { +# command line utility that makes applying changes easy and pretty +nh = { + enable = true; + flake = "/home/${user.username}/system"; +}; +}; } diff --git a/henrovnix_ok/configuration/default.nix b/henrovnix_ok/configuration/default.nix index df18f2687..6e92a2a24 100644 --- a/henrovnix_ok/configuration/default.nix +++ b/henrovnix_ok/configuration/default.nix @@ -1,45 +1,45 @@ { pkgs, user, ... } : { imports = [ - ./apps/install_flatpaks.nix - ./apps/install_packages.nix - ./core/files.nix - ./core/locale.nix - ./core/networking.nix - ./core/nix-settings.nix - #./core/login-tuigreeter.nix - ./core/login-lightdm.nix - ./desktop/audio.nix - ./desktop/hyprland.nix - ./dev/terminal.nix - ./core/boot.nix - ./services/services.nix - ]; + ./apps/install_flatpaks.nix + ./apps/install_packages.nix + ./core/files.nix + ./core/locale.nix + ./core/networking.nix + ./core/nix-settings.nix + #./core/login-tuigreeter.nix + ./core/login-lightdm.nix + ./desktop/audio.nix + ./desktop/hyprland.nix + ./dev/terminal.nix + ./core/boot.nix + ./services/services.nix + ]; - + - users.users.${user.username} = { - isNormalUser = true; - description = "henrov"; - extraGroups = [ - "networkmanager" # allow editing network connections - "wheel" # can do sudo - "scanner" # access to the network scanner - "lp" # access to the printer - ]; - }; + users.users.${user.username} = { + isNormalUser = true; + description = "henrov"; + extraGroups = [ + "networkmanager" # allow editing network connections + "wheel" # can do sudo + "scanner" # access to the network scanner + "lp" # access to the printer + ]; + }; - + - fonts.packages = with pkgs; [ - aporetic - nerd-fonts.iosevka - ]; + fonts.packages = with pkgs; [ + aporetic + nerd-fonts.iosevka + ]; - # enable the catppuccin theme for everything with mocha + blue accents - catppuccin.enable = true; - catppuccin.flavor = "mocha"; - catppuccin.accent = "blue"; + # enable the catppuccin theme for everything with mocha + blue accents + catppuccin.enable = true; + catppuccin.flavor = "mocha"; + catppuccin.accent = "blue"; - system.stateVersion = user.stateVersion; + system.stateVersion = user.stateVersion; } diff --git a/henrovnix_ok/configuration/desktop/audio.nix b/henrovnix_ok/configuration/desktop/audio.nix index e881c4d24..91a0fb583 100644 --- a/henrovnix_ok/configuration/desktop/audio.nix +++ b/henrovnix_ok/configuration/desktop/audio.nix @@ -2,21 +2,21 @@ { environment.systemPackages = with pkgs; [ - pipewire - wireplumber - alsa-utils - pulseaudio - pamixer - pavucontrol + pipewire + wireplumber + alsa-utils + pulseaudio + pamixer + pavucontrol ]; services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - wireplumber.enable = true; + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber.enable = true; }; security.rtkit.enable = true; @@ -26,45 +26,45 @@ # Prefer analog over HDMI/DP in a machine-agnostic way services.pipewire.wireplumber.extraConfig."51-audio-priorities" = { - "monitor.alsa.rules" = [ - # De-prioritize HDMI / DisplayPort sinks - { - matches = [ - { "node.name" = "~alsa_output\\..*HDMI.*"; } - { "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; - }; - } + "monitor.alsa.rules" = [ + # De-prioritize HDMI / DisplayPort sinks + { + matches = [ + { "node.name" = "~alsa_output\\..*HDMI.*"; } + { "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; + }; + } + ]; }; # Optional: clear "sticky" user-selected defaults so priority rules win 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" ]; - partOf = [ "wireplumber.service" ]; - wantedBy = [ "default.target" ]; + after = [ "wireplumber.service" ]; + partOf = [ "wireplumber.service" ]; + wantedBy = [ "default.target" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes"; - }; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes"; + }; }; } diff --git a/henrovnix_ok/configuration/desktop/hyprland.nix b/henrovnix_ok/configuration/desktop/hyprland.nix index 2e52a0b96..f03414a0d 100644 --- a/henrovnix_ok/configuration/desktop/hyprland.nix +++ b/henrovnix_ok/configuration/desktop/hyprland.nix @@ -1,56 +1,56 @@ { pkgs, ... }: { nix.settings = { - substituters = [ "https://hyprland.cachix.org" ]; - trusted-public-keys = [ - "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" - ]; + substituters = [ "https://hyprland.cachix.org" ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + ]; }; services.dbus.enable = true; security.polkit.enable = true; services.flatpak.enable = true; services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - wireplumber.enable = true; + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + wireplumber.enable = true; }; services.gvfs.enable = true; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-hyprland - xdg-desktop-portal-gtk - ]; - config.common.default = [ "hyprland" "gtk" ]; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + xdg-desktop-portal-gtk + ]; + config.common.default = [ "hyprland" "gtk" ]; }; environment.systemPackages = with pkgs; [ - walker - uwsm - hyprland-qtutils - hyprpolkitagent - grimblast + walker + uwsm + hyprland-qtutils + hyprpolkitagent + grimblast ]; programs = { - uwsm.enable = true; - uwsm.waylandCompositors.hyprland = { - prettyName = "Hyprland"; - comment = "Hyprland compositor managed by UWSM"; - binPath = "/run/current-system/sw/bin/Hyprland"; - }; - hyprland = { - withUWSM = true; - enable = true; - xwayland.enable = true; - }; + uwsm.enable = true; + uwsm.waylandCompositors.hyprland = { + prettyName = "Hyprland"; + comment = "Hyprland compositor managed by UWSM"; + binPath = "/run/current-system/sw/bin/Hyprland"; + }; + hyprland = { + withUWSM = true; + enable = true; + xwayland.enable = true; + }; }; environment.sessionVariables = { - XDG_SESSION_TYPE = "wayland"; - XDG_CURRENT_DESKTOP = "Hyprland"; - XDG_SESSION_DESKTOP = "Hyprland"; - NIXOS_OZONE_WL = "1"; - XCURSOR_SIZE = "24"; + XDG_SESSION_TYPE = "wayland"; + XDG_CURRENT_DESKTOP = "Hyprland"; + XDG_SESSION_DESKTOP = "Hyprland"; + NIXOS_OZONE_WL = "1"; + XCURSOR_SIZE = "24"; }; security.pam.services.hyprlock = { }; # Optional; GNOME-specific (keep only if you really use gnome-keyring integration) diff --git a/henrovnix_ok/configuration/services/services.nix b/henrovnix_ok/configuration/services/services.nix index 6778e81cf..35b3c75a2 100644 --- a/henrovnix_ok/configuration/services/services.nix +++ b/henrovnix_ok/configuration/services/services.nix @@ -1,23 +1,23 @@ { user, ...} : { - services = { - blueman.enable = true; # bluetooth manager - fwupd.enable = true; # firmware updating service - fstrim.enable = true; # ssd maintenance service - thermald.enable = true; # thermal regulation service - printing.enable = true; # printing services, cups - gnome.gnome-keyring.enable = true; # keyring - flatpak.enable = true; # allow installing things from flatpaks - #flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +services = { +blueman.enable = true; # bluetooth manager +fwupd.enable = true; # firmware updating service +fstrim.enable = true; # ssd maintenance service +thermald.enable = true; # thermal regulation service +printing.enable = true; # printing services, cups +gnome.gnome-keyring.enable = true; # keyring +flatpak.enable = true; # allow installing things from flatpaks +#flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo - # printer discovery - avahi = { - enable = true; - nssmdns4 = true; - openFirewall = true; - }; - }; +# printer discovery +avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; +}; +}; - virtualisation.docker.enable = true; # enable docker - users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group +virtualisation.docker.enable = true; # enable docker +users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group } diff --git a/henrovnix_ok/flake.nix b/henrovnix_ok/flake.nix index 008ae4878..f3331e003 100644 --- a/henrovnix_ok/flake.nix +++ b/henrovnix_ok/flake.nix @@ -1,89 +1,89 @@ { - description = "Henrov's nixos configuration"; - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - home-manager = { - url = "github:nix-community/home-manager"; - inputs.nixpkgs.follows = "nixpkgs"; +description = "Henrov's nixos configuration"; +inputs = { +nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; +home-manager = { + url = "github:nix-community/home-manager"; + 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"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - catppuccin = { - url = "github:catppuccin/nix"; - inputs.nixpkgs.follows = "nixpkgs"; + + home-manager.backupFileExtension = "backup"; + home-manager.users.${user.username} = { + imports = [ + ./machines/${machine}/home.nix + catppuccin.homeModules.catppuccin + ]; }; - 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@{ - 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; - }; - - 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 - ]; - }; - }; - + }) machines + ); + + devShells.${user.system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nil + nixfmt-rfc-style + ]; + }; +}; + } diff --git a/henrovnix_ok/hardware/hardware.nix b/henrovnix_ok/hardware/hardware.nix index 0b9664383..696626c9d 100755 --- a/henrovnix_ok/hardware/hardware.nix +++ b/henrovnix_ok/hardware/hardware.nix @@ -1,23 +1,23 @@ { pkgs, lib, user, config, ...} : { - nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu +nixpkgs.hostPlatform = lib.mkDefault user.system; # x86_64-linux +powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; # enable power saving on the cpu - # update cpu microcode with firmware that allows redistribution - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +# update cpu microcode with firmware that allows redistribution +hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - hardware = { - # always enable bluetooth - bluetooth.enable = true; +hardware = { +# always enable bluetooth +bluetooth.enable = true; - # always enable graphics drivers and enable a bunch of layers for it (including vulkan validation) - graphics = { - enable = true; - extraPackages = with pkgs; [ - vulkan-validation-layers # helps catch and debug vulkan crashes - ]; - }; - }; +# always enable graphics drivers and enable a bunch of layers for it (including vulkan validation) +graphics = { + enable = true; + extraPackages = with pkgs; [ + 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 } diff --git a/henrovnix_ok/home/apps/defaults-apps.nix b/henrovnix_ok/home/apps/defaults-apps.nix index 36731bd34..987d4afe3 100644 --- a/henrovnix_ok/home/apps/defaults-apps.nix +++ b/henrovnix_ok/home/apps/defaults-apps.nix @@ -2,8 +2,8 @@ { xdg.mimeApps.enable = true; xdg.mimeApps.defaultApplications = { - "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; - "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; - "text/html" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ]; + "x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ]; + "text/html" = [ "app.zen_browser.zen.desktop" ]; }; } diff --git a/henrovnix_ok/home/apps/ollama.nix b/henrovnix_ok/home/apps/ollama.nix index 80e343dc1..b79335828 100644 --- a/henrovnix_ok/home/apps/ollama.nix +++ b/henrovnix_ok/home/apps/ollama.nix @@ -7,8 +7,8 @@ in { services.ollama = { - enable = true; - package = pkgs.ollama; - environmentVariables = envVars; + enable = true; + package = pkgs.ollama; + environmentVariables = envVars; }; } diff --git a/henrovnix_ok/home/apps/theme.nix b/henrovnix_ok/home/apps/theme.nix index eb011c005..d0ac4c949 100644 --- a/henrovnix_ok/home/apps/theme.nix +++ b/henrovnix_ok/home/apps/theme.nix @@ -1,22 +1,22 @@ { pkgs, ...}: { - gtk = { - enable = true; - colorScheme = "dark"; - theme = { - name = "Catppuccin-GTK-Grey-Dark-Compact"; - package = (pkgs.magnetic-catppuccin-gtk.override { - accent = [ "grey" ]; - shade = "dark"; - tweaks = [ "black" ]; - size = "compact"; - }); - }; - iconTheme.name = "Papirus-Dark"; - }; - catppuccin.enable = true; - catppuccin.flavor = "mocha"; - catppuccin.accent = "blue"; - catppuccin.gtk.icon.enable = true; - catppuccin.cursors.enable = true; +gtk = { +enable = true; +colorScheme = "dark"; +theme = { + name = "Catppuccin-GTK-Grey-Dark-Compact"; + package = (pkgs.magnetic-catppuccin-gtk.override { + accent = [ "grey" ]; + shade = "dark"; + tweaks = [ "black" ]; + size = "compact"; + }); +}; +iconTheme.name = "Papirus-Dark"; +}; +catppuccin.enable = true; +catppuccin.flavor = "mocha"; +catppuccin.accent = "blue"; +catppuccin.gtk.icon.enable = true; +catppuccin.cursors.enable = true; } diff --git a/henrovnix_ok/home/default.nix b/henrovnix_ok/home/default.nix index fdfee0353..bd71d393b 100644 --- a/henrovnix_ok/home/default.nix +++ b/henrovnix_ok/home/default.nix @@ -1,35 +1,35 @@ { pkgs, user, ... } : { - imports = [ - ./apps/ollama.nix - #./apps/default-apps.nix - ./apps/theme.nix - ./desktop/hypridle.nix - ./desktop/hyprland.nix - ./desktop/hyprexpo.nix - ./desktop/hyprlock.nix - ./desktop/hyprscrolling.nix - ./desktop/hyprshell.nix - ./desktop/ncsway.nix - ./desktop/powermenu.nix - #./desktop/animated_wallpaper.nix - #./desktop/rotating_wallpaper.nix - ./desktop/workspace_wallpaper.nix - ./desktop/waybar.nix - ./desktop/walker.nix - ./dev/dev.nix - ./dev/kitty.nix - ./dev/shells.nix - ./dev/starship.nix - ./dev/zsh.nix - ./dev/emacs - ]; + imports = [ + ./apps/ollama.nix + #./apps/default-apps.nix + ./apps/theme.nix + ./desktop/hypridle.nix + ./desktop/hyprland.nix + ./desktop/hyprexpo.nix + ./desktop/hyprlock.nix + ./desktop/hyprscrolling.nix + ./desktop/hyprshell.nix + ./desktop/ncsway.nix + ./desktop/powermenu.nix + #./desktop/animated_wallpaper.nix + #./desktop/rotating_wallpaper.nix + ./desktop/workspace_wallpaper.nix + ./desktop/waybar.nix + ./desktop/walker.nix + ./dev/dev.nix + ./dev/kitty.nix + ./dev/shells.nix + ./dev/starship.nix + ./dev/zsh.nix + ./dev/emacs + ]; - home.username = "${user.username}"; - home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}"; - home.stateVersion = user.stateVersion; + home.username = "${user.username}"; + home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}"; + home.stateVersion = user.stateVersion; - + - programs.home-manager.enable = true; + programs.home-manager.enable = true; } diff --git a/henrovnix_ok/home/desktop/animated_wallpaper.nix b/henrovnix_ok/home/desktop/animated_wallpaper.nix index ff2f95a4b..418bae1eb 100644 --- a/henrovnix_ok/home/desktop/animated_wallpaper.nix +++ b/henrovnix_ok/home/desktop/animated_wallpaper.nix @@ -7,44 +7,44 @@ let userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4"; # (keep your existing approach: sync the repo wallpaper dir to the user dir) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: true; + src = repoWallpaperDir; + filter = path: type: true; }; in { home.packages = [ - pkgs.mpvpaper - pkgs.mpv + pkgs.mpvpaper + pkgs.mpv ]; # Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; systemd.user.services.mpvpaper-wallpaper = { - Unit = { - Description = "Video wallpaper (mpvpaper)"; - After = [ "graphical-session.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - Service = { - Type = "simple"; - # -p auto-pause saves resources when the wallpaper surface is hidden. - # '*' applies to all outputs. - # Stretch-to-fill (cover) behavior: - # --panscan=1.0 fills the entire output by cropping (no letterboxing). - # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. - ExecStart = '' - ${pkgs.mpvpaper}/bin/mpvpaper \ - -p \ - -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ - '*' "${userVideoPath}" - ''; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Video wallpaper (mpvpaper)"; + After = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "simple"; + # -p auto-pause saves resources when the wallpaper surface is hidden. + # '*' applies to all outputs. + # Stretch-to-fill (cover) behavior: + # --panscan=1.0 fills the entire output by cropping (no letterboxing). + # If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead. + ExecStart = '' + ${pkgs.mpvpaper}/bin/mpvpaper \ + -p \ + -o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \ + '*' "${userVideoPath}" + ''; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; } diff --git a/henrovnix_ok/home/desktop/hyprexpo.nix b/henrovnix_ok/home/desktop/hyprexpo.nix index 17f3f107d..c859130ff 100644 --- a/henrovnix_ok/home/desktop/hyprexpo.nix +++ b/henrovnix_ok/home/desktop/hyprexpo.nix @@ -1,28 +1,28 @@ { config, lib, pkgs, ... }: { wayland.windowManager.hyprland = { - # Load the Hyprexpo plugin (from nixpkgs) - plugins = [ - pkgs.hyprlandPlugins.hyprexpo - ]; + # Load the Hyprexpo plugin (from nixpkgs) + plugins = [ + pkgs.hyprlandPlugins.hyprexpo + ]; - # Append plugin config + keybind after your existing hyprland.conf - extraConfig = lib.mkAfter '' - ############################ - # Hyprexpo (workspace/window overview) - ############################ + # Append plugin config + keybind after your existing hyprland.conf + extraConfig = lib.mkAfter '' + ############################ + # Hyprexpo (workspace/window overview) + ############################ - # Basic plugin config (tweak as you like) - plugin { - hyprexpo { - columns = 3 - gaps_in = 5 - gaps_out = 20 + # Basic plugin config (tweak as you like) + plugin { + hyprexpo { + columns = 3 + gaps_in = 5 + gaps_out = 20 - # Optional; comment out if you don't want it - # workspace_method = center current - } - } - ''; + # Optional; comment out if you don't want it + # workspace_method = center current + } + } + ''; }; } diff --git a/henrovnix_ok/home/desktop/hypridle.nix b/henrovnix_ok/home/desktop/hypridle.nix index 45e6187fa..6361d87e3 100644 --- a/henrovnix_ok/home/desktop/hypridle.nix +++ b/henrovnix_ok/home/desktop/hypridle.nix @@ -4,5 +4,6 @@ let in { 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 ; } diff --git a/henrovnix_ok/home/desktop/hyprland.nix b/henrovnix_ok/home/desktop/hyprland.nix index a98908907..931299b1a 100644 --- a/henrovnix_ok/home/desktop/hyprland.nix +++ b/henrovnix_ok/home/desktop/hyprland.nix @@ -1,40 +1,41 @@ { config, lib, pkgs, flakeRoot, ... }: 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"; in { wayland.windowManager.hyprland = { - enable = true; - # Load base config + bindings from repo files - extraConfig = - (builtins.readFile hyprConf) - + "\n\n# --- Repo keybindings ---\n" - + (builtins.readFile bindingsConf) - + "\n"; - settings = { - windowrule = [ - "match:class nm-connection-editor, float 1, center 1, size 900 700" - ]; - }; + enable = true; + # Load base config + bindings from repo files + extraConfig = + (builtins.readFile hyprConf) + + "\n\n# --- Repo keybindings ---\n" + + (builtins.readFile bindingsConf) + + "\n"; + settings = { + windowrule = [ + "match:class nm-connection-editor, float 1, center 1, size 900 700" + ]; + }; }; xdg.configFile."hypr/scripts/lid-lock.sh" = { - source = flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh"; - executable = true; + source = lib.mkForce flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh"; + backup = lib.mkForce false; + executable = true; }; xdg.portal = { - enable = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-gtk - xdg-desktop-portal-hyprland - ]; - # GTK als algemene backend (OpenURI is daar betrouwbaar) - config.common.default = [ "gtk" ]; - # Hyprland alleen voor screensharing / remote desktop - config.hyprland = { - "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ]; - "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ]; - }; + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-gtk + xdg-desktop-portal-hyprland + ]; + # GTK als algemene backend (OpenURI is daar betrouwbaar) + config.common.default = [ "gtk" ]; + # Hyprland alleen voor screensharing / remote desktop + config.hyprland = { + "org.freedesktop.impl.portal.Screencast" = [ "hyprland" ]; + "org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ]; + }; }; } diff --git a/henrovnix_ok/home/desktop/hyprlock.nix b/henrovnix_ok/home/desktop/hyprlock.nix index df46aae5a..7056df3fd 100644 --- a/henrovnix_ok/home/desktop/hyprlock.nix +++ b/henrovnix_ok/home/desktop/hyprlock.nix @@ -1,10 +1,12 @@ {config, lib, pkgs, flakeRoot, ... }: let - lockPngSrc = flakeRoot + "/assets/lock.png"; + lockPngSrc = flakeRoot + "/assets/lock.png"; hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf"; in { home.packages = [ pkgs.hyprlock ]; - xdg.configFile."hypr/lock.png".source = lockPngSrc; - xdg.configFile."hypr/hyprlock.conf".source = hyprlockConf; + xdg.configFile."hypr/lock.png".source = lib.mkForce lockPngSrc; + 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; } diff --git a/henrovnix_ok/home/desktop/hyprscrolling.nix b/henrovnix_ok/home/desktop/hyprscrolling.nix index 1eee5df93..cc80c9eb9 100644 --- a/henrovnix_ok/home/desktop/hyprscrolling.nix +++ b/henrovnix_ok/home/desktop/hyprscrolling.nix @@ -11,37 +11,40 @@ let targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh"; # Facilitate switching between scrolling and dwindle 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"; in { # Ensure deps for the script exist at runtime # (hyprctl comes with Hyprland; jq is often not installed by default) home.packages = with pkgs; [ - jq + jq ]; wayland.windowManager.hyprland = { - enable = true; - plugins = [ - pkgs.hyprlandPlugins.hyprscrolling - ]; - extraConfig = '' - source = ~/.config/${targetRel} - ''; + enable = true; + plugins = [ + pkgs.hyprlandPlugins.hyprscrolling + ]; + extraConfig = '' + source = ~/.config/${targetRel} + ''; }; # 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}" = { - source = repoOverflowScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoOverflowScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetPerMonitor}" = { - source = repoPerMonitorScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoPerMonitorScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; xdg.configFile."${targetSwitchScript}" = { - source = repoSwitchScript; - executable = true; # makes it chmod +x + source = lib.mkForce repoSwitchScript; + backup = lib.mkForce false; + executable = true; # makes it chmod +x }; } diff --git a/henrovnix_ok/home/desktop/hyprshell.nix b/henrovnix_ok/home/desktop/hyprshell.nix index 8e038c0eb..30f0fedea 100644 --- a/henrovnix_ok/home/desktop/hyprshell.nix +++ b/henrovnix_ok/home/desktop/hyprshell.nix @@ -9,22 +9,24 @@ in xdg.enable = true; home.packages = [ pkgs.hyprshell ]; # Link repo -> ~/.config/hyprshell/... - xdg.configFile."hyprshell/config.ron".source = cfgRon; - xdg.configFile."hyprshell/styles.css".source = cssFile; + xdg.configFile."hyprshell/config.ron".source = lib.mkForce cfgRon; + 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) systemd.user.services.hyprshell = { - Unit = { - Description = "Hyprshell (window switcher / launcher)"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; + Unit = { + Description = "Hyprshell (window switcher / launcher)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs.hyprshell}/bin/hyprshell"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; }; } diff --git a/henrovnix_ok/home/desktop/powermenu.nix b/henrovnix_ok/home/desktop/powermenu.nix index e35fea33b..7549ccc13 100644 --- a/henrovnix_ok/home/desktop/powermenu.nix +++ b/henrovnix_ok/home/desktop/powermenu.nix @@ -1,13 +1,14 @@ { config, lib, pkgs, flakeRoot, ... }: let repoScript = - flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh"; + flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh"; targetRel = "hypr/scripts/powermenu.sh"; in { # Ensure script exists in ~/.config/hypr/scripts/ xdg.configFile."${targetRel}" = { - source = repoScript; - executable = true; + source = lib.mkForce repoScript; + backup = lib.mkForce false; + executable = true; }; } diff --git a/henrovnix_ok/home/desktop/rotating_wallpaper.nix b/henrovnix_ok/home/desktop/rotating_wallpaper.nix index 8beb6e0fe..e00b3bb4a 100644 --- a/henrovnix_ok/home/desktop/rotating_wallpaper.nix +++ b/henrovnix_ok/home/desktop/rotating_wallpaper.nix @@ -8,35 +8,35 @@ let userConfPath = "${userAbsRoot}/wallpaper.conf"; # Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions) repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: - (builtins.baseNameOf path) != "wallpaper.conf"; + src = repoWallpaperDir; + filter = path: type: + (builtins.baseNameOf path) != "wallpaper.conf"; }; in { home.packages = [ pkgs.wpaperd ]; # Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; # Now safely overwrite the config every activation (no HM collision) home.activation.wallpaperConfForce = - lib.hm.dag.entryAfter [ "writeBoundary" ] '' - set -euo pipefail - mkdir -p "${userAbsRoot}" - install -m 0644 "${repoWallpaperConf}" "${userConfPath}" - ''; + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + set -euo pipefail + mkdir -p "${userAbsRoot}" + install -m 0644 "${repoWallpaperConf}" "${userConfPath}" + ''; systemd.user.services.wpaperd = { - Unit = { - Description = "wpaperd wallpaper daemon"; - After = [ "default.target" ]; - }; - Service = { - Type = "simple"; - ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install.WantedBy = [ "default.target" ]; + Unit = { + Description = "wpaperd wallpaper daemon"; + After = [ "default.target" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install.WantedBy = [ "default.target" ]; ; diff --git a/henrovnix_ok/home/desktop/walker.nix b/henrovnix_ok/home/desktop/walker.nix index efea40b6b..17af25a1c 100644 --- a/henrovnix_ok/home/desktop/walker.nix +++ b/henrovnix_ok/home/desktop/walker.nix @@ -1,13 +1,13 @@ { config, pkgs, lib, flakeRoot, inputs ? null, ... }: let walkerPkg = - if inputs != null && inputs ? walker - then inputs.walker.packages.${pkgs.system}.default - else pkgs.walker; + if inputs != null && inputs ? walker + then inputs.walker.packages.${pkgs.system}.default + else pkgs.walker; elephantPkg = - if inputs != null && inputs ? elephant - then inputs.elephant.packages.${pkgs.system}.default - else pkgs.elephant; + if inputs != null && inputs ? elephant + then inputs.elephant.packages.${pkgs.system}.default + else pkgs.elephant; sessionTarget = "graphical-session.target"; # All theme files now live here repoThemesDir = flakeRoot + "/assets/conf/desktop/walker"; @@ -16,11 +16,15 @@ in xdg.enable = true; home.packages = [ walkerPkg elephantPkg ]; # ~/.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".backup = lib.mkForce false; 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) systemd.user.services.elephant = { /* ... your existing service ... */ }; - systemd.user.services.walker = { /* ... your existing service ... */ }; + systemd.user.services.walker = { /* ... your existing service ... */ }; } diff --git a/henrovnix_ok/home/desktop/waybar.nix b/henrovnix_ok/home/desktop/waybar.nix index f75a896ef..18f123aff 100644 --- a/henrovnix_ok/home/desktop/waybar.nix +++ b/henrovnix_ok/home/desktop/waybar.nix @@ -6,14 +6,16 @@ in programs.waybar.enable = true; # Ensure config matches repo (HM-managed symlink, not user-editable) xdg.configFile."waybar/config" = { - source = repoWaybarDir + "/config.jsonc"; - force = true; + source = lib.mkForce repoWaybarDir + "/config.jsonc"; + backup = lib.mkForce false; + force = true; }; # Override HM's internally-generated waybar-style.css derivation # and use your repo file instead. xdg.configFile."waybar/style.css" = { - source = lib.mkForce (repoWaybarDir + "/style.css"); - force = true; + source = lib.mkForce (repoWaybarDir + "/style.css"); + backup = lib.mkForce false; + force = true; }; # 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) diff --git a/henrovnix_ok/home/desktop/workspace_wallpaper.nix b/henrovnix_ok/home/desktop/workspace_wallpaper.nix index 554f68ed3..d55061b3c 100644 --- a/henrovnix_ok/home/desktop/workspace_wallpaper.nix +++ b/henrovnix_ok/home/desktop/workspace_wallpaper.nix @@ -7,197 +7,200 @@ let # (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper"; repoWallpapersOnly = lib.cleanSourceWith { - src = repoWallpaperDir; - filter = path: type: true; + src = repoWallpaperDir; + filter = path: type: true; }; daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh"; - setRel = "hypr/scripts/set-wallpaper.sh"; + setRel = "hypr/scripts/set-wallpaper.sh"; in { home.packages = [ - pkgs.hyprpaper - pkgs.socat - pkgs.jq - pkgs.findutils - pkgs.coreutils - pkgs.gnused - pkgs.gawk + pkgs.hyprpaper + pkgs.socat + pkgs.jq + pkgs.findutils + pkgs.coreutils + pkgs.gnused + pkgs.gawk ]; # Keep your existing "sync wallpapers into a writable dir" pattern home.file."${userRelRoot}" = { - source = repoWallpapersOnly; - recursive = true; + source = repoWallpapersOnly; + recursive = true; }; # Hyprpaper config (hyprpaper reads this; it does NOT need to write it) # `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0} - xdg.configFile."hypr/hyprpaper.conf".text = '' - ipc = true - splash = false + xdg.configFile."hypr/hyprpaper.conf".text = lib.mkForce '' + ipc = true + splash = false ''; + xdg.configFile."hypr/hyprpaper.conf".backup = lib.mkForce false; # Workspace wallpaper daemon: listens to socket2, applies w-=... mapping # Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1} xdg.configFile."${daemonRel}" = { - executable = true; - text = '' - #!/usr/bin/env bash - set -euo pipefail - : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" - : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" - SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" - [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } - PICTURES_DIR="''${1:-${picturesDir}}" - FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2} - HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" - MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" - focused_monitor() { - hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 - } - map_file_for_monitor() { - local mon="''${1}" - echo "''${MAP_ROOT}/''${mon}/defaults.conf" - } - ensure_map_file() { - local mon="''${1}" - local f - f="$(map_file_for_monitor "''${mon}")" - mkdir -p "$(dirname "''${f}")" - if [[ ! -f "''${f}" ]]; then - # Seed with 1..9 from picturesDir if present, else empty entries - { - 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)" - echo "w-''${i}= ''${seed}" - done - } > "''${f}" - fi - echo "''${f}" - } - get_wall_for_ws() { - local mon="''${1}" - local wsid="''${2}" - local f key val - f="$(ensure_map_file "''${mon}")" - key="w-''${wsid}" - # accept "w-1=/path" or "w-1= /path" - val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)" - echo "''${val}" - } - apply_wallpaper() { - local mon="''${1}" - local wsid="''${2}" - local file - file="$(get_wall_for_ws "''${mon}" "''${wsid}")" - [[ -n "''${file}" ]] || return 0 - [[ -f "''${file}" ]] || return 0 - # Apply via IPC - # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3} - hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null - } - # Initial apply on startup - mon="$(focused_monitor || true)" - wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - handle() { - local line="''${1}" - case "''${line}" in - workspacev2* ) - # workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4} - local payload wsid - payload="''${line#*>>}" - wsid="''${payload%%,*}" - mon="$(focused_monitor || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - ;; - focusedmon* ) - # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5} - # When monitor focus changes, re-apply for the active workspace id. - mon="$(focused_monitor || true)" - wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" - [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" - ;; - esac - } - socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do - handle "''${line}" || true - done - ''; + executable = true; + text = lib.mkForce '' + #!/usr/bin/env bash + set -euo pipefail + : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" + : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" + SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" + [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } + PICTURES_DIR="''${1:-${picturesDir}}" + FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2} + HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" + MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" + focused_monitor() { + hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 + } + map_file_for_monitor() { + local mon="''${1}" + echo "''${MAP_ROOT}/''${mon}/defaults.conf" + } + ensure_map_file() { + local mon="''${1}" + local f + f="$(map_file_for_monitor "''${mon}")" + mkdir -p "$(dirname "''${f}")" + if [[ ! -f "''${f}" ]]; then + # Seed with 1..9 from picturesDir if present, else empty entries + { + 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)" + echo "w-''${i}= ''${seed}" + done + } > "''${f}" + fi + echo "''${f}" + } + get_wall_for_ws() { + local mon="''${1}" + local wsid="''${2}" + local f key val + f="$(ensure_map_file "''${mon}")" + key="w-''${wsid}" + # accept "w-1=/path" or "w-1= /path" + val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)" + echo "''${val}" + } + apply_wallpaper() { + local mon="''${1}" + local wsid="''${2}" + local file + file="$(get_wall_for_ws "''${mon}" "''${wsid}")" + [[ -n "''${file}" ]] || return 0 + [[ -f "''${file}" ]] || return 0 + # Apply via IPC + # hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3} + hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null + } + # Initial apply on startup + mon="$(focused_monitor || true)" + wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + handle() { + local line="''${1}" + case "''${line}" in + workspacev2* ) + # workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4} + local payload wsid + payload="''${line#*>>}" + wsid="''${payload%%,*}" + mon="$(focused_monitor || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + ;; + focusedmon* ) + # focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5} + # When monitor focus changes, re-apply for the active workspace id. + mon="$(focused_monitor || true)" + wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" + [[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}" + ;; + esac + } + socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do + handle "''${line}" || true + done + ''; + backup = lib.mkForce false; }; # CLI setter in the style of your inspiration script. # Usage: set-wallpaper.sh [wallpaper] xdg.configFile."${setRel}" = { - executable = true; - text = '' - #!/usr/bin/env bash - set -euo pipefail + executable = true; + text = lib.mkForce '' + #!/usr/bin/env bash + set -euo pipefail - HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" - MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" + HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr" + MAP_ROOT="''${HYPR_DIR}/hyprpaper/config" - usage() { - echo "Usage: set-wallpaper.sh [wallpaper_path]" - } + usage() { + echo "Usage: set-wallpaper.sh [wallpaper_path]" + } - wsid="''${1:-}" - mon="''${2:-}" - wp="''${3:-}" + wsid="''${1:-}" + mon="''${2:-}" + wp="''${3:-}" - [[ -n "''${wsid}" ]] || { usage; exit 1; } - [[ -n "''${mon}" ]] || { usage; exit 1; } + [[ -n "''${wsid}" ]] || { usage; exit 1; } + [[ -n "''${mon}" ]] || { usage; exit 1; } - cfg="''${MAP_ROOT}/''${mon}/defaults.conf" - mkdir -p "$(dirname "''${cfg}")" - [[ -f "''${cfg}" ]] || touch "''${cfg}" + cfg="''${MAP_ROOT}/''${mon}/defaults.conf" + mkdir -p "$(dirname "''${cfg}")" + [[ -f "''${cfg}" ]] || touch "''${cfg}" - if [[ -z "''${wp}" ]]; then - # 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)" - [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } - fi + if [[ -z "''${wp}" ]]; then + # 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)" + [[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } + fi - # Ensure key exists; if not, append it - key="w-''${wsid}" - if ! grep -q "^''${key}=" "''${cfg}"; then - echo "''${key}=" >> "''${cfg}" - fi + # Ensure key exists; if not, append it + key="w-''${wsid}" + if ! grep -q "^''${key}=" "''${cfg}"; then + echo "''${key}=" >> "''${cfg}" + fi - # Set mapping - ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}" + # Set mapping + ${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}" - # 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)" - if [[ "''${curws}" == "''${wsid}" ]]; then - hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null - fi - ''; + # 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)" + if [[ "''${curws}" == "''${wsid}" ]]; then + hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null + fi + ''; + backup = lib.mkForce false; }; # Services systemd.user.services.hyprpaper = { - Unit = { - Description = "hyprpaper wallpaper daemon"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; - }; - Service = { - ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Unit = { + Description = "hyprpaper wallpaper daemon"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; }; systemd.user.services.hyprpaper-ws-daemon = { - Unit = { - Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" "hyprpaper.service" ]; - }; - Service = { - ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}"; - Restart = "on-failure"; - RestartSec = 1; - }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Unit = { + Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" "hyprpaper.service" ]; + }; + Service = { + ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}"; + Restart = "on-failure"; + RestartSec = 1; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; }; } diff --git a/henrovnix_ok/home/dev/alacritty.nix b/henrovnix_ok/home/dev/alacritty.nix index 992189892..7a0e2e037 100644 --- a/henrovnix_ok/home/dev/alacritty.nix +++ b/henrovnix_ok/home/dev/alacritty.nix @@ -7,6 +7,7 @@ in programs.alacritty.enable = true; # Override the config generated by programs.alacritty xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf; + xdg.configFile."alacritty/alacritty.toml".backup = lib.mkForce false catppuccin.alacritty.enable = true; catppuccin.alacritty.flavor = "mocha"; } diff --git a/henrovnix_ok/home/dev/dev.nix b/henrovnix_ok/home/dev/dev.nix index 2370dfdde..7b4542858 100644 --- a/henrovnix_ok/home/dev/dev.nix +++ b/henrovnix_ok/home/dev/dev.nix @@ -1,42 +1,42 @@ { config, pkgs, lib, ... }: { programs = { - vscode.enable = true; - vim.enable = true; - ripgrep.enable = true; - btop.enable = true; - fzf = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - zoxide = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - eza = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - }; - direnv = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - nix-direnv.enable = true; - }; - # Zsh-specific config belongs here - zsh = { + vscode.enable = true; + vim.enable = true; + ripgrep.enable = true; + btop.enable = true; + fzf = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + zoxide = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + eza = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; + direnv = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + nix-direnv.enable = true; + }; + # Zsh-specific config belongs here + zsh = { # for emacs-eat package - initContent = lib.mkOrder 1200 '' - [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \ - source "$EAT_SHELL_INTEGRATION_DIR/zsh" - ''; - }; - git = { - enable = true; - lfs.enable = true; - }; + initContent = lib.mkOrder 1200 '' + [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \ + source "$EAT_SHELL_INTEGRATION_DIR/zsh" + ''; + }; + git = { + enable = true; + lfs.enable = true; + }; }; } diff --git a/henrovnix_ok/home/dev/emacs/default.nix b/henrovnix_ok/home/dev/emacs/default.nix index 49c6c94fc..66513a06e 100644 --- a/henrovnix_ok/home/dev/emacs/default.nix +++ b/henrovnix_ok/home/dev/emacs/default.nix @@ -1,67 +1,67 @@ { pkgs, ... }: { - programs.emacs = { - enable = true; - # install with tree sitter enabled - package = (pkgs.emacs-pgtk.override { withTreeSitter = true; }); - extraPackages = epkgs: [ - # also install all tree sitter grammars - epkgs.manualPackages.treesit-grammars.with-all-grammars - epkgs.nerd-icons # nerd fonts support - epkgs.doom-modeline # model line - epkgs.diminish # hides modes from modeline - epkgs.eldoc # doc support - epkgs.pulsar # pulses the cursor when jumping about - epkgs.which-key # help porcelain - epkgs.expreg # expand region - epkgs.vundo # undo tree - epkgs.puni # structured editing - epkgs.avy # jumping utility - epkgs.consult # emacs right click - epkgs.vertico # minibuffer completion - epkgs.marginalia # annotations for completions - epkgs.crux # utilities - epkgs.magit # git porcelain - epkgs.nerd-icons-corfu # nerd icons for completion - epkgs.corfu # completion - epkgs.cape # completion extensions - epkgs.orderless # search paradigm - epkgs.yasnippet # snippets support - epkgs.yasnippet-snippets # commonly used snippets - epkgs.rg # ripgrep - epkgs.exec-path-from-shell # load env and path - epkgs.eat # better shell - epkgs.rust-mode # rust mode (when rust-ts doesn't cut it) - epkgs.rustic # more rust things - epkgs.nix-mode # nix lang - epkgs.hcl-mode # hashicorp file mode - epkgs.shell-pop # quick shell popup - epkgs.envrc # support for loading .envrc - epkgs.nixpkgs-fmt # format nix files - epkgs.f # string + file utilities - epkgs.gptel # llm chat (mainly claude) - epkgs.catppuccin-theme # catppuccin theme - epkgs.eldoc-box # docs in a box - epkgs.sideline # 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 - ]; - }; - home.sessionVariables = { - EDITOR = "emacs"; - XDG_SCREENSHOTS_DIR = "~/screenshots"; - }; - home.file = { - emacs-init = { - source = ./early-init.el; - target = ".emacs.d/early-init.el"; - }; - emacs = { - source = ./init.el; - target = ".emacs.d/init.el"; - }; - }; - services.nextcloud-client = { - enable = true; - }; +programs.emacs = { +enable = true; +# install with tree sitter enabled +package = (pkgs.emacs-pgtk.override { withTreeSitter = true; }); +extraPackages = epkgs: [ + # also install all tree sitter grammars + epkgs.manualPackages.treesit-grammars.with-all-grammars + epkgs.nerd-icons # nerd fonts support + epkgs.doom-modeline # model line + epkgs.diminish # hides modes from modeline + epkgs.eldoc # doc support + epkgs.pulsar # pulses the cursor when jumping about + epkgs.which-key # help porcelain + epkgs.expreg # expand region + epkgs.vundo # undo tree + epkgs.puni # structured editing + epkgs.avy # jumping utility + epkgs.consult # emacs right click + epkgs.vertico # minibuffer completion + epkgs.marginalia # annotations for completions + epkgs.crux # utilities + epkgs.magit # git porcelain + epkgs.nerd-icons-corfu # nerd icons for completion + epkgs.corfu # completion + epkgs.cape # completion extensions + epkgs.orderless # search paradigm + epkgs.yasnippet # snippets support + epkgs.yasnippet-snippets # commonly used snippets + epkgs.rg # ripgrep + epkgs.exec-path-from-shell # load env and path + epkgs.eat # better shell + epkgs.rust-mode # rust mode (when rust-ts doesn't cut it) + epkgs.rustic # more rust things + epkgs.nix-mode # nix lang + epkgs.hcl-mode # hashicorp file mode + epkgs.shell-pop # quick shell popup + epkgs.envrc # support for loading .envrc + epkgs.nixpkgs-fmt # format nix files + epkgs.f # string + file utilities + epkgs.gptel # llm chat (mainly claude) + epkgs.catppuccin-theme # catppuccin theme + epkgs.eldoc-box # docs in a box + epkgs.sideline # 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 +]; +}; +home.sessionVariables = { +EDITOR = "emacs"; +XDG_SCREENSHOTS_DIR = "~/screenshots"; +}; +home.file = { +emacs-init = { + source = ./early-init.el; + target = ".emacs.d/early-init.el"; +}; +emacs = { + source = ./init.el; + target = ".emacs.d/init.el"; +}; +}; +services.nextcloud-client = { +enable = true; +}; } diff --git a/henrovnix_ok/home/dev/emacs/early-init.el b/henrovnix_ok/home/dev/emacs/early-init.el index 348162dc6..d6f8111be 100644 --- a/henrovnix_ok/home/dev/emacs/early-init.el +++ b/henrovnix_ok/home/dev/emacs/early-init.el @@ -1,92 +1,92 @@ ;;; package --- early init -*- lexical-binding: t -*- -;;; Commentary: -;;; Prevents white flash and better Emacs defaults -;;; Code: -(set-language-environment "UTF-8") -(setq-default - default-frame-alist - '((background-color . "#1e1e2e") - (bottom-divider-width . 1) ; Thin horizontal window divider - (foreground-color . "#bac2de") ; Default foreground color - (fullscreen . maximized) ; Maximize the window by default - (horizontal-scroll-bars . nil) ; No horizontal scroll-bars - (left-fringe . 8) ; Thin left fringe - (menu-bar-lines . 0) ; No menu bar - (right-divider-width . 1) ; Thin vertical window divider - (right-fringe . 8) ; Thin right fringe - (tool-bar-lines . 0) ; No tool bar - (undecorated . t) ; Remove extraneous X decorations - (vertical-scroll-bars . nil)) ; No vertical scroll-bars - user-full-name "Henrov henrov" ; ME! - ;; memory configuration - ;; Higher garbage collection threshold, prevents frequent gc locks, reset later - gc-cons-threshold most-positive-fixnum - ;; Ignore warnings for (obsolete) elisp compilations - byte-compile-warnings '(not obsolete) - ;; And other log types completely - warning-suppress-log-types '((comp) (bytecomp)) - ;; Large files are okay in the new millenium. - large-file-warning-threshold 100000000 - ;; dont show garbage collection messages at startup, will reset later - garbage-collection-messages nil - ;; native compilation - package-native-compile t - native-comp-warning-on-missing-source nil - native-comp-async-report-warnings-errors 'silent - ;; Read more based on system pipe capacity - read-process-output-max (max (* 10240 10240) read-process-output-max) - ;; scroll configuration - scroll-margin 0 ; Lets scroll to the end of the margin - scroll-conservatively 100000 ; Never recenter the window - scroll-preserve-screen-position 1 ; Scrolling back and forth - ;; frame config - ;; Improve emacs startup time by not resizing to adjust for custom settings - frame-inhibit-implied-resize t - ;; Dont resize based on character height / width but to exact pixels - frame-resize-pixelwise t - ;; backups & files - backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter - backup-by-copying t ; Don't clobber symlinks - create-lockfiles nil ; Don't have temp files - delete-old-versions t ; Cleanup automatically - kept-new-versions 6 ; Update every few times - kept-old-versions 2 ; And cleanup even more - version-control t ; Version them backups - delete-by-moving-to-trash t ; Dont delete, send to trash instead - ;; startup - inhibit-startup-screen t ; I have already done the tutorial. Twice - inhibit-startup-message t ; I know I am ready - inhibit-startup-echo-area-message t ; Yep, still know it - initial-scratch-message nil ; I know it is the scratch buffer! - initial-buffer-choice nil - inhibit-startup-buffer-menu t - inhibit-x-resources t - initial-major-mode 'fundamental-mode - pgtk-wait-for-event-timeout 0.001 ; faster child frames - ad-redefinition-action 'accept ; dont care about legacy things being redefined - inhibit-compacting-font-caches t - ;; tabs - tab-width 4 ; Always tab 4 spaces. - indent-tabs-mode nil ; Never use actual tabs. - ;; rendering - cursor-in-non-selected-windows nil ; dont render cursors other windows - ;; packages - use-package-always-defer t - load-prefer-newer t - default-input-method nil - use-dialog-box nil - use-file-dialog nil - use-package-expand-minimally t - package-enable-at-startup nil - use-package-enable-imenu-support t - auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist. - package-archives '(("melpa" . "https://melpa.org/packages/") - ("gnu" . "https://elpa.gnu.org/packages/") - ("nongnu" . "https://elpa.nongnu.org/nongnu/") - ("melpa-stable" . "https://stable.melpa.org/packages/")) - package-archive-priorities '(("gnu" . 99) - ("nongnu" . 80) - ("melpa" . 70) - ("melpa-stable" . 50)) - ) - ;;; early-init.el ends here + ;;; Commentary: + ;;; Prevents white flash and better Emacs defaults + ;;; Code: + (set-language-environment "UTF-8") + (setq-default +default-frame-alist +'((background-color . "#1e1e2e") + (bottom-divider-width . 1) ; Thin horizontal window divider + (foreground-color . "#bac2de") ; Default foreground color + (fullscreen . maximized) ; Maximize the window by default + (horizontal-scroll-bars . nil) ; No horizontal scroll-bars + (left-fringe . 8) ; Thin left fringe + (menu-bar-lines . 0) ; No menu bar + (right-divider-width . 1) ; Thin vertical window divider + (right-fringe . 8) ; Thin right fringe + (tool-bar-lines . 0) ; No tool bar + (undecorated . t) ; Remove extraneous X decorations + (vertical-scroll-bars . nil)) ; No vertical scroll-bars +user-full-name "Henrov henrov" ; ME! +;; memory configuration +;; Higher garbage collection threshold, prevents frequent gc locks, reset later +gc-cons-threshold most-positive-fixnum +;; Ignore warnings for (obsolete) elisp compilations +byte-compile-warnings '(not obsolete) +;; And other log types completely +warning-suppress-log-types '((comp) (bytecomp)) +;; Large files are okay in the new millenium. +large-file-warning-threshold 100000000 +;; dont show garbage collection messages at startup, will reset later +garbage-collection-messages nil +;; native compilation +package-native-compile t +native-comp-warning-on-missing-source nil +native-comp-async-report-warnings-errors 'silent +;; Read more based on system pipe capacity +read-process-output-max (max (* 10240 10240) read-process-output-max) +;; scroll configuration +scroll-margin 0 ; Lets scroll to the end of the margin +scroll-conservatively 100000 ; Never recenter the window +scroll-preserve-screen-position 1 ; Scrolling back and forth +;; frame config +;; Improve emacs startup time by not resizing to adjust for custom settings +frame-inhibit-implied-resize t +;; Dont resize based on character height / width but to exact pixels +frame-resize-pixelwise t +;; backups & files +backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter +backup-by-copying t ; Don't clobber symlinks +create-lockfiles nil ; Don't have temp files +delete-old-versions t ; Cleanup automatically +kept-new-versions 6 ; Update every few times +kept-old-versions 2 ; And cleanup even more +version-control t ; Version them backups +delete-by-moving-to-trash t ; Dont delete, send to trash instead +;; startup +inhibit-startup-screen t ; I have already done the tutorial. Twice +inhibit-startup-message t ; I know I am ready +inhibit-startup-echo-area-message t ; Yep, still know it +initial-scratch-message nil ; I know it is the scratch buffer! +initial-buffer-choice nil +inhibit-startup-buffer-menu t +inhibit-x-resources t +initial-major-mode 'fundamental-mode +pgtk-wait-for-event-timeout 0.001 ; faster child frames +ad-redefinition-action 'accept ; dont care about legacy things being redefined +inhibit-compacting-font-caches t +;; tabs +tab-width 4 ; Always tab 4 spaces. +indent-tabs-mode nil ; Never use actual tabs. +;; rendering +cursor-in-non-selected-windows nil ; dont render cursors other windows +;; packages +use-package-always-defer t +load-prefer-newer t +default-input-method nil +use-dialog-box nil +use-file-dialog nil +use-package-expand-minimally t +package-enable-at-startup nil +use-package-enable-imenu-support t +auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist. +package-archives '(("melpa" . "https://melpa.org/packages/") + ("gnu" . "https://elpa.gnu.org/packages/") + ("nongnu" . "https://elpa.nongnu.org/nongnu/") + ("melpa-stable" . "https://stable.melpa.org/packages/")) +package-archive-priorities '(("gnu" . 99) + ("nongnu" . 80) + ("melpa" . 70) + ("melpa-stable" . 50)) +) +;;; early-init.el ends here diff --git a/henrovnix_ok/home/dev/emacs/init.el b/henrovnix_ok/home/dev/emacs/init.el index 573695006..932195993 100644 --- a/henrovnix_ok/home/dev/emacs/init.el +++ b/henrovnix_ok/home/dev/emacs/init.el @@ -1,400 +1,400 @@ ;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*- - ;;; Commentary: - ;;; Simple Emacs setup I carry everywhere +;;; Commentary: +;;; Simple Emacs setup I carry everywhere - ;;; Code: +;;; Code: (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) (package-initialize) (defun reset-custom-vars () - "Resets the custom variables that were set to crazy numbers" - (setopt gc-cons-threshold (* 1024 1024 100)) - (setopt garbage-collection-messages t)) +"Resets the custom variables that were set to crazy numbers" +(setopt gc-cons-threshold (* 1024 1024 100)) +(setopt garbage-collection-messages t)) (use-package emacs - :custom - (native-comp-async-query-on-exit t) - (read-answer-short t) - (use-short-answers t) - (enable-recursive-minibuffers t) - (which-func-update-delay 1.0) - (visible-bell nil) - (custom-buffer-done-kill t) - (whitespace-line-column nil) - (x-underline-at-descent-line t) - (imenu-auto-rescan t) - (uniquify-buffer-name-style 'forward) - (confirm-nonexistent-file-or-buffer nil) - (create-lockfiles nil) - (make-backup-files nil) - (kill-do-not-save-duplicates t) - (sentence-end-double-space nil) - (treesit-enabled-modes t) - :init - ;; base visual - (menu-bar-mode -1) ;; no menu bar - (toggle-scroll-bar -1) ;; no scroll bar - (tool-bar-mode -1) ;; no tool bar either - (blink-cursor-mode -1) ;; stop blinking +:custom +(native-comp-async-query-on-exit t) +(read-answer-short t) +(use-short-answers t) +(enable-recursive-minibuffers t) +(which-func-update-delay 1.0) +(visible-bell nil) +(custom-buffer-done-kill t) +(whitespace-line-column nil) +(x-underline-at-descent-line t) +(imenu-auto-rescan t) +(uniquify-buffer-name-style 'forward) +(confirm-nonexistent-file-or-buffer nil) +(create-lockfiles nil) +(make-backup-files nil) +(kill-do-not-save-duplicates t) +(sentence-end-double-space nil) +(treesit-enabled-modes t) +:init +;; base visual +(menu-bar-mode -1) ;; no menu bar +(toggle-scroll-bar -1) ;; no scroll bar +(tool-bar-mode -1) ;; no tool bar either +(blink-cursor-mode -1) ;; stop blinking - ;; font of the century - (set-frame-font "Aporetic Sans Mono 12" nil t) +;; font of the century +(set-frame-font "Aporetic Sans Mono 12" nil t) - :bind - (("C-" . pixel-scroll-precision) ; dont zoom in please, just scroll - ("C-" . pixel-scroll-precision) ; dont zoom in either, just scroll - ("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask - :hook - (text-mode . delete-trailing-whitespace-mode) - (prog-mode . delete-trailing-whitespace-mode) - (after-init . global-display-line-numbers-mode) ;; always show line numbers - (after-init . column-number-mode) ;; column number in the mode line - (after-init . size-indication-mode) ;; file size in the mode line - (after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll - (after-init . electric-pair-mode) ;; i mean ... parens should auto create - (after-init . reset-custom-vars) - ) +:bind +(("C-" . pixel-scroll-precision) ; dont zoom in please, just scroll + ("C-" . pixel-scroll-precision) ; dont zoom in either, just scroll + ("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask +:hook +(text-mode . delete-trailing-whitespace-mode) +(prog-mode . delete-trailing-whitespace-mode) +(after-init . global-display-line-numbers-mode) ;; always show line numbers +(after-init . column-number-mode) ;; column number in the mode line +(after-init . size-indication-mode) ;; file size in the mode line +(after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll +(after-init . electric-pair-mode) ;; i mean ... parens should auto create +(after-init . reset-custom-vars) +) (use-package autorevert - :ensure nil - :custom - (auto-revert-interval 3) - (auto-revert-remote-files nil) - (auto-revert-use-notify t) - (auto-revert-avoid-polling nil) - (auto-revert-verbose t) - :hook - (after-init . global-auto-revert-mode)) +:ensure nil +:custom +(auto-revert-interval 3) +(auto-revert-remote-files nil) +(auto-revert-use-notify t) +(auto-revert-avoid-polling nil) +(auto-revert-verbose t) +:hook +(after-init . global-auto-revert-mode)) (use-package recentf - :ensure nil - :commands (recentf-mode recentf-cleanup) - :hook - (after-init . recentf-mode) - :custom - (recentf-auto-cleanup 'never) - (recentf-exclude - (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$" - "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$" - "\\.7z$" "\\.rar$" - "COMMIT_EDITMSG\\'" - "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$" - "-autoloads\\.el$" "autoload\\.el$")) +:ensure nil +:commands (recentf-mode recentf-cleanup) +:hook +(after-init . recentf-mode) +:custom +(recentf-auto-cleanup 'never) +(recentf-exclude + (list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$" + "\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$" + "\\.7z$" "\\.rar$" + "COMMIT_EDITMSG\\'" + "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$" + "-autoloads\\.el$" "autoload\\.el$")) - :config - ;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before - ;; `recentf-save-list', allowing stale entries to be removed before the list - ;; is saved by `recentf-save-list', which is automatically added to - ;; `kill-emacs-hook' by `recentf-mode'. - (add-hook 'kill-emacs-hook #'recentf-cleanup -90)) +:config +;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before +;; `recentf-save-list', allowing stale entries to be removed before the list +;; is saved by `recentf-save-list', which is automatically added to +;; `kill-emacs-hook' by `recentf-mode'. +(add-hook 'kill-emacs-hook #'recentf-cleanup -90)) (use-package savehist - :ensure nil - :commands (savehist-mode savehist-save) - :hook - (after-init . savehist-mode) - :custom - (savehist-autosave-interval 600) - (savehist-additional-variables - '(kill-ring ; clipboard - register-alist ; macros - mark-ring global-mark-ring ; marks - search-ring regexp-search-ring))) +:ensure nil +:commands (savehist-mode savehist-save) +:hook +(after-init . savehist-mode) +:custom +(savehist-autosave-interval 600) +(savehist-additional-variables + '(kill-ring ; clipboard + register-alist ; macros + mark-ring global-mark-ring ; marks + search-ring regexp-search-ring))) (use-package hl-line - :ensure nil - :custom - (hl-line-sticky-flag nil) - (global-hl-line-sticky-flag nil) - :hook - (after-init . global-hl-line-mode)) +:ensure nil +:custom +(hl-line-sticky-flag nil) +(global-hl-line-sticky-flag nil) +:hook +(after-init . global-hl-line-mode)) (use-package saveplace - :ensure nil - :commands (save-place-mode save-place-local-mode) - :hook - (after-init . save-place-mode) - :custom - (save-place-limit 400)) +:ensure nil +:commands (save-place-mode save-place-local-mode) +:hook +(after-init . save-place-mode) +:custom +(save-place-limit 400)) (use-package nerd-icons - :custom - ;; disable bright icon colors - (nerd-icons-color-icons nil))hells.nix +:custom +;; disable bright icon colors +(nerd-icons-color-icons nil))hells.nix (use-package doom-modeline - :custom - (inhibit-compacting-font-caches t) ;; speed - (doom-modeline-buffer-file-name-style 'relative-from-project) - (doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you - (doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway - (doom-modeline-buffer-state-icon nil) ;; the filename already shows me - (doom-modeline-lsp nil) ;; lsp state is too distracting, too often - :hook (after-init . doom-modeline-mode)) +:custom +(inhibit-compacting-font-caches t) ;; speed +(doom-modeline-buffer-file-name-style 'relative-from-project) +(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you +(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway +(doom-modeline-buffer-state-icon nil) ;; the filename already shows me +(doom-modeline-lsp nil) ;; lsp state is too distracting, too often +:hook (after-init . doom-modeline-mode)) (load-theme 'catppuccin :no-confirm) -(use-package diminish :demand t) ;; declutter the modeline +(use-package diminish :demand t) ;; declutter the modeline (use-package eldoc - :diminish eldoc-mode - :custom - (eldoc-echo-area-use-multiline-p nil)) ;; docs for everything +:diminish eldoc-mode +:custom +(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything (use-package eldoc-box - :defer t - :config - (set-face-background 'eldoc-box-border (catppuccin-color 'green)) - (set-face-background 'eldoc-box-body (catppuccin-color 'base)) - :bind - (("M-h" . eldoc-box-help-at-point))) +:defer t +:config +(set-face-background 'eldoc-box-border (catppuccin-color 'green)) +(set-face-background 'eldoc-box-body (catppuccin-color 'base)) +:bind +(("M-h" . eldoc-box-help-at-point))) (use-package pulsar - :commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry - :init - (defface pulsar-catppuccin - `((default :extend t) - (((class color) (min-colors 88) (background light)) - :background ,(catppuccin-color 'sapphire)) - (((class color) (min-colors 88) (background dark)) - :background ,(catppuccin-color 'sapphire)) - (t :inverse-video t)) - "Alternative nord face for `pulsar-face'." - :group 'pulsar-faces) - :custom - (pulsar-face 'pulsar-catppuccin) - :hook - (after-init . pulsar-global-mode)) +:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry +:init +(defface pulsar-catppuccin +`((default :extend t) + (((class color) (min-colors 88) (background light)) + :background ,(catppuccin-color 'sapphire)) + (((class color) (min-colors 88) (background dark)) + :background ,(catppuccin-color 'sapphire)) + (t :inverse-video t)) +"Alternative nord face for `pulsar-face'." +:group 'pulsar-faces) +:custom +(pulsar-face 'pulsar-catppuccin) +:hook +(after-init . pulsar-global-mode)) (use-package which-key - :commands which-key-mode - :diminish which-key-mode - :hook - (after-init . which-key-mode)) +:commands which-key-mode +:diminish which-key-mode +:hook +(after-init . which-key-mode)) (use-package expreg - :bind ("M-m" . expreg-expand)) +:bind ("M-m" . expreg-expand)) (use-package vundo) ;; undo tree ;; better structured editing (use-package puni - :commands puni-global-mode - :hook - (after-init . puni-global-mode)) +:commands puni-global-mode +:hook +(after-init . puni-global-mode)) (use-package avy - :bind - ("M-i" . avy-goto-char-2) - :custom - (avy-background t)) +:bind +("M-i" . avy-goto-char-2) +:custom +(avy-background t)) (use-package consult - :bind - ("C-x b" . consult-buffer) ;; orig. switch-to-buffer - ("M-y" . consult-yank-pop) ;; orig. yank-pop - ("M-g M-g" . consult-goto-line) ;; orig. goto-line - ("M-g i" . consult-imenu) ;; consult version is interactive - ("M-g r" . consult-ripgrep) ;; find in project also works - :custom - (consult-narrow-key "<")) +:bind +("C-x b" . consult-buffer) ;; orig. switch-to-buffer +("M-y" . consult-yank-pop) ;; orig. yank-pop +("M-g M-g" . consult-goto-line) ;; orig. goto-line +("M-g i" . consult-imenu) ;; consult version is interactive +("M-g r" . consult-ripgrep) ;; find in project also works +:custom +(consult-narrow-key "<")) (use-package vertico - :commands vertico-mode - :custom - (read-file-name-completion-ignore-case t) - (read-buffer-completion-ignore-case t) - (completion-ignore-case t) - (enable-recursive-minibuffers t) - (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) - :init - (vertico-mode) - :hook - (minibuffer-setup-hook . cursor-intangible-mode)) +:commands vertico-mode +:custom +(read-file-name-completion-ignore-case t) +(read-buffer-completion-ignore-case t) +(completion-ignore-case t) +(enable-recursive-minibuffers t) +(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) +:init +(vertico-mode) +:hook +(minibuffer-setup-hook . cursor-intangible-mode)) (use-package marginalia - :commands marginalia-mode - :hook (after-init . marginalia-mode)) +:commands marginalia-mode +:hook (after-init . marginalia-mode)) (use-package crux - :bind - ("C-c M-e" . crux-find-user-init-file) - ("C-c C-w" . crux-transpose-windows) - ("C-c M-d" . crux-find-current-directory-dir-locals-file) - ("C-a" . crux-move-beginning-of-line)) +:bind +("C-c M-e" . crux-find-user-init-file) +("C-c C-w" . crux-transpose-windows) +("C-c M-d" . crux-find-current-directory-dir-locals-file) +("C-a" . crux-move-beginning-of-line)) (use-package magit - :bind (("C-M-g" . magit-status))) +:bind (("C-M-g" . magit-status))) (use-package nerd-icons-corfu - :commands nerd-icons-corfu-formatter - :defines corfu-margin-formatters) +:commands nerd-icons-corfu-formatter +:defines corfu-margin-formatters) (use-package corfu - :commands global-corfu-mode - :custom - (corfu-cycle t) - (corfu-auto t) - (corfu-auto-delay 1) - (corfu-auto-prefix 3) - (corfu-separator ?_) - :hook - (after-init . global-corfu-mode) - :config - (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) +:commands global-corfu-mode +:custom +(corfu-cycle t) +(corfu-auto t) +(corfu-auto-delay 1) +(corfu-auto-prefix 3) +(corfu-separator ?_) +:hook +(after-init . global-corfu-mode) +:config +(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (use-package cape) (use-package orderless - :custom - (completion-styles '(orderless partial-completion basic)) - (completion-category-defaults nil) - (completion-category-overrides nil)) +:custom +(completion-styles '(orderless partial-completion basic)) +(completion-category-defaults nil) +(completion-category-overrides nil)) (use-package yasnippet - :commands yas-global-mode - :diminish yas-minor-mode - :hook - (after-init . yas-global-mode)) +:commands yas-global-mode +:diminish yas-minor-mode +:hook +(after-init . yas-global-mode)) (use-package yasnippet-snippets :after yasnippet) (use-package exec-path-from-shell - :commands exec-path-from-shell-initialize - :custom - (exec-path-from-shell-arguments nil) - :hook - (after-init . exec-path-from-shell-initialize)) +:commands exec-path-from-shell-initialize +:custom +(exec-path-from-shell-arguments nil) +:hook +(after-init . exec-path-from-shell-initialize)) (use-package nixpkgs-fmt - :custom - (nixpkgs-fmt-command "nixfmt")) +:custom +(nixpkgs-fmt-command "nixfmt")) (use-package eat - :bind - (("C-c e p" . eat-project) - ("C-c e t" . eat))) +:bind +(("C-c e p" . eat-project) + ("C-c e t" . eat))) (use-package f :demand t) (use-package envrc - :commands envrc-global-mode - :hook - (after-init . envrc-global-mode)) +:commands envrc-global-mode +:hook +(after-init . envrc-global-mode)) (use-package gptel - :commands gptel-make-anthropic f-read-text - :config - (gptel-make-anthropic "Claude" - :stream t :key (f-read-text "/run/secrets/claude_key"))) +:commands gptel-make-anthropic f-read-text +:config +(gptel-make-anthropic "Claude" +:stream t :key (f-read-text "/run/secrets/claude_key"))) (use-package sideline-flymake) (use-package sideline-eglot) (use-package sideline - :custom - (sideline-backends-right '(sideline-flymake sideline-eglot)) - :hook - (eglot-managed-mode . sideline-mode) - (flymake-mode . sideline-mode)) +:custom +(sideline-backends-right '(sideline-flymake sideline-eglot)) +:hook +(eglot-managed-mode . sideline-mode) +(flymake-mode . sideline-mode)) (use-package eglot - :custom - (eglot-extend-to-xref t) - (eglot-ignored-server-capabilities '(:inlayHintProvider)) - (jsonrpc-event-hook nil) - :hook - (eglot-managed-mode . eldoc-box-hover-mode) - (before-save . eldoc-format-buffer) - :bind - (:map eglot-mode-map - ("C-c l a" . eglot-code-actions) - ("C-c l r" . eglot-rename) - ("C-c l h" . eldoc) - ("C-c l g" . xref-find-references) - ("C-c l w" . eglot-reconnect))) +:custom +(eglot-extend-to-xref t) +(eglot-ignored-server-capabilities '(:inlayHintProvider)) +(jsonrpc-event-hook nil) +:hook +(eglot-managed-mode . eldoc-box-hover-mode) +(before-save . eldoc-format-buffer) +:bind +(:map eglot-mode-map + ("C-c l a" . eglot-code-actions) + ("C-c l r" . eglot-rename) + ("C-c l h" . eldoc) + ("C-c l g" . xref-find-references) + ("C-c l w" . eglot-reconnect))) (use-package proced - :custom - (proced-auto-update-flag t) - (proced-auto-update-interval 3) - (proced-enable-color-flag t) - (proced-show-remote-processes t)) +:custom +(proced-auto-update-flag t) +(proced-auto-update-interval 3) +(proced-enable-color-flag t) +(proced-show-remote-processes t)) (use-package org - :ensure t - :defer t - :commands (org-mode org-capture org-agenda) - :init - (defvar org-journal-file "~/nextcloud/org/journal.org") - (defvar org-archive-file "~/nextcloud/org/archive.org") - (defvar org-notes-file "~/nextcloud/org/notes.org") - (defvar org-inbox-file "~/nextcloud/org/inbox.org") - (defvar org-work-file "~/nextcloud/org/work.org") - (defun my/org-capture-project-target-heading () - "Determine Org target headings from the current file's project path. +:ensure t +:defer t +:commands (org-mode org-capture org-agenda) +:init +(defvar org-journal-file "~/nextcloud/org/journal.org") +(defvar org-archive-file "~/nextcloud/org/archive.org") +(defvar org-notes-file "~/nextcloud/org/notes.org") +(defvar org-inbox-file "~/nextcloud/org/inbox.org") +(defvar org-work-file "~/nextcloud/org/work.org") +(defun my/org-capture-project-target-heading () +"Determine Org target headings from the current file's project path. - This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'. - It extracts 'COMPANY' and 'PROJECT' to use as nested headlines - for an Org capture template. +This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'. +It extracts 'COMPANY' and 'PROJECT' to use as nested headlines +for an Org capture template. - If the current buffer is not visi +If the current buffer is not visi ting a file within such a - project structure, it returns nil, causing capture to default to - the top of the file." - (when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer - (let ((path-parts (split-string path "/" t " "))) - (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=)) - (company (nth (+ 1 projects-pos) path-parts)) - (project (nth (+ 2 projects-pos) path-parts))) - ;; Return a list of headlines for Org to find or create. - (list company project))))) - :bind - (("C-c c" . org-capture) - ("C-c i" . org-store-link) - ("C-c a" . org-agenda) - :map org-mode-map - ("C-c t" . org-toggle-inline-images) - ("C-c l" . org-toggle-link-display)) - :custom - (org-agenda-files (list org-inbox-file org-journal-file)) - (org-directory "~/nextcloud/org") - (org-default-notes-file org-inbox-file) - (org-archive-location (concat org-archive-file "::* From %s")) - (org-log-done 'time) - (org-log-into-drawer t) - (org-hide-emphasis-markers t) - (org-src-fontify-natively t) - (org-src-tab-acts-natively t) - (org-capture-templates '(("t" "Todo" entry (file org-inbox-file) - "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)") - ("j" "Journal" entry (file+olp+datetree org-journal-file) - "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") - ("n" "Note" entry (file org-notes-file) - "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") - ("p" "Project Task" item - (file+function org-work-file my/org-capture-project-target-heading) - "* TODO %? \n CLOCK: %U" - )) - ) - :config - ;; Enable syntax highlighting in code blocks - (add-hook 'org-mode-hook 'turn-on-font-lock) - (add-hook 'org-mode-hook 'org-indent-mode)) +project structure, it returns nil, causing capture to default to +the top of the file." +(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer + (let ((path-parts (split-string path "/" t " "))) + (when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=)) + (company (nth (+ 1 projects-pos) path-parts)) + (project (nth (+ 2 projects-pos) path-parts))) + ;; Return a list of headlines for Org to find or create. + (list company project))))) +:bind +(("C-c c" . org-capture) + ("C-c i" . org-store-link) + ("C-c a" . org-agenda) + :map org-mode-map + ("C-c t" . org-toggle-inline-images) + ("C-c l" . org-toggle-link-display)) +:custom +(org-agenda-files (list org-inbox-file org-journal-file)) +(org-directory "~/nextcloud/org") +(org-default-notes-file org-inbox-file) +(org-archive-location (concat org-archive-file "::* From %s")) +(org-log-done 'time) +(org-log-into-drawer t) +(org-hide-emphasis-markers t) +(org-src-fontify-natively t) +(org-src-tab-acts-natively t) +(org-capture-templates '(("t" "Todo" entry (file org-inbox-file) + "* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)") + ("j" "Journal" entry (file+olp+datetree org-journal-file) + "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") + ("n" "Note" entry (file org-notes-file) + "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n") + ("p" "Project Task" item + (file+function org-work-file my/org-capture-project-target-heading) + "* TODO %? \n CLOCK: %U" + )) + ) +:config +;; Enable syntax highlighting in code blocks +(add-hook 'org-mode-hook 'turn-on-font-lock) +(add-hook 'org-mode-hook 'org-indent-mode)) ;; extras (use-package comp-run - :ensure nil - :config - (push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list) - (push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list)) +:ensure nil +:config +(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list) +(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list)) (use-package rustic - :custom - (rustic-lsp-client 'eglot)) +:custom +(rustic-lsp-client 'eglot)) (provide 'init) - ;;; init.el ends here +;;; init.el ends here diff --git a/henrovnix_ok/home/dev/kitty.nix b/henrovnix_ok/home/dev/kitty.nix index 3f2779907..110d7a228 100644 --- a/henrovnix_ok/home/dev/kitty.nix +++ b/henrovnix_ok/home/dev/kitty.nix @@ -1,29 +1,30 @@ { config, pkgs, lib, flakeRoot, ... }: let 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) repoKittyConfText = - builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf"); + builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf"); in { xdg.enable = true; # 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 = { - enable = true; - # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order: - # 1) include theme - # 2) your repo config (keymaps etc.) - # 3) force opacity LAST so it always wins - extraConfig = '' - # 1) Theme first (stable path) - include themes/Catppuccin-Mocha.conf - # 2) Your repo config (may also include theme; harmless if duplicated) - ${repoKittyConfText} - # 3) Force transparency last (wins) - #background_opacity 0.60 - #dynamic_background_opacity yes - ''; + enable = true; + # Home Manager generates ~/.config/kitty/kitty.conf; we append in-order: + # 1) include theme + # 2) your repo config (keymaps etc.) + # 3) force opacity LAST so it always wins + extraConfig = '' + # 1) Theme first (stable path) + include themes/Catppuccin-Mocha.conf + # 2) Your repo config (may also include theme; harmless if duplicated) + ${repoKittyConfText} + # 3) Force transparency last (wins) + #background_opacity 0.60 + #dynamic_background_opacity yes + ''; }; } diff --git a/henrovnix_ok/home/dev/shells.nix b/henrovnix_ok/home/dev/shells.nix index b3db0331c..cd0d1bff5 100644 --- a/henrovnix_ok/home/dev/shells.nix +++ b/henrovnix_ok/home/dev/shells.nix @@ -1,8 +1,8 @@ # shells.nix — Home-Manager module # # Reads: -# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf -# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf +# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf +# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf # # For each enabled shell in [enabled_shells]: # - 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 ""; normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l); parseSections = text: - let - lines = map normalizeLine (lib.splitString "\n" text); - isHeader = l: - let s = l; - in lib.hasPrefix "[" s - && lib.hasSuffix "]" s - && builtins.stringLength s >= 3; - nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l); - folded = - builtins.foldl' - (st: l: - if l == "" then st else - if isHeader l then st // { current = nameOf l; } - else - let - cur = st.current; - prev = st.sections.${cur} or []; - in - st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; } - ) - { current = "__root__"; sections = {}; } - lines; - in - folded.sections; + let + lines = map normalizeLine (lib.splitString "\n" text); + isHeader = l: + let s = l; + in lib.hasPrefix "[" s + && lib.hasSuffix "]" s + && builtins.stringLength s >= 3; + nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l); + folded = + builtins.foldl' + (st: l: + if l == "" then st else + if isHeader l then st // { current = nameOf l; } + else + let + cur = st.current; + prev = st.sections.${cur} or []; + in + st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; } + ) + { current = "__root__"; sections = {}; } + lines; + in + folded.sections; enabledSections = parseSections (readMaybe enabledFile); - aliasSections = parseSections (readMaybe aliasesFile); + aliasSections = parseSections (readMaybe aliasesFile); # [enabled_shells] lines: key = yes/no enabledShells = - let - raw = enabledSections.enabled_shells or []; - parseKV = l: - let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l; - in if m == null then null else { - k = trim (builtins.elemAt m 0); - v = lib.toLower (trim (builtins.elemAt m 1)); - }; - kvs = builtins.filter (x: x != null) (map parseKV raw); - in - map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs); + let + raw = enabledSections.enabled_shells or []; + parseKV = l: + let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l; + in if m == null then null else { + k = trim (builtins.elemAt m 0); + v = lib.toLower (trim (builtins.elemAt m 1)); + }; + kvs = builtins.filter (x: x != null) (map parseKV raw); + in + map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs); shellEnabled = shell: builtins.elem shell enabledShells; # ---------- per-shell repo config file (.conf) ---------- shellConfPath = shell: terminalDir + "/${shell}.conf"; shellConfExists = shell: builtins.pathExists (shellConfPath shell); sourceIfExistsSh = p: '' - if [ -f "${toString p}" ]; then - source "${toString p}" - fi + if [ -f "${toString p}" ]; then + source "${toString p}" + fi ''; # ---------- aliases section helpers ---------- secLines = name: aliasSections.${name} or []; @@ -80,55 +80,55 @@ let fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish"; # Seeds (created once; user can edit afterwards) bashSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - # - ${secText "bash_zsh"} - ${secText "bash_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + # + ${secText "bash_zsh"} + ${secText "bash_specific"} + ''; zshSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - ${secText "bash_zsh"} - ${secText "zsh_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + ${secText "bash_zsh"} + ${secText "zsh_specific"} + ''; # Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is parsePosixAlias = l: + let + m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l; + in + if m == null then null else 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 - if m == null then null else - 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; }; + { inherit name; cmd = unquote; }; escapeForFish = s: - lib.replaceStrings - [ "\\" "\"" "$" "`" ] - [ "\\\\" "\\\"" "\\$" "\\`" ] - s; + lib.replaceStrings + [ "\\" "\"" "$" "`" ] + [ "\\\\" "\\\"" "\\$" "\\`" ] + s; fishTranslated = - let - parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh")); - in - lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed); + let + parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh")); + in + lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed); fishSeed = '' - # Created once from: ${toString aliasesFile} - # Edit freely; Home Manager will not overwrite this file. - status is-interactive; or exit - # Translated from [bash_zsh]: - ${fishTranslated} - # From [fish_specific]: - ${secText "fish_specific"} - ''; + # Created once from: ${toString aliasesFile} + # Edit freely; Home Manager will not overwrite this file. + status is-interactive; or exit + # Translated from [bash_zsh]: + ${fishTranslated} + # From [fish_specific]: + ${secText "fish_specific"} + ''; in { xdg.enable = true; @@ -137,70 +137,70 @@ in programs.zsh.enable = shellEnabled "zsh"; programs.fish.enable = shellEnabled "fish"; home.packages = - (lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++ - (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]); + (lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++ + (lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]); # Source per-shell repo config (if present) AND source the user alias file (if it exists). # Important: define each option only ONCE. programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))} - if [ -f "${bashAliasesPath}" ]; then - source "${bashAliasesPath}" - fi + ${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))} + if [ -f "${bashAliasesPath}" ]; then + source "${bashAliasesPath}" + fi ''); programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))} - if [ -f "${zshAliasesPath}" ]; then - source "${zshAliasesPath}" - fi + ${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))} + if [ -f "${zshAliasesPath}" ]; then + source "${zshAliasesPath}" + fi ''); programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter '' - ${lib.optionalString (shellConfExists "fish") '' - if test -f "${toString (shellConfPath "fish")}" - source "${toString (shellConfPath "fish")}" - end - ''} - if test -f "${fishAliasesPath}" - source "${fishAliasesPath}" - end + ${lib.optionalString (shellConfExists "fish") '' + if test -f "${toString (shellConfPath "fish")}" + source "${toString (shellConfPath "fish")}" + end + ''} + if test -f "${fishAliasesPath}" + source "${fishAliasesPath}" + end ''); # Create/remove alias files based on enabled shells home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] '' set -euo pipefail # bash ------------------------------------------------------- if ${if shellEnabled "bash" then "true" else "false"}; then - cat > "${bashAliasesPath}" <<'EOF' + cat > "${bashAliasesPath}" <<'EOF' ${bashSeed} EOF else - rm -f "${bashAliasesPath}" + rm -f "${bashAliasesPath}" fi # zsh ------------------------------------------------------- if ${if shellEnabled "zsh" then "true" else "false"}; then - cat > "${zshAliasesPath}" <<'EOF' + cat > "${zshAliasesPath}" <<'EOF' ${zshSeed} EOF else - rm -f "${zshAliasesPath}" + rm -f "${zshAliasesPath}" fi # fish ------------------------------------------------------- if ${if shellEnabled "fish" then "true" else "false"}; then - mkdir -p "$(dirname "${fishAliasesPath}")" - cat > "${fishAliasesPath}" <<'EOF' + mkdir -p "$(dirname "${fishAliasesPath}")" + cat > "${fishAliasesPath}" <<'EOF' ${fishSeed} EOF else - rm -f "${fishAliasesPath}" + rm -f "${fishAliasesPath}" fi - # fish - if ${if shellEnabled "fish" then "true" else "false"}; then - mkdir -p "$(dirname "${fishAliasesPath}")" - if [ ! -f "${fishAliasesPath}" ]; then - cat > "${fishAliasesPath}" <<'EOF' + # fish + if ${if shellEnabled "fish" then "true" else "false"}; then + mkdir -p "$(dirname "${fishAliasesPath}")" + if [ ! -f "${fishAliasesPath}" ]; then + cat > "${fishAliasesPath}" <<'EOF' ${fishSeed} EOF - fi - else - rm -f "${fishAliasesPath}" - fi + fi + else + rm -f "${fishAliasesPath}" + fi ''; } diff --git a/henrovnix_ok/home/dev/starship.nix b/henrovnix_ok/home/dev/starship.nix index 8c011a16b..a3c75eae2 100644 --- a/henrovnix_ok/home/dev/starship.nix +++ b/henrovnix_ok/home/dev/starship.nix @@ -10,10 +10,10 @@ in xdg.enable = true; programs.starship = { - enable = true; - enableZshIntegration = true; - enableBashIntegration = true; - enableFishIntegration = true; + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + enableFishIntegration = true; }; # Force the *actual conflicting option* (home.file."".source) diff --git a/henrovnix_ok/home/dev/zsh.nix b/henrovnix_ok/home/dev/zsh.nix index bbfd86cf6..9ee29ae87 100644 --- a/henrovnix_ok/home/dev/zsh.nix +++ b/henrovnix_ok/home/dev/zsh.nix @@ -1,26 +1,26 @@ { config, pkgs, lib, flakeRoot, ... }: { programs.zsh = { - enable = true; - enableCompletion = true; - autocd = true; - # Optional but recommended: keep zsh config in one dir (relative to $HOME) - dotDir = ".config/zsh"; - oh-my-zsh = { - enable = true; - theme = ""; - plugins = [ - "git" - "sudo" - "extract" - "colored-man-pages" - "command-not-found" - "history" - "docker" - "kubectl" - ]; - }; - autosuggestion.enable = true; - syntaxHighlighting.enable = true; + enable = true; + enableCompletion = true; + autocd = true; + # Optional but recommended: keep zsh config in one dir (relative to $HOME) + dotDir = ".config/zsh"; + oh-my-zsh = { + enable = true; + theme = ""; + plugins = [ + "git" + "sudo" + "extract" + "colored-man-pages" + "command-not-found" + "history" + "docker" + "kubectl" + ]; + }; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; }; } diff --git a/henrovnix_ok/machines/traveldroid/configuration.nix b/henrovnix_ok/machines/traveldroid/configuration.nix index 8d6f17709..d25a9a1fb 100755 --- a/henrovnix_ok/machines/traveldroid/configuration.nix +++ b/henrovnix_ok/machines/traveldroid/configuration.nix @@ -1,7 +1,7 @@ { user, ... } : { imports = - [ - ./hardware-configuration.nix - ../../configuration - ]; + [ + ./hardware-configuration.nix + ../../configuration + ]; } diff --git a/henrovnix_ok/machines/traveldroid/hardware-configuration.nix b/henrovnix_ok/machines/traveldroid/hardware-configuration.nix index 0b163988d..8bb98b89c 100755 --- a/henrovnix_ok/machines/traveldroid/hardware-configuration.nix +++ b/henrovnix_ok/machines/traveldroid/hardware-configuration.nix @@ -1,17 +1,17 @@ { - hostname, - pkgs, - lib, - modulesPath, - user, - config, - ... +hostname, +pkgs, +lib, +modulesPath, +user, +config, +... }: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ../../hardware/hardware.nix - ]; +imports = [ +(modulesPath + "/installer/scan/not-detected.nix") +../../hardware/hardware.nix +]; boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ]; boot.initrd.kernelModules = [ ]; @@ -19,19 +19,19 @@ boot.kernelModules = [ "kvm-intel" ]; boot.extraModulePackages = [ ]; fileSystems."/" = - { device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2"; - fsType = "ext4"; - }; +{ device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2"; +fsType = "ext4"; +}; fileSystems."/boot" = - { device = "/dev/disk/by-uuid/811D-0676"; - fsType = "vfat"; - options = [ "fmask=0077" "dmask=0077" ]; - }; +{ device = "/dev/disk/by-uuid/811D-0676"; +fsType = "vfat"; +options = [ "fmask=0077" "dmask=0077" ]; +}; swapDevices = - [ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; } - ]; +[ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; } +]; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; diff --git a/henrovnix_ok/machines/traveldroid/home.nix b/henrovnix_ok/machines/traveldroid/home.nix index b76d5b345..7eb2990c4 100644 --- a/henrovnix_ok/machines/traveldroid/home.nix +++ b/henrovnix_ok/machines/traveldroid/home.nix @@ -1,15 +1,15 @@ { pkgs, ... }: { imports = [ - ../../home + ../../home ]; home.packages = with pkgs; [ - brightnessctl + brightnessctl ]; wayland.windowManager.hyprland = { - extraConfig = '' - # Default portable monitor rule - monitor=DP-1,3840x1080@144,1920x0,1 - ''; + extraConfig = '' + # Default portable monitor rule + monitor=DP-1,3840x1080@144,1920x0,1 + ''; }; } diff --git a/henrovnix_ok/no block b/henrovnix_ok/no block index 8d10931cd..dff92444d 100644 --- a/henrovnix_ok/no block +++ b/henrovnix_ok/no block @@ -37,13 +37,13 @@ nmcli connection show --active nmcli device status find ~/Repos/nixos/henrovnix_ok \ - -type d -name ".*" -prune -o \ - -type f -print0 \ +-type d -name ".*" -prune -o \ +-type f -print0 \ | xargs -0 sed -i 's/==/YOUR_USER/g' find ~/Repos/nixos/henrovnix_ok \ - -type d -name ".*" -prune -o \ - -type f -print0 \ +-type d -name ".*" -prune -o \ +-type f -print0 \ | xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g' mv ./machines/machine1 ./machines/YOUR_HOSTNAME