mirror of
https://github.com/tomasriveral/nixos.git
synced 2026-10-10 08:55:18 +02:00
694 lines
18 KiB
Markdown
694 lines
18 KiB
Markdown
# NixOS Configuration
|
||
|
||

|
||
|
||
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.
|
||
|
||
`<Space>` is the leader key.
|
||
|
||
| Key | Action |
|
||
| ------------------ | ---------------------- |
|
||
| `§` | Cheatsheet |
|
||
| `<leader>1` | Open fold |
|
||
| `<leader>2` | Close fold |
|
||
| `<leader>e1` | Show error message |
|
||
| `<leader>e2` | Show correction |
|
||
| `<leader>e3` | Show diagnostics |
|
||
| `<leader>e4` | Previous error |
|
||
| `<leader>e5` | Next error |
|
||
| `<leader>e<Tab>` | Stop grammar LSP |
|
||
| `<leader>f1` | Telescope files |
|
||
| `<leader>f2` | Telescope grep |
|
||
| `<leader>f3` | Telescope buffers |
|
||
| `<leader>f4` | Telescope help |
|
||
| `<leader>g1` | Hover documentation |
|
||
| `<leader>g2` | Go to definition |
|
||
| `<leader>g3` | Go to declaration |
|
||
| `<leader>g4` | Go to implementation |
|
||
| `<leader>g5` | Show references |
|
||
| `<leader><leader>` | Launch runner |
|
||
| `<leader>r1` | Run Fugitive |
|
||
| `t` | Count French syllables |
|
||
|
||
Some movement macros involving `<Space>`, `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 <secret_file>.age -i /etc/ssh/ssh_host_ed25519_key`.
|
||
* To decrypt a secret use `sudo agenix -d <secret_file>.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
|
||
```
|