2895 lines
97 KiB
Org Mode
Executable File
2895 lines
97 KiB
Org Mode
Executable File
f#+OPTIONS: toc:nil broken-links:t
|
||
#+PROPERTY: header-args :noweb yes :results silent :mkdirp yes
|
||
|
||
#+HTML: <div align="center">
|
||
#+HTML: <div>
|
||
#+HTML: <img src="./.github/images/nixos.svg" width="100px" alt="NixOS" />
|
||
#+HTML: <img src="./.github/images/emacs.svg" width="100px" alt="Emacs" />
|
||
#+HTML: </div>
|
||
#+HTML: <br />
|
||
#+HTML: <h1>Henrov's Literate System Configuration</h1>
|
||
#+HTML: <div>
|
||
#+HTML: <a href="https://orgmode.org/index.html">
|
||
#+HTML: <img src="https://img.shields.io/badge/org_mode-9.7-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=org&logoColor=a6e3a1&color=1e1e2e" alt="Org mode" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://nixos.org">
|
||
#+HTML: <img src="https://img.shields.io/badge/NixOS-unstable-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=NixOS&logoColor=89b4fa&color=1e1e2e" alt="NixOS" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://www.gnu.org/software/emacs/">
|
||
#+HTML: <img src="https://img.shields.io/badge/emacs-30-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=gnuemacs&logoColor=cba6f7&color=1e1e2e" alt="Emacs" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://github.com/gamedolphin/system/blob/main/LICENSE">
|
||
#+HTML: <img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=GPL&colorA=1e1e2e&colorB=f38ba8&logo=unlicense&logoColor=f9e2af" alt="License" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://github.com/gamedolphin/system/actions/workflows/tangle.yml">
|
||
#+HTML: <img src="https://img.shields.io/github/actions/workflow/status/gamedolphin/system/tangle.yml?style=for-the-badge&label=Tangle&colorA=1e1e2e&colorB=a6e3a1&logo=github&logoColor=cdd6f4" alt="Tangle workflow" />
|
||
#+HTML: </a>
|
||
#+HTML: </div>
|
||
#+HTML: </div>
|
||
|
||
* Introduction
|
||
#+HTML: <div align="center"><img src="./.github/images/screenshot.png" width="100%" alt="Screenshot" /></div>
|
||
|
||
This literate document describes and generates the configuration for the systems in this repository. It contains source blocks that are exported into individual files using Emacs Org mode’s tangling mechanism. The exported files are then evaluated as a NixOS flake to produce an immutable system configuration.
|
||
|
||
This repository currently includes configuration for:
|
||
|
||
* =traveldroid= — main workstation/laptop
|
||
|
||
To generate the Nix files, open this file in Emacs and run =M-x org-babel-tangle=.
|
||
|
||
Alternatively, run the following from the command line:
|
||
|
||
#+begin_src bash :tangle no
|
||
emacs README.org --batch -f org-babel-tangle
|
||
#+end_src
|
||
|
||
Once the Nix files are generated, deploy using:
|
||
|
||
#+begin_src bash :tangle no
|
||
nixos-rebuild switch --flake .#<machine>
|
||
#+end_src
|
||
|
||
Other files in this repo include:
|
||
|
||
* ~flake.lock~ for pinning input versions.
|
||
* ~assets/*~ for non-Nix-managed artifacts such as images and wallpapers.
|
||
#- ~secrets/secrets.yaml~ for encrypted secrets edited using ~sops~.
|
||
|
||
Generated outputs should not be edited directly. A CI workflow can tangle and commit generated outputs when they differ.
|
||
|
||
** Emacs + Org + Tangle
|
||
|
||
* [[[https://www.gnu.org/software/emacs/][Emacs](https://www.gnu.org/software/emacs/][Emacs)]] is used as the editor and execution environment for this literate configuration.
|
||
* [[[https://orgmode.org/][Org](https://orgmode.org/][Org) mode]] provides the document structure and the source block execution model used here.
|
||
* 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.
|
||
|
||
** Nix & NixOS
|
||
|
||
* [[[https://nix.dev/][Nix](https://nix.dev/][Nix)]] is used to define packages, environments, and configuration as pure expressions.
|
||
* [[[https://nixos.org/][NixOS](https://nixos.org/][NixOS)]] evaluates Nix expressions into a complete system configuration that can be applied by rebuild operations.
|
||
|
||
** Repository layout and folder conventions
|
||
#+HTML: <p>
|
||
#+HTML: This repository contains system modules, user modules, and configuration fragments. The following directories are treated as separate layers:
|
||
#+HTML: <code>./configuration</code> (NixOS modules), <code>./home</code> (Home Manager modules), and <code>./assets/conf</code> (configuration fragments referenced or deployed by the modules).
|
||
#+HTML: </p>
|
||
#+HTML: <p>
|
||
#+HTML: To keep navigation consistent, the same internal substructure is used in all three locations. Each layer keeps its role; only the internal grouping is standardized.
|
||
#+HTML: </p>
|
||
|
||
** Shared domain folders
|
||
#+HTML: <ul>
|
||
#+HTML: <li><code>core/</code> – base settings and common infrastructure</li>
|
||
#+HTML: <li><code>desktop/</code> – graphical session, compositor, UI components, and integration</li>
|
||
#+HTML: <li><code>apps/</code> – application enablement and application-level configuration</li>
|
||
#+HTML: <li><code>services/</code> – background services and daemons</li>
|
||
#+HTML: <li><code>security/</code> – secrets handling and security-related configuration</li>
|
||
#+HTML: <li><code>dev/</code> – developer tooling and editor configuration</li>
|
||
#+HTML: </ul>
|
||
|
||
** Full tree (including unchanged parts)
|
||
#+HTML: <p>
|
||
#+HTML: The tree below shows the full repository layout, with the standardized internal structure applied only inside
|
||
#+HTML: <code>configuration/</code>, <code>home/</code>, and <code>assets/conf/</code>.
|
||
#+HTML: </p>
|
||
|
||
#+HTML: <pre><code>.
|
||
#+HTML: ├── flake.lock
|
||
#+HTML: ├── flake.nix
|
||
#+HTML: ├── README.org
|
||
#+HTML: ├── user.nix
|
||
#+HTML: ├── assets
|
||
#+HTML: │ ├── background.png
|
||
#+HTML: │ ├── conf
|
||
#+HTML: │ │ ├── apps
|
||
#+HTML: │ │ │ ├── flatpak.conf
|
||
#+HTML: │ │ │ └── packages.conf
|
||
#+HTML: │ │ ├── core
|
||
#+HTML: │ │ │ └── xdg
|
||
#+HTML: │ │ │ └── mimeapps.list
|
||
#+HTML: │ │ ├── desktop
|
||
#+HTML: │ │ │ ├── greeter
|
||
#+HTML: │ │ │ │ └── greeter.conf
|
||
#+HTML: │ │ │ ├── hypr
|
||
#+HTML: │ │ │ │ ├── bindings.conf
|
||
#+HTML: │ │ │ │ ├── hyprland.conf
|
||
#+HTML: │ │ │ │ ├── hyprland_no_blur.conf
|
||
#+HTML: │ │ │ │ └── hyprshell.conf
|
||
#+HTML: │ │ │ ├── terminal
|
||
#+HTML: │ │ │ │ (optional: desktop-facing terminal fragments if needed)
|
||
#+HTML: │ │ │ ├── wallpaper
|
||
#+HTML: │ │ │ │ └── wallpaper.conf
|
||
#+HTML: │ │ │ └── waybar
|
||
#+HTML: │ │ │ ├── config.jsonc
|
||
#+HTML: │ │ │ └── style.css
|
||
#+HTML: │ │ ├── dev
|
||
#+HTML: │ │ │ ├── hyprshell
|
||
#+HTML: │ │ │ │ ├── config.ron.bak
|
||
#+HTML: │ │ │ │ └── styles.css.bak
|
||
#+HTML: │ │ │ └── terminal
|
||
#+HTML: │ │ │ ├── aliases.conf
|
||
#+HTML: │ │ │ ├── kitty.conf
|
||
#+HTML: │ │ │ ├── starship.toml
|
||
#+HTML: │ │ │ └── zsh.conf
|
||
#+HTML: │ │ ├── security
|
||
#+HTML: │ │ │ └── ssh
|
||
#+HTML: │ │ │ └── ssh-client.conf
|
||
#+HTML: │ │ └── services
|
||
#+HTML: │ ├── lock.png
|
||
#+HTML: │ ├── scripts
|
||
#+HTML: │ └── wallpaper
|
||
#+HTML: │ ├── gif
|
||
#+HTML: │ ├── picture
|
||
#+HTML: │ │ ├── pexels-kseniachernaya-5691695.jpg
|
||
#+HTML: │ │ ├── pexels-lalesh-147635.jpg
|
||
#+HTML: │ │ ├── pexels-lucaspezeta-2212858.jpg
|
||
#+HTML: │ │ ├── pexels-themob000-28428584.jpg
|
||
#+HTML: │ │ └── pexels-themob000-28428592.jpg
|
||
#+HTML: │ └── videos
|
||
#+HTML: │ ├── dark_water_large.mp4
|
||
#+HTML: │ └── white_blobs_small.mp4
|
||
#+HTML: ├── configuration
|
||
#+HTML: │ ├── default.nix
|
||
#+HTML: │ ├── apps
|
||
#+HTML: │ │ ├── flatpak.nix
|
||
#+HTML: │ │ └── packages.nix
|
||
#+HTML: │ ├── core
|
||
#+HTML: │ │ ├── cli.nix
|
||
#+HTML: │ │ ├── files.nix
|
||
#+HTML: │ │ ├── locale.nix
|
||
#+HTML: │ │ ├── networking.nix
|
||
#+HTML: │ │ └── nix-settings.nix
|
||
#+HTML: │ ├── desktop
|
||
#+HTML: │ │ ├── audio.nix
|
||
#+HTML: │ │ ├── hyprland.nix
|
||
#+HTML: │ │ └── login.nix
|
||
#+HTML: │ ├── dev
|
||
#+HTML: │ │ └── boot.nix
|
||
#+HTML: │ ├── security
|
||
#+HTML: │ │ └── sops.nix
|
||
#+HTML: │ └── services
|
||
#+HTML: │ └── services.nix
|
||
#+HTML: ├── hardware
|
||
#+HTML: │ └── hardware.nix
|
||
#+HTML: ├── home
|
||
#+HTML: │ ├── default.nix
|
||
#+HTML: │ ├── apps
|
||
#+HTML: │ │ └── theme.nix
|
||
#+HTML: │ ├── core
|
||
#+HTML: │ │ └── unity.nix
|
||
#+HTML: │ ├── desktop
|
||
#+HTML: │ │ ├── hyprland.nix
|
||
#+HTML: │ │ ├── lock.nix
|
||
#+HTML: │ │ ├── walker.nix
|
||
#+HTML: │ │ ├── wallpaper.nix
|
||
#+HTML: │ │ └── waybar.nix
|
||
#+HTML: │ ├── dev
|
||
#+HTML: │ │ ├── dev.nix
|
||
#+HTML: │ │ ├── terminal.nix
|
||
#+HTML: │ │ └── emacs
|
||
#+HTML: │ │ ├── default.nix
|
||
#+HTML: │ │ ├── early-init.el
|
||
#+HTML: │ │ └── init.el
|
||
#+HTML: │ ├── security
|
||
#+HTML: │ ├── services
|
||
#+HTML: │ └── theme
|
||
#+HTML: │ └── theme.nix
|
||
#+HTML: ├── LICENSE
|
||
#+HTML: ├── machines
|
||
#+HTML: │ └── traveldroid
|
||
#+HTML: │ ├── configuration.nix
|
||
#+HTML: │ ├── hardware-configuration.nix
|
||
#+HTML: │ └── home.nix
|
||
#+HTML: ├── main
|
||
#+HTML: └── secrets
|
||
#+HTML: └── secrets.yaml
|
||
#+HTML: </code></pre>
|
||
|
||
** Notes
|
||
#+HTML: <ul>
|
||
#+HTML: <li>Only the internal layout of <code>configuration/</code>, <code>home/</code>, and <code>assets/conf/</code> is standardized; all other paths remain as currently organized.</li>
|
||
#+HTML: <li>The <code>services/</code> and <code>security/</code> folders are included for completeness even if initially empty in some layers.</li>
|
||
#+HTML: </ul>
|
||
f#+OPTIONS: toc:nil broken-links:t
|
||
#+PROPERTY: header-args :noweb yes :results silent :mkdirp yes
|
||
|
||
#+HTML: <div align="center">
|
||
#+HTML: <div>
|
||
#+HTML: <img src="./.github/images/nixos.svg" width="100px" alt="NixOS" />
|
||
#+HTML: <img src="./.github/images/emacs.svg" width="100px" alt="Emacs" />
|
||
#+HTML: </div>
|
||
#+HTML: <br />
|
||
#+HTML: <h1>Henrov's Literate System Configuration</h1>
|
||
#+HTML: <div>
|
||
#+HTML: <a href="https://orgmode.org/index.html">
|
||
#+HTML: <img src="https://img.shields.io/badge/org_mode-9.7-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=org&logoColor=a6e3a1&color=1e1e2e" alt="Org mode" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://nixos.org">
|
||
#+HTML: <img src="https://img.shields.io/badge/NixOS-unstable-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=NixOS&logoColor=89b4fa&color=1e1e2e" alt="NixOS" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://www.gnu.org/software/emacs/">
|
||
#+HTML: <img src="https://img.shields.io/badge/emacs-30-blue.svg?style=for-the-badge&labelColor=1e1e2e&logo=gnuemacs&logoColor=cba6f7&color=1e1e2e" alt="Emacs" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://github.com/gamedolphin/system/blob/main/LICENSE">
|
||
#+HTML: <img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=GPL&colorA=1e1e2e&colorB=f38ba8&logo=unlicense&logoColor=f9e2af" alt="License" />
|
||
#+HTML: </a>
|
||
#+HTML: <a href="https://github.com/gamedolphin/system/actions/workflows/tangle.yml">
|
||
#+HTML: <img src="https://img.shields.io/github/actions/workflow/status/gamedolphin/system/tangle.yml?style=for-the-badge&label=Tangle&colorA=1e1e2e&colorB=a6e3a1&logo=github&logoColor=cdd6f4" alt="Tangle workflow" />
|
||
#+HTML: </a>
|
||
#+HTML: </div>
|
||
#+HTML: </div>
|
||
|
||
* Introduction
|
||
#+HTML: <div align="center"><img src="./.github/images/screenshot.png" width="100%" alt="Screenshot" /></div>
|
||
|
||
This literate document describes and generates the configuration for the systems in this repository. It contains source blocks that are exported into individual files using Emacs Org mode’s tangling mechanism. The exported files are then evaluated as a NixOS flake to produce an immutable system configuration.
|
||
|
||
This repository currently includes configuration for:
|
||
|
||
* =traveldroid= — main workstation/laptop
|
||
|
||
To generate the Nix files, open this file in Emacs and run =M-x org-babel-tangle=.
|
||
|
||
Alternatively, run the following from the command line:
|
||
|
||
#+begin_src bash :tangle no
|
||
emacs README.org --batch -f org-babel-tangle
|
||
#+end_src
|
||
|
||
Once the Nix files are generated, deploy using:
|
||
|
||
#+begin_src bash :tangle no
|
||
nixos-rebuild switch --flake .#<machine>
|
||
#+end_src
|
||
|
||
Other files in this repo include:
|
||
|
||
* ~flake.lock~ for pinning input versions.
|
||
* ~assets/*~ for non-Nix-managed artifacts such as images and wallpapers.
|
||
#- ~secrets/secrets.yaml~ for encrypted secrets edited using ~sops~.
|
||
|
||
Generated outputs should not be edited directly. A CI workflow can tangle and commit generated outputs when they differ.
|
||
|
||
** Emacs + Org + Tangle
|
||
|
||
* [[[https://www.gnu.org/software/emacs/][Emacs](https://www.gnu.org/software/emacs/][Emacs)]] is used as the editor and execution environment for this literate configuration.
|
||
* [[[https://orgmode.org/][Org](https://orgmode.org/][Org) mode]] provides the document structure and the source block execution model used here.
|
||
* 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.
|
||
|
||
** Nix & NixOS
|
||
|
||
* [[[https://nix.dev/][Nix](https://nix.dev/][Nix)]] is used to define packages, environments, and configuration as pure expressions.
|
||
* [[[https://nixos.org/][NixOS](https://nixos.org/][NixOS)]] evaluates Nix expressions into a complete system configuration that can be applied by rebuild operations.
|
||
|
||
** Repository layout and folder conventions
|
||
#+HTML: <p>
|
||
#+HTML: This repository contains system modules, user modules, and configuration fragments. The following directories are treated as separate layers:
|
||
#+HTML: <code>./configuration</code> (NixOS modules), <code>./home</code> (Home Manager modules), and <code>./assets/conf</code> (configuration fragments referenced or deployed by the modules).
|
||
#+HTML: </p>
|
||
#+HTML: <p>
|
||
#+HTML: To keep navigation consistent, the same internal substructure is used in all three locations. Each layer keeps its role; only the internal grouping is standardized.
|
||
#+HTML: </p>
|
||
|
||
** Shared domain folders
|
||
#+HTML: <ul>
|
||
#+HTML: <li><code>core/</code> – base settings and common infrastructure</li>
|
||
#+HTML: <li><code>desktop/</code> – graphical session, compositor, UI components, and integration</li>
|
||
#+HTML: <li><code>apps/</code> – application enablement and application-level configuration</li>
|
||
#+HTML: <li><code>services/</code> – background services and daemons</li>
|
||
#+HTML: <li><code>security/</code> – secrets handling and security-related configuration</li>
|
||
#+HTML: <li><code>dev/</code> – developer tooling and editor configuration</li>
|
||
#+HTML: </ul>
|
||
|
||
** Full tree (including unchanged parts)
|
||
#+HTML: <p>
|
||
#+HTML: The tree below shows the full repository layout, with the standardized internal structure applied only inside
|
||
#+HTML: <code>configuration/</code>, <code>home/</code>, and <code>assets/conf/</code>.
|
||
#+HTML: </p>
|
||
|
||
#+HTML: <pre><code>.
|
||
#+HTML: ├── flake.nix
|
||
#+HTML: ├── flake.lock
|
||
#+HTML: ├── README.org
|
||
#+HTML: ├── user.nix
|
||
#+HTML: ├── assets
|
||
#+HTML: │ ├── background.png
|
||
#+HTML: │ ├── conf
|
||
#+HTML: │ │ ├── apps
|
||
#+HTML: │ │ │ ├── flatpak.conf
|
||
#+HTML: │ │ │ └── packages.conf
|
||
#+HTML: │ │ ├── core
|
||
#+HTML: │ │ │ └── xdg
|
||
#+HTML: │ │ │ └── mimeapps.list
|
||
#+HTML: │ │ ├── desktop
|
||
#+HTML: │ │ │ ├── greeter
|
||
#+HTML: │ │ │ │ └── greeter.conf
|
||
#+HTML: │ │ │ ├── hypr
|
||
#+HTML: │ │ │ │ ├── bindings.conf
|
||
#+HTML: │ │ │ │ ├── hyprland.conf
|
||
#+HTML: │ │ │ │ ├── hyprland_no_blur.conf
|
||
#+HTML: │ │ │ │ └── hyprshell.conf
|
||
#+HTML: │ │ │ ├── terminal
|
||
#+HTML: │ │ │ │ (optional: desktop-facing terminal fragments if needed)
|
||
#+HTML: │ │ │ ├── wallpaper
|
||
#+HTML: │ │ │ │ └── wallpaper.conf
|
||
#+HTML: │ │ │ └── waybar
|
||
#+HTML: │ │ │ ├── config.jsonc
|
||
#+HTML: │ │ │ └── style.css
|
||
#+HTML: │ │ ├── dev
|
||
#+HTML: │ │ │ ├── hyprshell
|
||
#+HTML: │ │ │ │ ├── config.ron.bak
|
||
#+HTML: │ │ │ │ └── styles.css.bak
|
||
#+HTML: │ │ │ └── terminal
|
||
#+HTML: │ │ │ ├── aliases.conf
|
||
#+HTML: │ │ │ ├── kitty.conf
|
||
#+HTML: │ │ │ ├── starship.toml
|
||
#+HTML: │ │ │ └── zsh.conf
|
||
#+HTML: │ │ ├── security
|
||
#+HTML: │ │ │ └── ssh
|
||
#+HTML: │ │ │ └── ssh-client.conf
|
||
#+HTML: │ │ └── services
|
||
#+HTML: │ ├── lock.png
|
||
#+HTML: │ ├── scripts
|
||
#+HTML: │ └── wallpaper
|
||
#+HTML: │ ├── gif
|
||
#+HTML: │ ├── picture
|
||
#+HTML: │ │ ├── pexels-kseniachernaya-5691695.jpg
|
||
#+HTML: │ │ ├── pexels-lalesh-147635.jpg
|
||
#+HTML: │ │ ├── pexels-lucaspezeta-2212858.jpg
|
||
#+HTML: │ │ ├── pexels-themob000-28428584.jpg
|
||
#+HTML: │ │ └── pexels-themob000-28428592.jpg
|
||
#+HTML: │ └── videos
|
||
#+HTML: │ ├── dark_water_large.mp4
|
||
#+HTML: │ └── white_blobs_small.mp4
|
||
#+HTML: ├── configuration
|
||
#+HTML: │ ├── default.nix
|
||
#+HTML: │ ├── apps
|
||
#+HTML: │ │ ├── flatpak.nix
|
||
#+HTML: │ │ └── packages.nix
|
||
#+HTML: │ ├── core
|
||
#+HTML: │ │ ├── cli.nix
|
||
#+HTML: │ │ ├── files.nix
|
||
#+HTML: │ │ ├── locale.nix
|
||
#+HTML: │ │ ├── networking.nix
|
||
#+HTML: │ │ └── nix-settings.nix
|
||
#+HTML: │ ├── desktop
|
||
#+HTML: │ │ ├── audio.nix
|
||
#+HTML: │ │ ├── hyprland.nix
|
||
#+HTML: │ │ └── login.nix
|
||
#+HTML: │ ├── dev
|
||
#+HTML: │ │ └── boot.nix
|
||
#+HTML: │ ├── security
|
||
#+HTML: │ │ └── sops.nix
|
||
#+HTML: │ └── services
|
||
#+HTML: │ └── services.nix
|
||
#+HTML: ├── hardware
|
||
#+HTML: │ └── hardware.nix
|
||
#+HTML: ├── home
|
||
#+HTML: │ ├── default.nix
|
||
#+HTML: │ ├── apps
|
||
#+HTML: │ │ └── theme.nix
|
||
#+HTML: │ ├── core
|
||
#+HTML: │ │ └── unity.nix
|
||
#+HTML: │ ├── desktop
|
||
#+HTML: │ │ ├── hyprland.nix
|
||
#+HTML: │ │ ├── lock.nix
|
||
#+HTML: │ │ ├── walker.nix
|
||
#+HTML: │ │ ├── wallpaper.nix
|
||
#+HTML: │ │ └── waybar.nix
|
||
#+HTML: │ ├── dev
|
||
#+HTML: │ │ ├── dev.nix
|
||
#+HTML: │ │ ├── terminal.nix
|
||
#+HTML: │ │ └── emacs
|
||
#+HTML: │ │ ├── default.nix
|
||
#+HTML: │ │ ├── early-init.el
|
||
#+HTML: │ │ └── init.el
|
||
#+HTML: │ ├── security
|
||
#+HTML: │ ├── services
|
||
#+HTML: │ └── theme
|
||
#+HTML: │ └── theme.nix
|
||
#+HTML: ├── LICENSE
|
||
#+HTML: ├── machines
|
||
#+HTML: │ └── traveldroid
|
||
#+HTML: │ ├── configuration.nix
|
||
#+HTML: │ ├── hardware-configuration.nix
|
||
#+HTML: │ └── home.nix
|
||
#+HTML: ├── main
|
||
#+HTML: └── secrets
|
||
#+HTML: └── secrets.yaml
|
||
#+HTML: </code></pre>
|
||
|
||
** Notes
|
||
#+HTML: <ul>
|
||
#+HTML: <li>Only the internal layout of <code>configuration/</code>, <code>home/</code>, and <code>assets/conf/</code> is standardized; all other paths remain as currently organized.</li>
|
||
#+HTML: <li>The <code>services/</code> and <code>security/</code> folders are included for completeness even if initially empty in some layers.</li>
|
||
#+HTML: </ul>
|
||
|
||
~YourNixCode(Input) -> System Configuration~
|
||
|
||
├── flake.lock
|
||
├── flake.nix
|
||
├── README.org
|
||
├── user.nix
|
||
├── assets
|
||
│ ├── background.png
|
||
│ ├── conf
|
||
│ │ ├── apps
|
||
│ │ │ ├── flatpak.conf
|
||
│ │ │ └── packages.conf
|
||
│ │ ├── core
|
||
│ │ │ └── xdg
|
||
│ │ │ └── mimeapps.list
|
||
│ │ ├── desktop
|
||
│ │ │ ├── greeter
|
||
│ │ │ │ └── greeter.conf
|
||
│ │ │ ├── hypr
|
||
│ │ │ │ ├── bindings.conf
|
||
│ │ │ │ ├── hyprland.conf
|
||
│ │ │ │ ├── hyprland_no_blur.conf
|
||
│ │ │ │ └── hyprshell.conf
|
||
│ │ │ ├── terminal
|
||
│ │ │ │ (optional: desktop-facing terminal fragments if needed)
|
||
│ │ │ ├── wallpaper
|
||
│ │ │ │ └── wallpaper.conf
|
||
│ │ │ └── waybar
|
||
│ │ │ ├── config.jsonc
|
||
│ │ │ └── style.css
|
||
│ │ ├── dev
|
||
│ │ │ ├── hyprshell
|
||
│ │ │ │ ├── config.ron.bak
|
||
│ │ │ │ └── styles.css.bak
|
||
│ │ │ └── terminal
|
||
│ │ │ ├── aliases.conf
|
||
│ │ │ ├── kitty.conf
|
||
│ │ │ ├── starship.toml
|
||
│ │ │ └── zsh.conf
|
||
│ │ ├── security
|
||
│ │ │ └── ssh
|
||
│ │ │ └── ssh-client.conf
|
||
│ │ └── services
|
||
│ ├── lock.png
|
||
│ ├── scripts
|
||
│ └── wallpaper
|
||
│ ├── gif
|
||
│ ├── picture
|
||
│ │ ├── pexels-kseniachernaya-5691695.jpg
|
||
│ │ ├── pexels-lalesh-147635.jpg
|
||
│ │ ├── pexels-lucaspezeta-2212858.jpg
|
||
│ │ ├── pexels-themob000-28428584.jpg
|
||
│ │ └── pexels-themob000-28428592.jpg
|
||
│ └── videos
|
||
│ ├── dark_water_large.mp4
|
||
│ └── white_blobs_small.mp4
|
||
├── configuration
|
||
│ ├── default.nix
|
||
│ ├── apps
|
||
│ │ ├── flatpak.nix
|
||
│ │ └── packages.nix
|
||
│ ├── core
|
||
│ │ ├── cli.nix
|
||
│ │ ├── files.nix
|
||
│ │ ├── locale.nix
|
||
│ │ ├── networking.nix
|
||
│ │ └── nix-settings.nix
|
||
│ ├── desktop
|
||
│ │ ├── audio.nix
|
||
│ │ ├── hyprland.nix
|
||
│ │ └── login.nix
|
||
│ ├── dev
|
||
│ │ └── boot.nix
|
||
│ ├── security
|
||
│ │ └── sops.nix
|
||
│ └── services
|
||
│ └── services.nix
|
||
├── hardware
|
||
│ └── hardware.nix
|
||
├── home
|
||
│ ├── default.nix
|
||
│ ├── apps
|
||
│ │ └── theme.nix
|
||
│ ├── core
|
||
│ │ └── unity.nix
|
||
│ ├── desktop
|
||
│ │ ├── hyprland.nix
|
||
│ │ ├── lock.nix
|
||
│ │ ├── walker.nix
|
||
│ │ ├── wallpaper.nix
|
||
│ │ └── waybar.nix
|
||
│ ├── dev
|
||
│ │ ├── dev.nix
|
||
│ │ ├── terminal.nix
|
||
│ │ └── emacs
|
||
│ │ ├── default.nix
|
||
│ │ ├── early-init.el
|
||
│ │ └── init.el
|
||
│ ├── security
|
||
│ ├── services
|
||
│ └── theme
|
||
│ └── theme.nix
|
||
├── LICENSE
|
||
├── machines
|
||
│ └── traveldroid
|
||
│ ├── configuration.nix
|
||
│ ├── hardware-configuration.nix
|
||
│ └── home.nix
|
||
├── main
|
||
├── README.org
|
||
└── secrets
|
||
└── secrets.yaml
|
||
|
||
|
||
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
|
||
}
|
||
#+end_src
|
||
|
||
Nix flakes is still behind an ~experimental~ flag, but it is de facto the standard by most of the community.
|
||
Flakes allow us to pin the input package versions using a ~flake.lock~ file.
|
||
This prevents unwanted and surprise updates when rebuilding without changing the configuration.
|
||
|
||
* TLDR App List
|
||
|
||
| Window Manager | [[https://hyprland.org/][Hyprland]] |
|
||
| Bar | [[https://github.com/Alexays/Waybar][Waybar]] |
|
||
| Application Launcher | [[https://github.com/abenz1267/walker][Walker]] |
|
||
| Notification Daemon | [[https://github.com/dunst-project/dunst][Dunst]] |
|
||
| 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.
|
||
The values are imported at the beginning and are available to almost all the functions being called to configure the system.
|
||
#+begin_src nix :tangle user.nix
|
||
{
|
||
system = "x86_64-linux";
|
||
username = "henrov";
|
||
stateVersion = "25.11";
|
||
locale = "sv_SE.UTF-8";
|
||
}
|
||
#+end_src
|
||
|
||
* 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.
|
||
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://github.com/getsops/sops][sops-nix]] - adds latest sops for secrets management.
|
||
5. [[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";
|
||
};
|
||
|
||
# sops-nix = {
|
||
# url = "github:Mic92/sops-nix";
|
||
# inputs.nixpkgs.follows = "nixpkgs";
|
||
# };
|
||
#
|
||
catppuccin = {
|
||
url = "github:catppuccin/nix";
|
||
inputs.nixpkgs.follows = "nixpkgs";
|
||
};
|
||
};
|
||
|
||
<<flake-outputs>>
|
||
}
|
||
#+end_src
|
||
|
||
* Flake Output
|
||
#+HTML: ├── flake.nix
|
||
#+HTML: ├── user.nix
|
||
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.
|
||
We also add a devshell that makes editing this repository easier in emacs.
|
||
|
||
#+name: flake-outputs
|
||
#+begin_src nix :noweb no-export
|
||
outputs = {
|
||
nixpkgs,
|
||
home-manager,
|
||
emacs-overlay,
|
||
# sops-nix,
|
||
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 = [
|
||
<<flake-emacs-module>>
|
||
<<flake-config-module>>
|
||
<<flake-home-module>>
|
||
#sops-nix.nixosModules.sops # sops
|
||
catppuccin.nixosModules.catppuccin # theme
|
||
];
|
||
specialArgs = {
|
||
hostname = machine;
|
||
inherit user;
|
||
};
|
||
};
|
||
}) machines
|
||
);
|
||
devShells.${user.system}.default = pkgs.mkShell {
|
||
buildInputs = with pkgs; [
|
||
nil # nix lsp server
|
||
nixfmt-rfc-style # nix formatter
|
||
#sops # used to edit secrets
|
||
];
|
||
};
|
||
};
|
||
#+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.
|
||
|
||
#+name: flake-emacs-module
|
||
#+begin_src nix
|
||
({ ... }: {
|
||
nixpkgs.overlays = [ emacs-overlay.overlays.default ];
|
||
})
|
||
#+end_src
|
||
|
||
2. Then the machine specific configuration, in this case, just "traveldroid".
|
||
#+name: flake-config-module
|
||
#+begin_src 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.
|
||
|
||
#+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.extraSpecialArgs = {
|
||
inherit user;
|
||
};
|
||
<<flake-home-backup>>
|
||
<<flake-home-config>>
|
||
}
|
||
#+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
|
||
|
||
** Envrc + Direnv
|
||
Editing this file will be much nicer if we have the dev environment configured.
|
||
That is done in the devshells section. But to auto load this dev shell, we need a .envrc file.
|
||
This tells [[https://direnv.net/][direnv]] to load the devshell in the flake.
|
||
#Finally, we also look for a .envrc-private file and try to load that. That contains devshell specific secrets.
|
||
|
||
#+begin_src nix :tangle .envrc
|
||
use flake
|
||
|
||
watch_file .envrc.private
|
||
if [[ -f .envrc.private ]]; then
|
||
source_env .envrc.private
|
||
fi
|
||
#+end_src
|
||
|
||
#+HTML: ├── machines
|
||
#+HTML: │ └── traveldroid
|
||
#+HTML: │ ├── configuration.nix
|
||
#+HTML: │ ├── hardware-configuration.nix
|
||
#+HTML: │ └── home.nix
|
||
* Machines
|
||
The individual machines subdirectory is configured as follows :-
|
||
#+name: tree
|
||
#+begin_src ditaa
|
||
+--machine
|
||
| +--configuration.nix
|
||
| +--home.nix
|
||
| +--hardware-configuration.nix
|
||
#+end_src
|
||
|
||
- configuration.nix has the system configuration.
|
||
- home.nix has the user level configuration.
|
||
- hardware-configuration.nix has the unique hardware configuration.
|
||
|
||
~nixos-rebuild switch --flake .#traveldroid~ looks for the traveldroid configuration (in ~/machines/traveldroid~) and returns the configuration that is specific to that computer.
|
||
|
||
- Note about imports
|
||
~imports = []~ in a nix file will pull in the function/object from the list of files provided.
|
||
This imported object (or function result) is just trivially merged into a common object.
|
||
|
||
We can take a look at that the common hardware options I have for all my machines.
|
||
*** Other Utils
|
||
**** 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 :-
|
||
#+begin_src bash
|
||
nix flake update
|
||
#+end_src
|
||
|
||
**** Editing secrets
|
||
The age key needs to exist. Then I can edit the secrets using :-
|
||
#+begin_src bash
|
||
#sops edit secrets/secrets.yaml
|
||
#+end_src
|
||
|
||
#+HTML: ├── hardware
|
||
#+HTML: │ └── hardware.nix
|
||
* Hardware
|
||
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
|
||
|
||
# update cpu microcode with firmware that allows redistribution
|
||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||
|
||
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
|
||
];
|
||
};
|
||
};
|
||
|
||
hardware.enableAllFirmware = true; # enable all firmware regardless of license
|
||
}
|
||
#+end_src
|
||
|
||
#+HTML: ├── configuration
|
||
#+HTML: │ ├── default.nix
|
||
#+HTML: │ ├── apps
|
||
#+HTML: │ │ ├── flatpak.nix
|
||
#+HTML: │ │ └── packages.nix
|
||
#+HTML: │ ├── core
|
||
#+HTML: │ │ ├── cli.nix
|
||
#+HTML: │ │ ├── files.nix
|
||
#+HTML: │ │ ├── locale.nix
|
||
#+HTML: │ │ ├── networking.nix
|
||
#+HTML: │ │ └── nix-settings.nix
|
||
#+HTML: │ ├── security
|
||
#+HTML: │ │ └── sops.nix
|
||
* 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 :-
|
||
|
||
#+begin_src nix :tangle configuration/default.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, user, ... } :
|
||
{
|
||
imports = [
|
||
./boot.nix
|
||
./login.nix
|
||
./cli.nix
|
||
./files.nix
|
||
./locale.nix
|
||
./nix-settings.nix
|
||
./networking.nix
|
||
./hyprland.nix
|
||
./services.nix
|
||
./audio.nix
|
||
#./steam.nix
|
||
#./sops.nix
|
||
./packages.nix
|
||
./flatpak.nix
|
||
];
|
||
|
||
<<config-system-packages>>
|
||
|
||
<<config-user>>
|
||
|
||
<<config-programs>>
|
||
|
||
<<config-fonts>>
|
||
|
||
# enable the catppuccin theme for everything with mocha + blue accents
|
||
catppuccin.enable = true;
|
||
catppuccin.flavor = "mocha";
|
||
catppuccin.accent = "blue";
|
||
|
||
system.stateVersion = user.stateVersion;
|
||
}
|
||
#+end_src
|
||
|
||
Whoa. Thats a lot of imports. Lets go through them one by one.
|
||
|
||
#+HTML: │ └── services
|
||
#+HTML: │ └── services.nix
|
||
** Nix Settings
|
||
These are global nix settings that configure the settings for the actual tool.
|
||
|
||
#+begin_src nix :tangle configuration/nix-settings.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, user, ... } :
|
||
{
|
||
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="
|
||
];
|
||
};
|
||
|
||
# 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";
|
||
};
|
||
|
||
programs = {
|
||
# command line utility that makes applying changes easy and pretty
|
||
nh = {
|
||
enable = true;
|
||
flake = "/home/${user.username}/system";
|
||
};
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
#+HTML: │ ├── dev
|
||
#+HTML: │ │ └── boot.nix
|
||
** Boot
|
||
This file has most of the settings the control how the computer boots up.
|
||
|
||
#+begin_src nix :tangle configuration/boot.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... } :
|
||
{
|
||
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
|
||
|
||
consoleLogLevel = 0; # quiten more logs
|
||
plymouth.enable = true; # graphical boot animation instead
|
||
|
||
supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows)
|
||
|
||
loader = {
|
||
systemd-boot.enable = true; # systemd-boot
|
||
systemd-boot.configurationLimit = 2;
|
||
efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader
|
||
|
||
|
||
timeout = 5; # grub timeout to make a selection
|
||
};
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Login
|
||
Here we control what the login screen would look like. I'm using greetd's [[https://github.com/apognu/tuigreet][tuigreet]] for the ui.
|
||
Doesn't match the rest of the aesthetic of the system (with hyprland), but I like its simplicity.
|
||
|
||
#+begin_src nix :tangle configuration/login.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'";
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
#+end_src
|
||
|
||
** CLI
|
||
This is the initial system level configuration for the terminal that I use on this machine. Its just [[https://ohmyz.sh/][zsh]].
|
||
|
||
#+begin_src nix :tangle configuration/cli.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, user, ... }:
|
||
{
|
||
console.useXkbConfig = true;
|
||
users.users.${user.username}.shell = pkgs.zsh;
|
||
|
||
environment.shells = with pkgs; [ zsh ];
|
||
programs.zsh.enable = true;
|
||
environment.pathsToLink = [ "/share/zsh" ];
|
||
}
|
||
#+end_src
|
||
|
||
** Files
|
||
I use Thunar as the file explorer. Also setup a few plugins for [[https://docs.xfce.org/xfce/thunar/start][Thunar]] in this config.
|
||
Along with that, a few other utilities like zip and enabling services to automount usb drives.
|
||
|
||
#+begin_src nix :tangle configuration/files.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, user, config, ... } :
|
||
{
|
||
environment.systemPackages = with pkgs; [
|
||
zip
|
||
unzip
|
||
p7zip
|
||
usbutils
|
||
udiskie
|
||
];
|
||
|
||
programs.thunar = {
|
||
enable = true;
|
||
plugins = with pkgs.xfce; [
|
||
thunar-archive-plugin
|
||
thunar-media-tags-plugin
|
||
thunar-volman
|
||
];
|
||
};
|
||
|
||
programs.file-roller.enable = true; # thunar zip support
|
||
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
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Locale
|
||
I live in Netherlands and would like all my locale and timezone settings to match. Except my default locale.
|
||
#+begin_src nix :tangle configuration/locale.nix :noweb tangle :mkdirp yes
|
||
{ user, ... } :
|
||
let
|
||
locale = user.locale;
|
||
defaultLocale = "nl_NL.UTF-8";
|
||
in
|
||
{
|
||
# Set your time zone.
|
||
time.timeZone = "Europe/Amsterdam";
|
||
|
||
# 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;
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Networking
|
||
Not much to see here. I want networking to be enabled. I want firewall as well.
|
||
#+begin_src nix :tangle configuration/networking.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... } : {
|
||
networking = {
|
||
# allow automatic ip assignment when connecting to a network
|
||
useDHCP = pkgs.lib.mkDefault true;
|
||
networkmanager.enable = true;
|
||
firewall.enable = true;
|
||
|
||
# let wifi info be NOT declarative, allowing user to configure wifi.
|
||
wireless.userControlled.enable = true;
|
||
wireless.iwd.enable = true;
|
||
networkmanager.wifi.backend = "wpa_supplicant";
|
||
};
|
||
|
||
# tui to manage wifi networks
|
||
environment.systemPackages = with pkgs; [ impala ];
|
||
}
|
||
#+end_src
|
||
|
||
** Hyprland
|
||
This is a big one because the DE needs so much configuration. This section mostly installs [[https://hyprland.org/][Hyprland]].
|
||
The configuration is done in the home manager section.
|
||
#+begin_src nix :tangle configuration/test/hyprland.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... }:
|
||
{
|
||
nix.settings = {
|
||
# add the hyprland cache so that we dont build hyprland from source
|
||
substituters = [ "https://hyprland.cachix.org" ];
|
||
trusted-public-keys = [
|
||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||
];
|
||
};
|
||
|
||
# these extra portals allow for things like screen sharing
|
||
xdg = {
|
||
portal = {
|
||
enable = true;
|
||
extraPortals = [
|
||
pkgs.xdg-desktop-portal-wlr
|
||
pkgs.xdg-desktop-portal-gtk
|
||
];
|
||
};
|
||
};
|
||
|
||
environment.systemPackages = with pkgs; [
|
||
hyprland # the actual package
|
||
walker # launcher
|
||
uwsm # wayland session manager
|
||
hyprland-qtutils # needed by hyprland
|
||
hyprpolkitagent # polkit agent
|
||
grimblast # screenshot
|
||
];
|
||
|
||
# we use uwsm to manage launching hyprland
|
||
# uswm will add hyprland to the login sessions with tuigreet.
|
||
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;
|
||
};
|
||
};
|
||
|
||
# this is mainly for the lock screen
|
||
# lock.png is provided elsewhere
|
||
services.xserver = {
|
||
enable = true;
|
||
|
||
desktopManager = {
|
||
xterm.enable = false;
|
||
};
|
||
|
||
|
||
displayManager = {
|
||
lightdm.background = ./lock.png;
|
||
};
|
||
};
|
||
|
||
# this is a lot of env vars.
|
||
# and this requires some cleanup
|
||
# but hyprland moves fast and some of these are probably outdated already
|
||
environment.sessionVariables = {
|
||
XDG_SESSION_TYPE="wayland";
|
||
XDG_CURRENT_DESKTOP="Hyprland";
|
||
XDG_SESSION_DESKTOP="Hyprland";
|
||
NIXOS_OZONE_WL="1";
|
||
XCURSOR_SIZE="24";
|
||
};
|
||
|
||
# allow hyprlock (lockscreen) to lock user session
|
||
security.pam.services.hyprlock = { };
|
||
security.polkit.enable = true;
|
||
security.pam.services.gdm.enableGnomeKeyring = true;
|
||
}
|
||
|
||
#+end_src
|
||
|
||
** Services
|
||
These are some of the services that I enable at the system level. Explanation in the comments.
|
||
#+begin_src nix :tangle configuration/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
|
||
|
||
# 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
|
||
}
|
||
#+end_src
|
||
|
||
** Audio
|
||
This is still a work in progress, but it almost works. I enable all the audio related services, hoping everything is going to be okay.
|
||
#+begin_src nix :tangle configuration/audio.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ...}:
|
||
{
|
||
environment.systemPackages = with pkgs; [ pamixer ];
|
||
services.pipewire = {
|
||
enable = true;
|
||
alsa.enable = true;
|
||
alsa.support32Bit = true;
|
||
pulse.enable = true;
|
||
jack.enable = true;
|
||
};
|
||
|
||
# pipewire needs realtime scheduling access
|
||
security.rtkit.enable = true;
|
||
}
|
||
#+end_src
|
||
|
||
** Sops
|
||
#We use [[https://github.com/Mic92/sops-nix][sops]] to manage secrets on this machine.
|
||
#+begin_src nix :tangle configuration/sops.nix :noweb tangle :mkdirp yes
|
||
# { user, ...} :
|
||
# {
|
||
# sops.defaultSopsFile = ../secrets/secrets.yaml;
|
||
# sops.defaultSopsFormat = "yaml";
|
||
# sops.age.keyFile = "/home/${user.username}/.config/sops/age/keys.txt";
|
||
#
|
||
# sops.secrets.claude_key = { # anthropic claude api key, used in emacs
|
||
# owner = "${user.username}";
|
||
# };
|
||
# }
|
||
#+end_src
|
||
|
||
#Sops requires a public ~.sops.yaml~ that dictates how the secrets are encrypted.
|
||
#This contains the public key and path to the secrets file.
|
||
|
||
#+begin_src yaml :tangle .sops.yaml :mkdirp yes
|
||
#keys:
|
||
# - &primary age1yq35g6mmlem0rhr47u6ewh8dctlwp9hj0s0ac60e4hrw9hjzlqms6crf7n
|
||
#creation_rules:
|
||
# - path_regex: secrets/secrets.yaml$
|
||
# key_groups:
|
||
# - age:
|
||
# - *primary
|
||
#+end_src
|
||
|
||
** Miscellaneous Packages and Programs
|
||
#+name: config-system-packages
|
||
#+begin_src nix
|
||
environment.systemPackages = with pkgs; [
|
||
wget # fetch utility
|
||
curl # more fetch utility
|
||
binutils # executable utilities, like ld
|
||
dmidecode # tool for dumping system info
|
||
libnotify # notification daemon
|
||
python3 # nice to have this ready for quick things
|
||
cacert # certificate authority
|
||
remmina # remote desktop app
|
||
#rg # ripgrep
|
||
wev # for finding keypresses
|
||
tree # list foldetrtree's
|
||
file # filinfo
|
||
htop # sysmonitor
|
||
solaar # logitech controller
|
||
git # source control
|
||
# jetbrains.pycharm # Dev and course environment
|
||
|
||
|
||
];
|
||
|
||
# to enable icons with wlogout
|
||
# https://github.com/catppuccin/nix/issues/584
|
||
programs.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
|
||
#+end_src
|
||
|
||
#+name: config-programs
|
||
#+begin_src nix
|
||
programs = {
|
||
nix-ld.enable = true; # helps with linking troubles with dynamic libraries
|
||
appimage.enable = true; # allow appimage installations
|
||
dconf.enable = true; # to save user settings
|
||
gnupg.agent = {
|
||
# pgp client
|
||
enable = true;
|
||
enableSSHSupport = true;
|
||
};
|
||
firefox.enable = true; # browser
|
||
wireshark.enable = true; # vpn
|
||
};
|
||
#+end_src
|
||
|
||
** Fonts
|
||
Nothing much to see here. I love [[https://protesilaos.com/codelog/2025-02-12-aporetic-fonts-version-1-1-0/][Aporetic]], and I use it everywhere.
|
||
#+name: config-fonts
|
||
#+begin_src nix
|
||
fonts.packages = with pkgs; [
|
||
aporetic
|
||
nerd-fonts.iosevka
|
||
];
|
||
#+end_src
|
||
|
||
** User Config
|
||
This creates the user profile that I login with. Initially created during install.
|
||
#+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
|
||
];
|
||
};
|
||
#+end_src
|
||
|
||
* Home
|
||
I use home-manager to manage my user level dotfiles and configurations.
|
||
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.
|
||
|
||
#+begin_src nix :tangle home/default.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, user, ... } :
|
||
{
|
||
imports = [
|
||
./waybar.nix
|
||
./wallpaper.nix
|
||
./lock.nix
|
||
./unity.nix
|
||
./hyprland.nix
|
||
./walker.nix
|
||
./theme.nix
|
||
./terminal.nix
|
||
./dev.nix
|
||
./emacs
|
||
];
|
||
|
||
<<home-user>>
|
||
|
||
<<home-packages>>
|
||
|
||
programs.home-manager.enable = true;
|
||
}
|
||
#+end_src
|
||
Oof! Again with all the imports! We can go through them one at a time!
|
||
|
||
** Waybar
|
||
[[./.github/images/waybar.png]]
|
||
|
||
Mostly styling and enabling modules in the [[https://github.com/Alexays/Waybar][top bar]].
|
||
#+begin_src nix :tangle home/waybar.nix :noweb tangle :mkdirp yes
|
||
{
|
||
programs.waybar = {
|
||
enable = true;
|
||
settings = {
|
||
mainBar = {
|
||
layer = "top";
|
||
height = 34;
|
||
modules-left = [ "hyprland/workspaces" "hyprland/window" ];
|
||
modules-right = [
|
||
"idle_inhibitor"
|
||
"pulseaudio"
|
||
"network"
|
||
"cpu"
|
||
"memory"
|
||
"temperature"
|
||
"battery"
|
||
"tray"
|
||
"clock"
|
||
];
|
||
"idle_inhibitor" = {
|
||
format = "{icon}";
|
||
format-icons = {
|
||
activated = " ";
|
||
deactivated = " ";
|
||
};
|
||
};
|
||
"pulseaudio" = {
|
||
"format" = "{volume}% {icon}";
|
||
"format-bluetooth" = "{volume}% {icon}";
|
||
"format-muted" = "";
|
||
"format-icons"= {
|
||
"headphones"= "";
|
||
"headset"= "";
|
||
"phone"= "";
|
||
"portab le"= "";
|
||
"default"= ["" ""];
|
||
};
|
||
"on-click"= "pavucontrol";
|
||
};
|
||
"network" = {
|
||
"format-wifi" = " ({bandwidthDownBits})";
|
||
"format-ethernet" = " ({bandwidthDownBits})";
|
||
"format-disconnected" = "Disconnected ⚠";
|
||
"tooltip-format-wifi" = "{essid} ({signalStrength}%)";
|
||
"tooltip-format-ethernet" = "{ifname}: {ipaddr}/{cidr}";
|
||
"on-click" = "impala";
|
||
};
|
||
"cpu".format = "{usage}% ";
|
||
"cpu".tooltip = false;
|
||
"temperature" = {
|
||
"format" = "{temperatureC}°C ";
|
||
};
|
||
"temperature".tooltip = false;
|
||
"tray".spacing = 10;
|
||
"tray".icon-size = 14;
|
||
"clock".format = "{:%a, %d %b %Y - %H:%M}";
|
||
"clock".tooltip = false;
|
||
"battery" = {
|
||
"bat" = "BAT0";
|
||
"states" = {
|
||
"good" = 95;
|
||
"warning" = 30;
|
||
"critical" = 15;
|
||
};
|
||
"format" = "{capacity}% {icon}";
|
||
"format-charging" = "{capacity}% ";
|
||
"format-plugged" = "{capacity}% ";
|
||
"format-icons" = ["" "" "" "" " "];
|
||
};
|
||
"memory".format = "{percentage}% ";
|
||
};
|
||
};
|
||
style = ''
|
||
,* {
|
||
font-family: Aporetic Sans Mono, Iosevka Nerd Font, Roboto, Helvetica, Arial, sans-serif;
|
||
font-size: 13px;
|
||
}
|
||
|
||
window#waybar {
|
||
background-color: @base;
|
||
color: @text;
|
||
transition-property: background-color;
|
||
border-bottom: 0px solid rgba(0, 0, 0, 0);
|
||
transition-duration: .5s;
|
||
}
|
||
|
||
#workspaces button {
|
||
padding: 0 5px;
|
||
background-color: transparent;
|
||
border: none;
|
||
border-radius: 0;
|
||
color: @text;
|
||
}
|
||
|
||
#workspaces button:hover {
|
||
background: @surface1;
|
||
color: @text;
|
||
}
|
||
|
||
#workspaces button.active {
|
||
background-color: @green;
|
||
color: @base;
|
||
box-shadow: inset 0 -3px @subtext1;
|
||
}
|
||
|
||
#clock,
|
||
#idle_inhibitor
|
||
#battery,
|
||
#cpu,
|
||
#memory,
|
||
#temperature,
|
||
#network,
|
||
#pulseaudio,
|
||
#tray {
|
||
margin: 0 5px;
|
||
padding: 0 2px;
|
||
}
|
||
|
||
#idle_inhibitor.activated {
|
||
background-color: @green;
|
||
}
|
||
|
||
#battery.charging {
|
||
color: @green;
|
||
}
|
||
|
||
@keyframes blink {
|
||
to {
|
||
background-color: #ffffff;
|
||
color: black;
|
||
}
|
||
}
|
||
|
||
#battery.warning:not(.charging) {
|
||
color: white;
|
||
animation-name: blink;
|
||
animation-duration: 0.5s;
|
||
animation-timing-function: linear;
|
||
animation-iteration-count: infinite;
|
||
animation-direction: alternate;
|
||
}
|
||
|
||
#window,
|
||
#workspaces {
|
||
margin: 0 4px;
|
||
}
|
||
|
||
.modules-left > widget:first-child > #workspaces {
|
||
margin-left: 0;
|
||
}
|
||
|
||
.modules-right > widget:last-child > #workspaces {
|
||
margin-right: 0;
|
||
}
|
||
|
||
#network.disconnected {
|
||
background-color: @red;
|
||
}
|
||
|
||
#temperature.critical {
|
||
background-color: @red;
|
||
}
|
||
'';
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Wallpaper
|
||
|
||
[[./assets/background.png]]
|
||
I use [[https://wiki.hyprland.org/Hypr-Ecosystem/hyprpaper/][hyprpaper]] for setting the wallpaper. The image is copied into the home folder when applying this configuration and the tool picks it from there.
|
||
#+begin_src nix :tangle home/wallpaper.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... }:
|
||
{
|
||
home.packages = with pkgs; [
|
||
hyprpaper
|
||
];
|
||
|
||
services.hyprpaper.enable = true;
|
||
services.hyprpaper.settings = {
|
||
ipc = "on";
|
||
splash = false;
|
||
splash_offset = 2.0;
|
||
|
||
preload = [ "~/.background-image.png" ];
|
||
wallpaper = [ ",~/.background-image.png" ];
|
||
};
|
||
|
||
home.file = {
|
||
background = {
|
||
source = ../assets/background.png;
|
||
target = ".background-image.png";
|
||
};
|
||
};
|
||
}
|
||
|
||
#+end_src
|
||
** Lock Screen
|
||
The lock screen configured using [[https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/][hyprlock]].
|
||
I use [[https://wiki.hyprland.org/Hypr-Ecosystem/hypridle/][hypridle]] to detect idle time and use wlogout to show a logout menu.
|
||
They are configured below.
|
||
#+begin_src nix :tangle home/lock.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... } :
|
||
{
|
||
home.packages = with pkgs; [
|
||
hyprlock
|
||
hypridle
|
||
wlogout
|
||
];
|
||
|
||
|
||
home.file = {
|
||
lock = {
|
||
source = ../assets/lock.png;
|
||
target = ".lock.png";
|
||
};
|
||
};
|
||
|
||
services = {
|
||
# hypridle to
|
||
# 150 seconds - turn of monitor
|
||
# 300 seconds - lock screen
|
||
# 330 seconds - turn of monitor
|
||
# 30 minutes - put to sleep
|
||
hypridle = {
|
||
enable = true;
|
||
settings = {
|
||
general = {
|
||
lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
|
||
before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
|
||
after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
|
||
};
|
||
|
||
listener = [
|
||
{
|
||
timeout = 150; # 2.5min.
|
||
on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
|
||
on-resume = "brightnessctl -r"; # monitor backlight restore.
|
||
}
|
||
{
|
||
timeout = 300; # 5min
|
||
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
||
}
|
||
{
|
||
timeout = 330; # 5.5min
|
||
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
||
on-resume = "hyprctl dispatch dpms on && brightnessctl -r"; # screen on when activity is detected after timeout has fired.
|
||
}
|
||
{
|
||
timeout = 1800; # 30min
|
||
on-timeout = "systemctl suspend"; # suspend pc
|
||
}
|
||
];
|
||
|
||
};
|
||
};
|
||
};
|
||
|
||
|
||
|
||
programs.wlogout = {
|
||
enable = true;
|
||
layout = [
|
||
{
|
||
"label" = "lock";
|
||
"action" = "hyprlock";
|
||
"text" = "Lock";
|
||
"keybind" = "l";
|
||
}
|
||
{
|
||
"label" = "shutdown";
|
||
"action" = "systemctl poweroff";
|
||
"text" = "Shutdown";
|
||
"keybind" = "s";
|
||
}
|
||
{
|
||
"label" = "suspend";
|
||
"action" = "systemctl suspend";
|
||
"text" = "Suspend";
|
||
"keybind" = "u";
|
||
}
|
||
{
|
||
"label" = "reboot";
|
||
"action" = "systemctl reboot";
|
||
"text" = "Reboot";
|
||
"keybind" = "r";
|
||
}
|
||
{
|
||
"label" = "hibernate";
|
||
"action" = "systemctl hibernate";
|
||
"text" = "Hibernate";
|
||
"keybind" = "h";
|
||
}
|
||
{
|
||
"label" = "reboot";
|
||
"action" = "systemctl reboot";
|
||
"text" = "Reboot";
|
||
"keybind" = "r";
|
||
}
|
||
];
|
||
};
|
||
|
||
catppuccin.wlogout.iconStyle = "wleave";
|
||
|
||
programs.hyprlock = {
|
||
enable = true;
|
||
settings = {
|
||
auth = {
|
||
fingerprint = {
|
||
enabled = true;
|
||
};
|
||
};
|
||
|
||
background = {
|
||
path = "~/.lock.png";
|
||
color = "$base";
|
||
};
|
||
|
||
label = {
|
||
monitor = "";
|
||
text = "$TIME";
|
||
color = "$text";
|
||
font_size = 90;
|
||
position = "0, 0";
|
||
halign = "center";
|
||
valign = "top";
|
||
};
|
||
|
||
input-field = {
|
||
monitor = "";
|
||
size = "300, 60";
|
||
outline_thickness = 4;
|
||
dots_size = 0.2;
|
||
dots_spacing = 0.2;
|
||
dots_center = true;
|
||
outer_color = "$accent";
|
||
inner_color = "$surface0";
|
||
font_color = "$text";
|
||
fade_on_empty = true;
|
||
placeholder_text = ''<span foreground="##$textAlpha"><i> Logged in as </i><span foreground="##$accentAlpha">$USER</span></span>'';
|
||
hide_input = false;
|
||
check_color = "$accent";
|
||
fail_color = "$red";
|
||
fail_text = ''<i>$FAIL <b>($ATTEMPTS)</b></i>'';
|
||
capslock_color = "$yellow";
|
||
position = "0, -47";
|
||
halign = "center";
|
||
valign = "center";
|
||
};
|
||
};
|
||
};
|
||
|
||
catppuccin.hyprlock.enable = true;
|
||
catppuccin.hyprlock.flavor = "mocha";
|
||
catppuccin.hyprlock.accent = "blue";
|
||
catppuccin.hyprlock.useDefaultConfig = false; # we use our own
|
||
}
|
||
|
||
#+end_src
|
||
** Unity
|
||
I work with the [[https://unity.com/][Unity Game Engine]] and I have the unity hub installed globally, instead of in a project flake.
|
||
Often I work with dotnet directly inside of unity and so we set that up too.
|
||
#+begin_src nix :tangle home/unity.nix :noweb tangle :mkdirp yes.
|
||
{ pkgs, ... }:
|
||
{
|
||
home.packages = with pkgs; [
|
||
(pkgs.unityhub.override {
|
||
extraPkgs = pkgs: with pkgs; [
|
||
dotnet-sdk
|
||
];
|
||
})
|
||
];
|
||
|
||
}
|
||
#+end_src
|
||
|
||
** Hyprland
|
||
This configures the desktop environment along with the peripherals. The comments should explain whats happening.
|
||
#+begin_src nix :tangle home/hyprland.nix :noweb tangle :mkdirp yes.
|
||
{
|
||
# required for the default Hyprland config
|
||
programs.kitty.enable = true;
|
||
|
||
services.hyprpolkitagent.enable = true;
|
||
|
||
# enable Hyprland
|
||
wayland.windowManager.hyprland.enable = true;
|
||
|
||
# we start hyprland using uwsm
|
||
wayland.windowManager.hyprland.systemd.enable = false;
|
||
|
||
# hyprland.conf
|
||
wayland.windowManager.hyprland.settings = {
|
||
exec-once = [
|
||
# read in env vars
|
||
"dbus-update-activation-environment --systemd --all"
|
||
# start waybar
|
||
"uwsm app -- waybar"
|
||
];
|
||
|
||
input = {
|
||
follow_mouse = "1";
|
||
|
||
touchpad = {
|
||
natural_scroll = "no";
|
||
scroll_factor = 0.5;
|
||
};
|
||
|
||
scroll_factor = 0.5;
|
||
|
||
accel_profile = "adaptive";
|
||
sensitivity = -0.5; # -1.0 - 1.0, 0 means no modification.
|
||
|
||
kb_layout = "us";
|
||
|
||
# very emacs specific, i use caps as an extra ctrl key
|
||
kb_options = "ctrl:nocaps";
|
||
};
|
||
|
||
cursor = {
|
||
no_hardware_cursors = "true";
|
||
};
|
||
|
||
general = {
|
||
gaps_in = 2;
|
||
gaps_out = 4;
|
||
border_size = 2;
|
||
"col.active_border" = "$blue $green 45deg";
|
||
"col.inactive_border" = "$base";
|
||
|
||
layout = "dwindle";
|
||
};
|
||
|
||
decoration = {
|
||
rounding = 5;
|
||
};
|
||
|
||
animations = {
|
||
enabled = "yes";
|
||
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
|
||
|
||
animation = [
|
||
"windows, 1, 7, myBezier"
|
||
"windowsOut, 1, 7, default, popin 80%"
|
||
"border, 1, 10, default"
|
||
"borderangle, 1, 8, default"
|
||
"fade, 1, 7, default"
|
||
"workspaces, 1, 6, default"
|
||
];
|
||
};
|
||
|
||
dwindle = {
|
||
pseudotile = "yes";
|
||
preserve_split = "yes";
|
||
};
|
||
|
||
misc = {
|
||
disable_hyprland_logo = true;
|
||
focus_on_activate = true;
|
||
};
|
||
|
||
"$mainMod" = "SUPER";
|
||
|
||
bind = [
|
||
"$mainMod, Return, exec, uwsm app -- kitty"
|
||
# use walker to show exec menu
|
||
"$mainMod, Space, exec, walker"
|
||
"$mainMod, P, pseudo"
|
||
"$mainMod, J, togglesplit"
|
||
|
||
# grimblast
|
||
"$mainMod_SHIFT, p, exec, grimblast -n -f copysave active"
|
||
"$mainMod_SHIFT, a, exec, grimblast -n -f copysave area"
|
||
"$mainMod_ALT, p, exec, grimblast -n -f copysave output"
|
||
"$mainMod_CTRL, p, exec, grimblast -n -f copysave screen"
|
||
|
||
# Terminal / launcher / kill / reload
|
||
"$mainMod, RETURN, exec, kitty"
|
||
"$mainMod, D, exec, wofi --show drun"
|
||
"$mainMod, Q, killactive"
|
||
"$mainMod_SHIFT, Q, exit"
|
||
"$mainMod_SHIFT, R, exec, hyprctl reload"
|
||
"$mainMod_SHIFT, S, exec, wlogout"
|
||
|
||
# Default browser
|
||
"$mainMod, W, exec, xdg-open https://about:blank"
|
||
|
||
# Focus movement
|
||
"$mainMod, H, movefocus, l"
|
||
"$mainMod, L, movefocus, r"
|
||
"$mainMod, K, movefocus, u"
|
||
"$mainMod, J, movefocus, d"
|
||
"$mainMod, left, movefocus, l"
|
||
"$mainMod, right, movefocus, r"
|
||
"$mainMod, up, movefocus, u"
|
||
"$mainMod, down, movefocus, d"
|
||
# Keybindings #
|
||
|
||
# Move windows
|
||
"$mainMod_SHIFT, H, movewindow, l"
|
||
"$mainMod_SHIFT, L, movewindow, r"
|
||
"$mainMod_SHIFT, K, movewindow, u"
|
||
"$mainMod_SHIFT, J, movewindow, d"
|
||
"$mainMod_SHIFT, left, movewindow, l"
|
||
"$mainMod_SHIFT, right, movewindow, r"
|
||
"$mainMod_SHIFT, up, movewindow, u"
|
||
"$mainMod_SHIFT, down, movewindow, d"
|
||
|
||
# Resize windows
|
||
"$mainMod CTRL, H, resizeactive, -30 0"
|
||
"$mainMod CTRL, L, resizeactive, 30 0"
|
||
"$mainMod CTRL, K, resizeactive, 0 -30"
|
||
"$mainMod CTRL, J, resizeactive, 0 30"
|
||
|
||
# Floating / fullscreen
|
||
"$mainMod, V, togglefloating"
|
||
"$mainMod, F, fullscreen, 0"
|
||
"$mainMod_SHIFT, F, fullscreen, 1"
|
||
|
||
# Workspaces
|
||
"$mainMod, 1, workspace, 1"
|
||
"$mainMod, 2, workspace, 2"
|
||
"$mainMod, 3, workspace, 3"
|
||
"$mainMod, 4, workspace, 4"
|
||
"$mainMod, 5, workspace, 5"
|
||
"$mainMod, 6, workspace, 6"
|
||
"$mainMod, 7, workspace, 7"
|
||
"$mainMod, 8, workspace, 8"
|
||
"$mainMod, 9, workspace, 9"
|
||
"$mainMod, 0, workspace, 10"
|
||
|
||
"$mainMod_SHIFT, 1, movetoworkspace, 1"
|
||
"$mainMod_SHIFT, 2, movetoworkspace, 2"
|
||
"$mainMod_SHIFT, 3, movetoworkspace, 3"
|
||
"$mainMod_SHIFT, 4, movetoworkspace, 4"
|
||
"$mainMod_SHIFT, 5, movetoworkspace, 5"
|
||
"$mainMod_SHIFT, 6, movetoworkspace, 6"
|
||
"$mainMod_SHIFT, 7, movetoworkspace, 7"
|
||
"$mainMod_SHIFT, 8, movetoworkspace, 8"
|
||
"$mainMod_SHIFT, 9, movetoworkspace, 9"
|
||
"$mainMod_SHIFT, 0, movetoworkspace, 10"
|
||
|
||
# Cycle workspaces
|
||
"$mainMod, mouse_down, workspace, e+1"
|
||
"$mainMod, mouse_up, workspace, e-1"
|
||
|
||
# Mouse drag
|
||
"$mainMod, mouse:272, movewindow"
|
||
"$mainMod, mouse:273, resizewindow"
|
||
|
||
#########################
|
||
# Audio (pamixer)
|
||
#########################
|
||
"XF86AudioRaiseVolume, exec, pamixer -i 5"
|
||
"XF86AudioLowerVolume, exec, pamixer -d 5"
|
||
"XF86AudioMute, exec, pamixer -t"
|
||
"XF86AudioMicMute, exec, pamixer --default-source -t"
|
||
|
||
#########################
|
||
# Media (playerctl)
|
||
#########################
|
||
"XF86AudioPlay, exec, playerctl play-pause"
|
||
"XF86AudioPause, exec, playerctl pause"
|
||
"XF86AudioNext, exec, playerctl next"
|
||
"XF86AudioPrev, exec, playerctl previous"
|
||
"XF86AudioStop, exec, playerctl stop"
|
||
|
||
#########################
|
||
# Brightness (brightnessctl)
|
||
#########################
|
||
"XF86MonBrightnessUp, exec, brightnessctl set +10%"
|
||
"XF86MonBrightnessDown, exec, brightnessctl set 10%-"
|
||
"XF86KbdBrightnessUp, exec, brightnessctl -d '*kbd_backlight*' set +10%"
|
||
"XF86KbdBrightnessDown, exec, brightnessctl -d '*kbd_backlight*' set 10%-"
|
||
|
||
#########################
|
||
# Power / session
|
||
#########################
|
||
"XF86Sleep, exec, systemctl suspend"
|
||
"XF86PowerOff, exec, systemctl poweroff"
|
||
"XF86WakeUp, exec, systemctl suspend"
|
||
|
||
|
||
#########################
|
||
# Start apps
|
||
#########################
|
||
"CTRLALT, B, exec, flatpak run eu.betterbird.Betterbird"
|
||
"CTRLALT, S, exec, spotify"
|
||
"CTRLALT, z, exec, flatpak run app.zen_browser.zen"
|
||
|
||
"$mainMod_SHIFT, S, exec, wlogout"
|
||
];
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Walker
|
||
[[https://github.com/abenz1267/walker][This]] is how I launch applications. It is bound to Win+Space in the hyprland config above.
|
||
#+begin_src nix :tangle home/walker.nix :noweb tangle :mkdirp yes.
|
||
{
|
||
services.walker.enable = true;
|
||
services.walker.settings = {
|
||
close = "ctrl g";
|
||
next = "ctrl n";
|
||
previous = "ctrl p";
|
||
quick_activate = ["1" "2" "3" "4"];
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Theme
|
||
I use the [[https://catppuccin.com/][Catppuccin]] almost everywhere. The nix module integrates almost automatically everywhere (except gtk).
|
||
You'll notice the color values in multiple places outside this as well.
|
||
#+begin_src nix :tangle home/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;
|
||
}
|
||
#+end_src
|
||
|
||
** Terminal
|
||
[[https://alacritty.org/][Alacritty]] is my terminal program. The snippet below configures how it looks.
|
||
#+begin_src nix :tangle home/terminal.nix :noweb tangle :mkdirp yes
|
||
{
|
||
programs = {
|
||
# <henrov: I need to setup kitty here>
|
||
alacritty = {
|
||
enable = true;
|
||
settings = {
|
||
font.normal.family = "Aporetic Sans Mono";
|
||
font.size = 12;
|
||
terminal.shell.program = "zsh";
|
||
|
||
window = {
|
||
padding.x = 4;
|
||
padding.y = 4;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
|
||
catppuccin.alacritty.enable = true;
|
||
catppuccin.alacritty.flavor = "mocha";
|
||
}
|
||
|
||
#+end_src
|
||
|
||
** Dev Tools
|
||
All the miscellaneous dev tools on this computer.
|
||
#+begin_src nix :tangle home/dev.nix :noweb tangle :mkdirp yes
|
||
{ user, pkgs, ... }:
|
||
{
|
||
programs = {
|
||
vscode.enable = true; # yes, sometimes i like to dabble
|
||
vim.enable = true; # and this one too
|
||
ripgrep.enable = true; # fast text search across projects
|
||
btop.enable = true; # even better task manager
|
||
|
||
# nicer terminal info
|
||
starship = {
|
||
enable = true;
|
||
enableZshIntegration = true;
|
||
enableBashIntegration = true;
|
||
};
|
||
|
||
# fuzzy finder
|
||
fzf = {
|
||
enable = true;
|
||
enableZshIntegration = true;
|
||
enableBashIntegration = true;
|
||
};
|
||
|
||
# better cd
|
||
zoxide = {
|
||
enable = true;
|
||
enableZshIntegration = true;
|
||
enableBashIntegration = true;
|
||
};
|
||
|
||
# better ls
|
||
eza = {
|
||
enable = true;
|
||
enableZshIntegration = true;
|
||
enableBashIntegration = true;
|
||
};
|
||
|
||
# this is mainly for integration with nix flakes in individual projects
|
||
direnv = {
|
||
enable = true;
|
||
enableZshIntegration = true;
|
||
enableBashIntegration = true;
|
||
nix-direnv.enable = true;
|
||
};
|
||
|
||
# zsh everywhere with oh-my-zsh
|
||
zsh = {
|
||
enable = true;
|
||
oh-my-zsh = {
|
||
enable = true;
|
||
plugins = [ "git" ];
|
||
theme = "robbyrussell";
|
||
};
|
||
|
||
shellAliases = {
|
||
cd = "z"; # zoxide
|
||
};
|
||
|
||
# for emacs-eat package
|
||
initContent = pkgs.lib.mkOrder 1200 ''
|
||
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \
|
||
source "$EAT_SHELL_INTEGRATION_DIR/zsh"
|
||
'';
|
||
};
|
||
|
||
# git with lfs
|
||
git = {
|
||
lfs.enable = true;
|
||
enable = true;
|
||
};
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Other Settings
|
||
Some repeated info from the configuration.
|
||
*** Home User
|
||
#+name: home-user
|
||
#+begin_src nix
|
||
home.username = "${user.username}";
|
||
home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}";
|
||
home.stateVersion = user.stateVersion;
|
||
#+end_src
|
||
|
||
*** Home Packages
|
||
A bunch of programs that I use.
|
||
#+name: home-packages
|
||
#+begin_src nix
|
||
home.packages = with pkgs; [
|
||
audacity # audio recording
|
||
handbrake # video transcoding
|
||
xdg-utils # utils, for screensharing
|
||
vlc # media player
|
||
pavucontrol # audio control
|
||
# everdo # gtd tool
|
||
spotify # music player
|
||
simple-scan # scanner software
|
||
# gimp2 # image editor
|
||
mpv # media player
|
||
kdePackages.kate # best texteditor
|
||
libreoffice # office suite
|
||
obsidian # knowegde base
|
||
vivaldi # browser
|
||
brave # browser
|
||
kdePackages.kdeconnect-kde # KDE Connect
|
||
pamixer # volumemixer
|
||
|
||
];
|
||
|
||
services.dunst.enable = true; # notifications daemon
|
||
|
||
programs.obs-studio.enable = true; # screen recording tool
|
||
#+end_src
|
||
|
||
* Emacs
|
||
I practically live inside emacs. The configuration for it is a mix between init.el and the nix configuration.
|
||
Nix allows me to install emacs packages as part of the configuration which is most of the following file.
|
||
I install the nix community provided emacs overlay that lets me have the latest emacs with pgtk ui (for wayland).
|
||
Comments describe the emacs package and what it does.
|
||
#+begin_src nix :tangle home/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;
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Early Initialization
|
||
There are some emacs settings that can be configured before the gui shows up.
|
||
And some of them help increase performance and let the gui show up that much faster.
|
||
These are listed here.
|
||
|
||
#+begin_src emacs-lisp :tangle home/emacs/early-init.el :mkdirp yes
|
||
;;; package --- early init -*- lexical-binding: t -*-
|
||
|
||
;;; Commentary:
|
||
;;; Prevents white flash and better Emacs defaults
|
||
|
||
;;; Code:
|
||
(set-language-environment "UTF-8")
|
||
|
||
(setq-default
|
||
default-frame-alist
|
||
'((background-color . "#1e1e2e")
|
||
(bottom-divider-width . 1) ; Thin horizontal window divider
|
||
(foreground-color . "#bac2de") ; Default foreground color
|
||
(fullscreen . maximized) ; Maximize the window by default
|
||
(horizontal-scroll-bars . nil) ; No horizontal scroll-bars
|
||
(left-fringe . 8) ; Thin left fringe
|
||
(menu-bar-lines . 0) ; No menu bar
|
||
(right-divider-width . 1) ; Thin vertical window divider
|
||
(right-fringe . 8) ; Thin right fringe
|
||
(tool-bar-lines . 0) ; No tool bar
|
||
(undecorated . t) ; Remove extraneous X decorations
|
||
(vertical-scroll-bars . nil)) ; No vertical scroll-bars
|
||
|
||
user-full-name "Henrov henrov" ; ME!
|
||
|
||
;; memory configuration
|
||
;; Higher garbage collection threshold, prevents frequent gc locks, reset later
|
||
gc-cons-threshold most-positive-fixnum
|
||
;; Ignore warnings for (obsolete) elisp compilations
|
||
byte-compile-warnings '(not obsolete)
|
||
;; And other log types completely
|
||
warning-suppress-log-types '((comp) (bytecomp))
|
||
;; Large files are okay in the new millenium.
|
||
large-file-warning-threshold 100000000
|
||
;; dont show garbage collection messages at startup, will reset later
|
||
garbage-collection-messages nil
|
||
;; native compilation
|
||
package-native-compile t
|
||
native-comp-warning-on-missing-source nil
|
||
native-comp-async-report-warnings-errors 'silent
|
||
|
||
|
||
;; Read more based on system pipe capacity
|
||
read-process-output-max (max (* 10240 10240) read-process-output-max)
|
||
|
||
;; scroll configuration
|
||
scroll-margin 0 ; Lets scroll to the end of the margin
|
||
scroll-conservatively 100000 ; Never recenter the window
|
||
scroll-preserve-screen-position 1 ; Scrolling back and forth
|
||
|
||
;; frame config
|
||
;; Improve emacs startup time by not resizing to adjust for custom settings
|
||
frame-inhibit-implied-resize t
|
||
;; Dont resize based on character height / width but to exact pixels
|
||
frame-resize-pixelwise t
|
||
|
||
;; backups & files
|
||
backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter
|
||
backup-by-copying t ; Don't clobber symlinks
|
||
create-lockfiles nil ; Don't have temp files
|
||
delete-old-versions t ; Cleanup automatically
|
||
kept-new-versions 6 ; Update every few times
|
||
kept-old-versions 2 ; And cleanup even more
|
||
version-control t ; Version them backups
|
||
delete-by-moving-to-trash t ; Dont delete, send to trash instead
|
||
|
||
;; startup
|
||
inhibit-startup-screen t ; I have already done the tutorial. Twice
|
||
inhibit-startup-message t ; I know I am ready
|
||
inhibit-startup-echo-area-message t ; Yep, still know it
|
||
initial-scratch-message nil ; I know it is the scratch buffer!
|
||
initial-buffer-choice nil
|
||
inhibit-startup-buffer-menu t
|
||
inhibit-x-resources t
|
||
initial-major-mode 'fundamental-mode
|
||
|
||
pgtk-wait-for-event-timeout 0.001 ; faster child frames
|
||
|
||
ad-redefinition-action 'accept ; dont care about legacy things being redefined
|
||
inhibit-compacting-font-caches t
|
||
|
||
;; tabs
|
||
tab-width 4 ; Always tab 4 spaces.
|
||
indent-tabs-mode nil ; Never use actual tabs.
|
||
|
||
;; rendering
|
||
cursor-in-non-selected-windows nil ; dont render cursors other windows
|
||
|
||
;; packages
|
||
use-package-always-defer t
|
||
|
||
load-prefer-newer t
|
||
|
||
default-input-method nil
|
||
|
||
use-dialog-box nil
|
||
|
||
use-file-dialog nil
|
||
|
||
use-package-expand-minimally t
|
||
|
||
package-enable-at-startup nil
|
||
|
||
use-package-enable-imenu-support t
|
||
|
||
auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist.
|
||
|
||
package-archives '(("melpa" . "https://melpa.org/packages/")
|
||
("gnu" . "https://elpa.gnu.org/packages/")
|
||
("nongnu" . "https://elpa.nongnu.org/nongnu/")
|
||
("melpa-stable" . "https://stable.melpa.org/packages/"))
|
||
|
||
package-archive-priorities '(("gnu" . 99)
|
||
("nongnu" . 80)
|
||
("melpa" . 70)
|
||
("melpa-stable" . 50))
|
||
)
|
||
;;; early-init.el ends here
|
||
#+end_src
|
||
|
||
** Initialization
|
||
Now starts the main emacs configuration.
|
||
|
||
#+begin_src emacs-lisp :tangle home/emacs/init.el :mkdirp yes
|
||
;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-
|
||
|
||
;;; Commentary:
|
||
;;; Simple Emacs setup I carry everywhere
|
||
|
||
;;; Code:
|
||
(setq custom-file (locate-user-emacs-file "custom.el"))
|
||
(load custom-file 'noerror) ;; no error on missing custom file
|
||
|
||
(require 'package)
|
||
(package-initialize)
|
||
|
||
(defun reset-custom-vars ()
|
||
"Resets the custom variables that were set to crazy numbers"
|
||
(setopt gc-cons-threshold (* 1024 1024 100))
|
||
(setopt garbage-collection-messages t))
|
||
|
||
(use-package emacs
|
||
:custom
|
||
(native-comp-async-query-on-exit t)
|
||
(read-answer-short t)
|
||
(use-short-answers t)
|
||
(enable-recursive-minibuffers t)
|
||
(which-func-update-delay 1.0)
|
||
(visible-bell nil)
|
||
(custom-buffer-done-kill t)
|
||
(whitespace-line-column nil)
|
||
(x-underline-at-descent-line t)
|
||
(imenu-auto-rescan t)
|
||
(uniquify-buffer-name-style 'forward)
|
||
(confirm-nonexistent-file-or-buffer nil)
|
||
(create-lockfiles nil)
|
||
(make-backup-files nil)
|
||
(kill-do-not-save-duplicates t)
|
||
(sentence-end-double-space nil)
|
||
(treesit-enabled-modes t)
|
||
:init
|
||
;; base visual
|
||
(menu-bar-mode -1) ;; no menu bar
|
||
(toggle-scroll-bar -1) ;; no scroll bar
|
||
(tool-bar-mode -1) ;; no tool bar either
|
||
(blink-cursor-mode -1) ;; stop blinking
|
||
|
||
;; font of the century
|
||
(set-frame-font "Aporetic Sans Mono 12" nil t)
|
||
|
||
:bind
|
||
(("C-<wheel-up>" . pixel-scroll-precision) ; dont zoom in please, just scroll
|
||
("C-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
|
||
("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask
|
||
:hook
|
||
(text-mode . delete-trailing-whitespace-mode)
|
||
(prog-mode . delete-trailing-whitespace-mode)
|
||
(after-init . global-display-line-numbers-mode) ;; always show line numbers
|
||
(after-init . column-number-mode) ;; column number in the mode line
|
||
(after-init . size-indication-mode) ;; file size in the mode line
|
||
(after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll
|
||
(after-init . electric-pair-mode) ;; i mean ... parens should auto create
|
||
(after-init . reset-custom-vars)
|
||
)
|
||
|
||
(use-package autorevert
|
||
:ensure nil
|
||
:custom
|
||
(auto-revert-interval 3)
|
||
(auto-revert-remote-files nil)
|
||
(auto-revert-use-notify t)
|
||
(auto-revert-avoid-polling nil)
|
||
(auto-revert-verbose t)
|
||
:hook
|
||
(after-init . global-auto-revert-mode))
|
||
|
||
(use-package recentf
|
||
:ensure nil
|
||
:commands (recentf-mode recentf-cleanup)
|
||
:hook
|
||
(after-init . recentf-mode)
|
||
:custom
|
||
(recentf-auto-cleanup 'never)
|
||
(recentf-exclude
|
||
(list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
|
||
"\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
|
||
"\\.7z$" "\\.rar$"
|
||
"COMMIT_EDITMSG\\'"
|
||
"\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
|
||
"-autoloads\\.el$" "autoload\\.el$"))
|
||
|
||
:config
|
||
;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
|
||
;; `recentf-save-list', allowing stale entries to be removed before the list
|
||
;; is saved by `recentf-save-list', which is automatically added to
|
||
;; `kill-emacs-hook' by `recentf-mode'.
|
||
(add-hook 'kill-emacs-hook #'recentf-cleanup -90))
|
||
|
||
(use-package savehist
|
||
:ensure nil
|
||
:commands (savehist-mode savehist-save)
|
||
:hook
|
||
(after-init . savehist-mode)
|
||
:custom
|
||
(savehist-autosave-interval 600)
|
||
(savehist-additional-variables
|
||
'(kill-ring ; clipboard
|
||
register-alist ; macros
|
||
mark-ring global-mark-ring ; marks
|
||
search-ring regexp-search-ring)))
|
||
|
||
(use-package hl-line
|
||
:ensure nil
|
||
:custom
|
||
(hl-line-sticky-flag nil)
|
||
(global-hl-line-sticky-flag nil)
|
||
:hook
|
||
(after-init . global-hl-line-mode))
|
||
|
||
(use-package saveplace
|
||
:ensure nil
|
||
:commands (save-place-mode save-place-local-mode)
|
||
:hook
|
||
(after-init . save-place-mode)
|
||
:custom
|
||
(save-place-limit 400))
|
||
|
||
(use-package nerd-icons
|
||
:custom
|
||
;; disable bright icon colors
|
||
(nerd-icons-color-icons nil))
|
||
|
||
(use-package doom-modeline
|
||
:custom
|
||
(inhibit-compacting-font-caches t) ;; speed
|
||
(doom-modeline-buffer-file-name-style 'relative-from-project)
|
||
(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you
|
||
(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway
|
||
(doom-modeline-buffer-state-icon nil) ;; the filename already shows me
|
||
(doom-modeline-lsp nil) ;; lsp state is too distracting, too often
|
||
:hook (after-init . doom-modeline-mode))
|
||
|
||
(load-theme 'catppuccin :no-confirm)
|
||
|
||
(use-package diminish :demand t) ;; declutter the modeline
|
||
(use-package eldoc
|
||
:diminish eldoc-mode
|
||
:custom
|
||
(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything
|
||
|
||
(use-package eldoc-box
|
||
:defer t
|
||
:config
|
||
(set-face-background 'eldoc-box-border (catppuccin-color 'green))
|
||
(set-face-background 'eldoc-box-body (catppuccin-color 'base))
|
||
:bind
|
||
(("M-h" . eldoc-box-help-at-point)))
|
||
|
||
(use-package pulsar
|
||
:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
|
||
:init
|
||
(defface pulsar-catppuccin
|
||
`((default :extend t)
|
||
(((class color) (min-colors 88) (background light))
|
||
:background ,(catppuccin-color 'sapphire))
|
||
(((class color) (min-colors 88) (background dark))
|
||
:background ,(catppuccin-color 'sapphire))
|
||
(t :inverse-video t))
|
||
"Alternative nord face for `pulsar-face'."
|
||
:group 'pulsar-faces)
|
||
:custom
|
||
(pulsar-face 'pulsar-catppuccin)
|
||
:hook
|
||
(after-init . pulsar-global-mode))
|
||
|
||
(use-package which-key
|
||
:commands which-key-mode
|
||
:diminish which-key-mode
|
||
:hook
|
||
(after-init . which-key-mode))
|
||
|
||
(use-package expreg
|
||
:bind ("M-m" . expreg-expand))
|
||
|
||
(use-package vundo) ;; undo tree
|
||
|
||
;; better structured editing
|
||
(use-package puni
|
||
:commands puni-global-mode
|
||
:hook
|
||
(after-init . puni-global-mode))
|
||
|
||
(use-package avy
|
||
:bind
|
||
("M-i" . avy-goto-char-2)
|
||
:custom
|
||
(avy-background t))
|
||
|
||
(use-package consult
|
||
:bind
|
||
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
|
||
("M-y" . consult-yank-pop) ;; orig. yank-pop
|
||
("M-g M-g" . consult-goto-line) ;; orig. goto-line
|
||
("M-g i" . consult-imenu) ;; consult version is interactive
|
||
("M-g r" . consult-ripgrep) ;; find in project also works
|
||
:custom
|
||
(consult-narrow-key "<"))
|
||
|
||
(use-package vertico
|
||
:commands vertico-mode
|
||
:custom
|
||
(read-file-name-completion-ignore-case t)
|
||
(read-buffer-completion-ignore-case t)
|
||
(completion-ignore-case t)
|
||
(enable-recursive-minibuffers t)
|
||
(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
|
||
:init
|
||
(vertico-mode)
|
||
:hook
|
||
(minibuffer-setup-hook . cursor-intangible-mode))
|
||
|
||
(use-package marginalia
|
||
:commands marginalia-mode
|
||
:hook (after-init . marginalia-mode))
|
||
|
||
(use-package crux
|
||
:bind
|
||
("C-c M-e" . crux-find-user-init-file)
|
||
("C-c C-w" . crux-transpose-windows)
|
||
("C-c M-d" . crux-find-current-directory-dir-locals-file)
|
||
("C-a" . crux-move-beginning-of-line))
|
||
|
||
(use-package magit
|
||
:bind (("C-M-g" . magit-status)))
|
||
|
||
(use-package nerd-icons-corfu
|
||
:commands nerd-icons-corfu-formatter
|
||
:defines corfu-margin-formatters)
|
||
|
||
(use-package corfu
|
||
:commands global-corfu-mode
|
||
:custom
|
||
(corfu-cycle t)
|
||
(corfu-auto t)
|
||
(corfu-auto-delay 1)
|
||
(corfu-auto-prefix 3)
|
||
(corfu-separator ?_)
|
||
:hook
|
||
(after-init . global-corfu-mode)
|
||
:config
|
||
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
|
||
|
||
(use-package cape)
|
||
|
||
(use-package orderless
|
||
:custom
|
||
(completion-styles '(orderless partial-completion basic))
|
||
(completion-category-defaults nil)
|
||
(completion-category-overrides nil))
|
||
|
||
(use-package yasnippet
|
||
:commands yas-global-mode
|
||
:diminish yas-minor-mode
|
||
:hook
|
||
(after-init . yas-global-mode))
|
||
|
||
(use-package yasnippet-snippets :after yasnippet)
|
||
|
||
(use-package exec-path-from-shell
|
||
:commands exec-path-from-shell-initialize
|
||
:custom
|
||
(exec-path-from-shell-arguments nil)
|
||
:hook
|
||
(after-init . exec-path-from-shell-initialize))
|
||
|
||
(use-package nixpkgs-fmt
|
||
:custom
|
||
(nixpkgs-fmt-command "nixfmt"))
|
||
|
||
(use-package eat
|
||
:bind
|
||
(("C-c e p" . eat-project)
|
||
("C-c e t" . eat)))
|
||
|
||
(use-package f :demand t)
|
||
|
||
(use-package envrc
|
||
:commands envrc-global-mode
|
||
:hook
|
||
(after-init . envrc-global-mode))
|
||
|
||
(use-package gptel
|
||
:commands gptel-make-anthropic f-read-text
|
||
:config
|
||
(gptel-make-anthropic "Claude"
|
||
:stream t :key (f-read-text "/run/secrets/claude_key")))
|
||
|
||
(use-package sideline-flymake)
|
||
(use-package sideline-eglot)
|
||
(use-package sideline
|
||
:custom
|
||
(sideline-backends-right '(sideline-flymake sideline-eglot))
|
||
:hook
|
||
(eglot-managed-mode . sideline-mode)
|
||
(flymake-mode . sideline-mode))
|
||
|
||
(use-package eglot
|
||
:custom
|
||
(eglot-extend-to-xref t)
|
||
(eglot-ignored-server-capabilities '(:inlayHintProvider))
|
||
(jsonrpc-event-hook nil)
|
||
:hook
|
||
(eglot-managed-mode . eldoc-box-hover-mode)
|
||
(before-save . eldoc-format-buffer)
|
||
:bind
|
||
(:map eglot-mode-map
|
||
("C-c l a" . eglot-code-actions)
|
||
("C-c l r" . eglot-rename)
|
||
("C-c l h" . eldoc)
|
||
("C-c l g" . xref-find-references)
|
||
("C-c l w" . eglot-reconnect)))
|
||
|
||
(use-package proced
|
||
:custom
|
||
(proced-auto-update-flag t)
|
||
(proced-auto-update-interval 3)
|
||
(proced-enable-color-flag t)
|
||
(proced-show-remote-processes t))
|
||
|
||
(use-package org
|
||
:ensure t
|
||
:defer t
|
||
:commands (org-mode org-capture org-agenda)
|
||
:init
|
||
(defvar org-journal-file "~/nextcloud/org/journal.org")
|
||
(defvar org-archive-file "~/nextcloud/org/archive.org")
|
||
(defvar org-notes-file "~/nextcloud/org/notes.org")
|
||
(defvar org-inbox-file "~/nextcloud/org/inbox.org")
|
||
(defvar org-work-file "~/nextcloud/org/work.org")
|
||
(defun my/org-capture-project-target-heading ()
|
||
"Determine Org target headings from the current file's project path.
|
||
|
||
This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
|
||
It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
|
||
for an Org capture template.
|
||
|
||
If the current buffer is not visi
|
||
ting a file within such a
|
||
project structure, it returns nil, causing capture to default to
|
||
the top of the file."
|
||
(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
|
||
(let ((path-parts (split-string path "/" t " ")))
|
||
(when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
|
||
(company (nth (+ 1 projects-pos) path-parts))
|
||
(project (nth (+ 2 projects-pos) path-parts)))
|
||
;; Return a list of headlines for Org to find or create.
|
||
(list company project)))))
|
||
:bind
|
||
(("C-c c" . org-capture)
|
||
("C-c i" . org-store-link)
|
||
("C-c a" . org-agenda)
|
||
:map org-mode-map
|
||
("C-c t" . org-toggle-inline-images)
|
||
("C-c l" . org-toggle-link-display))
|
||
:custom
|
||
(org-agenda-files (list org-inbox-file org-journal-file))
|
||
(org-directory "~/nextcloud/org")
|
||
(org-default-notes-file org-inbox-file)
|
||
(org-archive-location (concat org-archive-file "::* From %s"))
|
||
(org-log-done 'time)
|
||
(org-log-into-drawer t)
|
||
(org-hide-emphasis-markers t)
|
||
(org-src-fontify-natively t)
|
||
(org-src-tab-acts-natively t)
|
||
(org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
|
||
"* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
|
||
("j" "Journal" entry (file+olp+datetree org-journal-file)
|
||
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
|
||
("n" "Note" entry (file org-notes-file)
|
||
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
|
||
("p" "Project Task" item
|
||
(file+function org-work-file my/org-capture-project-target-heading)
|
||
"* TODO %? \n CLOCK: %U"
|
||
))
|
||
)
|
||
:config
|
||
;; Enable syntax highlighting in code blocks
|
||
(add-hook 'org-mode-hook 'turn-on-font-lock)
|
||
(add-hook 'org-mode-hook 'org-indent-mode))
|
||
|
||
;; extras
|
||
(use-package comp-run
|
||
:ensure nil
|
||
:config
|
||
(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
|
||
(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))
|
||
|
||
(use-package rustic
|
||
:custom
|
||
(rustic-lsp-client 'eglot))
|
||
|
||
(provide 'init)
|
||
|
||
;;; init.el ends here
|
||
#+end_src
|
||
|
||
* Machines
|
||
Only a few more things left. Specifically the machine level extra settings.
|
||
** Smallbox
|
||
The configuration for the laptop does not change much. Most changes are because the hardware is different.
|
||
*** System Level
|
||
Nothing specific for the laptop.
|
||
|
||
#+begin_src nix :tangle machines/traveldroid/configuration.nix :noweb tangle :mkdirp yes
|
||
{ user, ... } : {
|
||
imports =
|
||
[
|
||
./hardware-configuration.nix
|
||
../../configuration
|
||
];
|
||
|
||
<<traveldroid-secrets>>
|
||
}
|
||
#+end_src
|
||
|
||
*** Hardware
|
||
This is the most different. Mostly taken from hardware-configuration.nix setup at first install.
|
||
|
||
#+begin_src nix :tangle machines/traveldroid/hardware-configuration.nix :noweb tangle :mkdirp yes
|
||
{
|
||
hostname,
|
||
pkgs,
|
||
lib,
|
||
modulesPath,
|
||
user,
|
||
config,
|
||
...
|
||
}:
|
||
{
|
||
imports = [
|
||
(modulesPath + "/installer/scan/not-detected.nix")
|
||
../../hardware/hardware.nix
|
||
];
|
||
|
||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
|
||
boot.initrd.kernelModules = [ ];
|
||
boot.kernelModules = [ "kvm-intel" ];
|
||
boot.extraModulePackages = [ ];
|
||
|
||
fileSystems."/" =
|
||
{ device = "/dev/disk/by-uuid/69433a14-fbaf-401b-af85-cd1bbf02b4e2";
|
||
fsType = "ext4";
|
||
};
|
||
|
||
fileSystems."/boot" =
|
||
{ device = "/dev/disk/by-uuid/811D-0676";
|
||
fsType = "vfat";
|
||
options = [ "fmask=0077" "dmask=0077" ];
|
||
};
|
||
|
||
swapDevices =
|
||
[ { device = "/dev/disk/by-uuid/b6c557c2-7682-460b-a5e7-8f6f2f429a3a"; }
|
||
];
|
||
|
||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||
}
|
||
#+end_src
|
||
|
||
*** Home
|
||
This is mostly about configuring the monitor and key bindings. And laptop specific utilities.
|
||
#+begin_src nix :tangle machines/traveldroid/home.nix :noweb tangle :mkdirp yes
|
||
{ pkgs, ... } : {
|
||
imports = [
|
||
../../home
|
||
];
|
||
|
||
home.packages = with pkgs; [
|
||
brightnessctl
|
||
];
|
||
|
||
wayland.windowManager.hyprland.settings = {
|
||
bind = [
|
||
"XF86MonBrightnessUp, exec, brightnessctl set 5%+"
|
||
"XF86MonBrightnessDown, exec, brightnessctl set 5%-"
|
||
"XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
|
||
"XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
|
||
"XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
|
||
"XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
|
||
];
|
||
|
||
bindl = [
|
||
'', switch:on:Lid Switch, exec, hyprctl keyword monitor "eDP-1, disable"''
|
||
'', switch:off:Lid Switch, exec, hyprctl keyword monitor "eDP-1, preferred, 0x0, 1"''
|
||
];
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
*** Secrets
|
||
#+name: traveldroid-secrets
|
||
#+begin_src nix
|
||
# sops.secrets."ssh/traveldroid/private" = { # ssh private key
|
||
# owner = "${user.username}";
|
||
# mode = "600";
|
||
# path = "/home/${user.username}/.ssh/id_ed25519";
|
||
# };
|
||
# sops.secrets."ssh/traveldroid/public" = { # ssh public key
|
||
# owner = "${user.username}";
|
||
# mode = "644";
|
||
# path = "/home/${user.username}/.ssh/id_ed25519.pub";
|
||
# };
|
||
# sops.secrets."ssh/wavefunk/private" = { # ssh private key
|
||
# owner = "${user.username}";
|
||
# mode = "600";
|
||
# path = "/home/${user.username}/.ssh/wavefunk";
|
||
# };
|
||
# sops.secrets."ssh/wavefunk/public" = { # ssh public key
|
||
# owner = "${user.username}";
|
||
# mode = "644";
|
||
# path = "/home/${user.username}/.ssh/wavefunk.pub";
|
||
# };
|
||
# sops.secrets."ssh/wavefunk_dev/private" = { # ssh private key
|
||
# owner = "${user.username}";
|
||
# mode = "600";
|
||
# path = "/home/${user.username}/.ssh/wavefunk_dev";
|
||
# };
|
||
# sops.secrets."ssh/wavefunk_dev/public" = { # ssh public key
|
||
# owner = "${user.username}";
|
||
# mode = "644";
|
||
# path = "/home/${user.username}/.ssh/wavefunk_dev.pub";
|
||
# };
|
||
|
||
programs._1password.enable = true;
|
||
programs._1password-gui = {
|
||
enable = true;
|
||
polkitPolicyOwners = [ "${user.username}" ];
|
||
};
|
||
#+end_src
|
||
* README Utils
|
||
*** Headers
|
||
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))
|
||
#+END_SRC
|
||
|
||
# Local Variables:
|
||
# org-confirm-babel-evaluate: nil
|
||
# eval: (progn (org-babel-goto-named-src-block "startup") (org-babel-execute-src-block) (outline-hide-sublevels 1))
|
||
# End:
|