# NixOS Configuration ![NixOS configuration](/assets/example.png) This repository contains my personal NixOS configuration. The configuration uses the **[dendritic pattern](https://github.com/mightyiam/dendritic)**. Instead of keeping one large system configuration, functionality is split into smaller, composable modules. This makes it easier to reuse pieces of the configuration across hosts and to keep application, hardware, utility, and host-specific configuration separate. See the [dendritic pattern repository](https://github.com/mightyiam/dendritic) for an explanation of the approach. --- ## Installation This configuration is primarily designed for my own machines, so some parts are host- and hardware-specific. ### Requirements * NixOS * Git * Nix flakes enabled Clone the repository: ```bash cd ~ git clone https://github.com/tomasriveral/nixos.git cd nixos ``` The available hosts are: ```text hosts/ ├── laptop.nix └── desktop.nix ``` Build and switch to a host with: ```bash sudo nixos-rebuild switch --flake ~/nixos#laptop ``` or: ```bash sudo nixos-rebuild switch --flake ~/nixos#desktop ``` For a temporary test generation: ```bash sudo nixos-rebuild test --flake ~/nixos#laptop ``` ### Hardware configuration Hardware-specific configuration is kept under: ```text modules/hardware/ ``` This includes: * bootloader configuration * disks and filesystems * battery and power management * Bluetooth * NVIDIA * performance settings * udev rules * hardware utilities Declarative disk configuration is located in: ```text modules/hardware/disko/ ``` When deploying this configuration to a new machine, review the host and hardware modules rather than assuming the existing hardware configuration is appropriate. --- # Repository Structure ```text nixos/ ├── assets/ # Wallpapers, images, sounds and other static assets ├── docs/ # Additional documentation │ └── printing.md │ ├── modules/ │ ├── applications/ # Application and desktop application configuration │ ├── hardware/ # Hardware, boot, disk, battery, GPU and device configuration │ ├── other/ # Fonts, cursor, printer, desktop entries, user configuration, etc. │ ├── packages/ # Custom packages and scripts │ └── utilities/ # Reusable utilities and supporting services │ ├── hosts/ │ ├── laptop.nix # Laptop-specific configuration │ └── desktop.nix # Desktop-specific configuration │ ├── other/ │ ├── hyprland/ # Hyprland configuration │ │ ├── hyprland.conf # Previous hyprlang configuration │ │ ├── hyprland.lua # Current Lua configuration │ │ └── README.md │ ├── kblayouts/ # Keyboard and Framework macropad layouts │ ├── mullvad/ # Mullvad configuration │ └── quickshell/ # Quickshell configuration │ ├── secrets/ # agenix-encrypted secrets ├── flake.nix ├── flake.lock └── README.md ``` --- # Modules ## Applications `modules/applications/` contains configuration for applications and desktop components. Some examples: * `anki.nix` * `browser.nix` * `caelestia.nix` * `git.nix` * `gtk.nix` * `hypridle.nix` * `hyprland.nix` * `kitty.nix` * `neovim.nix` * `obsidian.nix` * `rofi.nix` * `thunderbird.nix` * `waybar.nix` * `wlogout.nix` * `zsh.nix` ## Hardware `modules/hardware/` contains machine-level configuration such as: * battery and power management * Bluetooth * bootloader * disks * hardware detection/configuration * NVIDIA * performance tuning * udev rules ## Other `modules/other/` contains configuration that does not fit directly into applications or hardware, such as: * cursors * desktop entries * fonts * I/O configuration * printers * user configuration ## Packages `modules/packages/` contains custom packages and scripts used throughout the configuration. Examples include: * `custom-bottom` * `custom-browserprofiles` * `custom-colorpicker` * `custom-cowsay` * `custom-syllabes` * `custom-tomato` * `custom-weather` * manually derived packages Many of these packages are called directly by Hyprland keybindings. ## Utilities `modules/utilities/` contains reusable system utilities and services, including: * agenix * audio/media configuration * automatic cleanup * automatic updates * communication and notifications * development tools * documentation tools * Git backup * LaTeX * networking * Nix utilities * office tools * Ollama * RSS tools --- # Hosts Host-specific configuration is kept under: ```text hosts/ ``` Currently: ```text hosts/ ├── laptop.nix └── desktop.nix ``` The host files combine the nixos and home-manager modules needed for each machine. --- # Hyprland Hyprland is configured using its **Lua configuration API**. The current configuration is: ```text other/hyprland/hyprland.lua ``` The previous hyprlang configuration remains here: ```text other/hyprland/hyprland.conf ``` Host specific hyprland settings are generated by `/modules/applications/hyprland.nix` as `host.lua` which is imported by `hyprland.lua`. ## Workspace layouts The current layout configuration is: | Workspace | Layout | | --------- | ----------- | | `1` | `master` | | `2` | `scrolling` 0.45 width | | `other` | `dwindle` | ## Wallpapers The wallpapers are stored in: ```text assets/ ├── wallpaper1.jpg ├── wallpaper2.jpg ├── wallpaper3.jpg ├── wallpaper4.jpg └── wallpaper5.jpg ``` The active wallpaper is selected based on the workspace: | Workspace | Wallpaper | | --------- | ---------------- | | `1` | `wallpaper1.jpg` | | `2` | `wallpaper2.jpg` | | `3` | `wallpaper3.jpg` | | `4` | `wallpaper4.jpg` | | `5` | `wallpaper5.jpg` | | `6` | `wallpaper1.jpg` | | `7` | `wallpaper2.jpg` | | `8` | `wallpaper3.jpg` | | `9` | `wallpaper4.jpg` | | `10` | `wallpaper5.jpg` | The Lua configuration contains placeholders for these paths, which are replaced by Nix during configuration generation. The five wallpapers are paintings from Thomas Cole's *The Course of Empire* series. --- # Hyprland Keybindings `SUPER` is the primary modifier. ## Window management | Key | Action | | ----------------------------------- | ----------------- | | `SUPER + W` | Toggle floating | | `SUPER + G` | Toggle group | | `ALT + Return` | Toggle fullscreen | | `SUPER + Arrow keys` | Move focus | | `SUPER + CTRL + A` | Swap column left | | `SUPER + CTRL + D` | Swap column right | | `SUPER + SHIFT + CTRL + Arrow keys` | Move window | | `SUPER + SHIFT + Arrow keys` | Resize window | | `SUPER + Z` | Drag window | | `SUPER + X` | Resize window | | `SUPER + mouse:272` | Drag window | | `SUPER + mouse:273` | Resize window | ## Workspaces | Key | Action | | ---------------------- | --------------------------------------- | | `SUPER + 1..9` | Focus workspace 1–9 | | `SUPER + 0` | Focus workspace 10 | | `SUPER + SHIFT + 1..9` | Move window to workspace 1–9 | | `SUPER + SHIFT + 0` | Move window to workspace 10 | | `SUPER + CTRL + Right` | Move to relative workspace `+1` | | `SUPER + CTRL + Left` | Move to relative workspace `-1` | | `SUPER + CTRL + Down` | Focus an empty workspace | | `SUPER + mouse_down` | Next workspace | | `SUPER + mouse_up` | Previous workspace | | `SUPER + S` | Toggle special workspace | | `SUPER + ALT + S` | Move active window to special workspace | ## Scrolling layout | Key | Action | | ----------- | --------------------------- | | `SUPER + A` | Move scrolling layout left | | `SUPER + D` | Move scrolling layout right | ## Custom window management ### `SUPER + Q` A custom Lua function checks the active window. * Steam → move it to the special workspace * `custom-pomodoro` → move it to the special workspace * anything else → close the window ### `SUPER + CTRL + 6` Closes every window on the current workspace except the currently focused window. --- # Applications | Key | Action | | ------------------- | ------------------------ | | `SUPER + T` | Kitty | | `SUPER + E` | Dolphin | | `SUPER + F` | Browser profile selector | | `SUPER + N` | Obsidian vault selector | | `SUPER + SHIFT + A` | Application launcher | | `SUPER + Backspace` | Session drawer | | `CTRL + ALT + W` | Sidebar | | `SUPER + L` | Lock screen | | `SUPER + SHIFT + S` | Screenshot picker | | `F11` | Screenshot | | `SUPER + V` | Clipboard history Additional bindings launch or control: * Hyprland keybinding viewer * Pavucontrol * GNOME Characters * Anki * custom performance mode * custom tomato/pomodoro * custom bottom launcher * custom audio-output selector * Caelestia shell --- # Multimedia and Hardware Keys | Key | Action | | ---- | -------------------- | | `F1` | Mute audio | | `F2` | Volume down | | `F3` | Volume up | | `F4` | Previous media track | | `F5` | Play/pause | | `F6` | Next media track | | `F7` | Brightness down | | `F8` | Brightness up | Volume and brightness bindings repeat while held. --- # Gestures The current Hyprland configuration includes: | Gesture | Action | | ----------------------- | ------------- | | Three-finger horizontal | `scroll_move` (only for scrolling layout) | | Two-finger pinch | Cursor zoom | --- # Framework 16 RGB Macropad The Framework 16 RGB Macropad layout is stored at: ```text other/kblayouts/framework_laptop_16_rgb_macropad.layout.json ``` The macropad is used as a collection of physical shortcuts for actions that already have Hyprland keybindings. The macros in the layout generate combinations involving `CTRL`, `ALT`, `SUPER`, and `SHIFT`. The important part is the **logical mapping** between each physical macropad position and its Hyprland shortcut. > Positions are documented as `[row, column]`, starting from the top-left. | Macropad Key | Linked Action | | ------------ | ------------------------------------------------- | | Row 1, Col 1 | Kill all apps except focused (`CTRL + SUPER + 6`) | | Row 1, Col 2 | Performance mode (`CTRL + ALT + 7`) | | Row 1, Col 3 | Do not disturb (`CTRL + SUPER + 4`) | | Row 1, Col 4 | Notification center (`CTRL + ALT + 1`) | | Row 2, Col 1 | PulseAudio control (`CTRL + SUPER + 3`) | | Row 2, Col 2 | Change audio output (`CTRL + ALT + SHIFT + 0`) | | Row 2, Col 3 | Special characters (`CTRL + SUPER + 5`) | | Row 2, Col 4 | Color picker (`CTRL + ALT + 8`) | | Row 4, Col 1 | Launch Anki (`CTRL + ALT + 9`) | The physical layout file contains additional transparent/unused positions, but the bindings above are the active shortcuts documented for the macropad. --- # Neovim Neovim is configured in: ```text modules/applications/neovim.nix ``` The configuration includes LSP support, Telescope, Git tooling, grammar tooling and custom commands. `` is the leader key. | Key | Action | | ------------------ | ---------------------- | | `§` | Cheatsheet | | `1` | Open fold | | `2` | Close fold | | `e1` | Show error message | | `e2` | Show correction | | `e3` | Show diagnostics | | `e4` | Previous error | | `e5` | Next error | | `e` | Stop grammar LSP | | `f1` | Telescope files | | `f2` | Telescope grep | | `f3` | Telescope buffers | | `f4` | Telescope help | | `g1` | Hover documentation | | `g2` | Go to definition | | `g3` | Go to declaration | | `g4` | Go to implementation | | `g5` | Show references | | `` | Launch runner | | `r1` | Run Fugitive | | `t` | Count French syllables | Some movement macros involving ``, `g`, and recording with `q` are intentionally disabled. --- # Shell The shell is based on **zsh**. Relevant configuration is primarily found in: ```text modules/applications/zsh.nix ``` and related application modules. `oh-my-zsh` is used for shell customization. `deja` is used for shell completion. Useful command-line tools include: * `eza` * `zoxide` * `ripgrep` * `fzf` * `fastfetch` * `man` * `manix` `ls` is replaced by `eza`. Common aliases include: ```text l ll la ``` --- # Git and Nix Workflow The configuration includes tooling for Git, Nix development, backups and cherry-picking. Relevant modules include: ```text modules/utilities/gitBackup.nix modules/utilities/nixGitCherryPicker.nix modules/utilities/nixUtils.nix ``` Two useful rebuild aliases are: ```bash snrt ``` which runs: ```bash git add -A && sudo nixos-rebuild test --flake ~/nixos/#laptop ``` and: ```bash snrs ``` which runs: ```bash git add -A && sudo nixos-rebuild switch --flake ~/nixos/#laptop ``` These aliases currently target the laptop host. --- # Secrets Secrets are managed using **agenix**. The relevant files are: ```text secrets/ ├── ntfy.age └── secrets.nix ``` Encrypted secrets should remain encrypted in Git. Decrypted secret contents and private keys should not be committed. * To edit a secret use `agenix -e .age -i /etc/ssh/ssh_host_ed25519_key`. * To decrypt a secret use `sudo agenix -d .age -i /etc/ssh/ssh_host_ed25519_key`. --- # Quickshell The legacy Quickshell configuration lives under: ```text other/quickshell/ ``` --- # Custom Packages Custom scripts and packages are located in: ```text modules/packages/ ``` Examples include: * `custom-colorpicker` * `custom-cowsay` * `custom-syllabes` * `custom-tomato` * `custom-weather` * `vivifyManuallyDerived` * `dejaManuallyDerived` Or imported in flake.nix from other repos. Examples include: * `custom-browserprofiles` Fzf selector between different LibreWolf profiles, private window and the tor browser. * `custom-syllabes` A syllab counter when I write french poetry. (note: algorithmic syllab counting is pretty difficult in french, so this small scripts makes a lot of errors) * `ngcp` (see the [GitHub repo](https://github.com/tomasriveral/Nix-Git-Cherry-Picker)) is what i use to manage between my `laptop` and `desktop` git branch. * `nixpkgs-notifier` (see the [GitHub repo](https://github.com/tomasriveral/nixpkgs-notifier)) notifies my when PRs get merged to nixos-unstable. --- # Applications and Desktop Environment The configuration currently contains modules for applications and components such as: * Hyprland * Kitty * Dolphin * LibreWolf/browser tooling * Thunderbird * Obsidian * Neovim * Caelestia * Quickshell * Hypridle * Rofi * Waybar * Wlogout * Git * SSH * Mullvad * Bluetooth * audio/media tools * office tools * LaTeX * development tools * Ollama The exact set of enabled software depends on the host configuration and imported modules. --- # Things That Still Require Manual Setup Not everything used by the desktop environment is completely declarative. Some application state may need to be configured manually after installation: * LibreWolf extension settings * LibreWolf bookmarks * Thunderbird account/server settings * Birdtray settings * Inkscape settings * other application-specific user data * git configuration --- # Useful Information * Wallpapers are five paintings from Thomas Cole's *The Course of Empire*. * `qtbatticon` is a custom battery tray indicator. * `man` and `manix` use `fzf` for fuzzy searching. * `pkgs-unstable` is available for packages that need to come from unstable nixpkgs. * `pkgs-master` can be enabled in flake.nix. Attention, all the packages will need to be compiled on the machine. * `pkgs-local` can be enable in flake.nix. Attention, all the packages will need to be compiled on the machine. * Automatic Nix garbage collection removes old generations according to the configured cleanup policy. * Non-free packages are enabled where required. * Neovim plugins are configured in `modules/applications/neovim.nix`. * `oh-my-zsh` configuration is kept with the shell/application modules. * The Framework 16 RGB Macropad layout is stored in `other/kblayouts/framework_laptop_16_rgb_macropad.layout.json`. * Anki-related configuration is distributed across the relevant application/package modules. * Battery and power-related configuration is under `modules/hardware/`. * Custom commands used by Hyprland are generally provided by `modules/packages/`. --- # Documentation Additional documentation is kept close to the corresponding configuration where practical. Important documentation files include: ```text docs/printing.md modules/applications/README.md modules/hardware/disko/README.md modules/packages/README.md modules/utilities/README.md other/hyprland/README.md other/mullvad/README.md other/quickshell/README.md ```