TTY-themed NixOS Hyprland workstation flake
| Bare desktop | Tiled windows |
|---|---|
![]() |
![]() |
| Fuzzel launcher | Keybind cheatsheet (Super + /) |
|---|---|
![]() |
![]() |
| btop overlay (Ctrl + Shift + Esc) | Wallpaper switcher (Super + Shift + W) |
|---|---|
![]() |
![]() |
| Session menu (Ctrl + Alt + Delete) | Recording audio picker (Super + R) |
|---|---|
![]() |
![]() |
| Pavucontrol (Ctrl + Alt + V) |
|---|
![]() |
Waybar tooltips for CPU, RAM, swap, disk, GPU and battery:
Run the wizard on a NixOS system as your own user:
scripts/setup.sh- It asks for the username, hostname, login display name, commit author name, phone address, time zone, locale and screen size. It also asks for your git email and GPG key.
- Every question shows its current value. Enter keeps it.
- It prints a summary and writes nothing until you confirm.
- The email and key go to
~/.config/git/identityonly. Enternonefor the key to turn commit signing off. - It keeps
hosts/nixos/hardware-configuration.nixwhen it already matches the root filesystem. Otherwise it offers a new scan and defaults to no. - It offers to build the system and then to switch. The switch asks for sudo.
- It never offers the switch while the hardware file names another machine's disk. It also withholds the switch when the new username differs from your login, because the new account has no password yet. It prints the reason and the manual command.
--defaultsaccepts every default, rewritesvars.nixand stops.
The manual steps below do the same by hand.
-
Edit
vars.nix. It holds the username, hostname, login display name, commit author name, the Tailscale address of the paired phone, the time zone, the locale and the screen resolution. Every module reads these values from there. Set the phone address tonullto close the KDE Connect ports. -
Replace
hosts/nixos/hardware-configuration.nixwith your own:nixos-generate-config --show-hardware-config > hosts/nixos/hardware-configuration.nixchecks.configuration-safetypins the storage and boot layout of the original machine. Update the baseline inchecks/default.nixto match your hardware. -
Create the git identity file. It stays outside the repository:
mkdir -p ~/.config/git cat > ~/.config/git/identity <<'EOF' [user] email = [email protected] signingkey = YOUR_GPG_KEY_FINGERPRINT EOF chmod 600 ~/.config/git/identity
Commits are signed by default. Without a GPG key, set
signByDefault = falseinhome/rugbedbugg/git.nix. Each switch prints a warning until this file exists. -
Stage every new or renamed file before you build. Flakes only see files tracked by git. An untracked file fails with a "path does not exist" error, even if it is on disk.
-
Build and switch:
sudo nixos-rebuild switch --flake .#nixos -
Restore the state that stays outside the repository. Nothing here is automated on purpose.
- Import the GPG signing key whose fingerprint is in the git identity file.
- Authenticate Tailscale with
sudo tailscale up. - Sign in to Edge, Vesktop, Codex and Claude Code. Each keeps its own account state.
Keep private values such as your email out of vars.nix. It is committed and ends up in the world-readable Nix store. Put them in a runtime file like the git identity file instead.
From this directory:
nix --extra-experimental-features 'nix-command flakes' flake check --max-jobs 2 --cores 2
nix --extra-experimental-features 'nix-command flakes' build .#system --out-link result-system --max-jobs 2 --cores 2flake checkalso boots the whole system in a QEMU VM and checks the units, the user, the Home Manager activation and the core executables. It does the same for the fresh install host. It needs/dev/kvm. To run only the VM checks, one at a time, usescripts/vm-checks.sh. Passvm,vm-freshordisk-layoutto run a subset.- These commands write build results to the Nix store and a local result symlink. They do not change the active system, user configuration, bootloader or EFI files.
- The running configuration enables flakes. Use the explicit repository path for future rebuilds.
- The original
/etc/nixosfiles are retired to/etc/nixos/retired-2026-10-21/. A barenixos-rebuild switchstops with an error that points back to the flake. - The first permanent activation is complete. Do not rerun its one-time helper.
- Future activations still require build/test validation and a check of any EFI writes.
.#fresh is a second host for a machine that starts from an empty disk. It
shares the desktop, Home Manager and user modules with .#nixos. It has its
own hostname, nixos-fresh. It uses no hardware scan and no pinned storage
layout. hosts/fresh/disk-layout.nix declares
a 512M EFI partition and an ext4 root through disko.
- The
fresh.diskoption names the disk that disko wipes. It defaults to/dev/vda, the first disk of a virtual machine. A physical machine needs a dedicated disk set inhosts/fresh/disk-config.nix. Never use the disk of the.#nixoslaptop. - Two checks cover it.
vm-freshboots the full system.disk-layoutpartitions an empty disk, installs a minimal system and boots it. - Only these VM tests have run. No physical machine has been installed this way.
Dev shells are per project. Generate one from a template inside the project directory:
nix flake init -t ~/0xNix#python
direnv allow- Available templates:
python,go,bash,rust,node,cpp,systemsandai. - Each template is a standalone
flake.nixplus an.envrcwithuse flake. The project locks its own nixpkgs. - Templates track
nixos-unstableand carry no lockfile. The firstdirenv allowin a project locks the toolchains of that day. Two projects created on different days can get different versions. Commit the generatedflake.lockto keep a project reproducible. - This repo's own shell is
nix develop ~/0xNix. It holds the Nix and shell formatters and linters. - Python projects may use
uvto maintain their own dependency lock and virtualenv. - Fish/direnv integration is configured. Each project's
.envrcstill needs the normal explicitdirenv allowtrust decision.
| Key | Action |
|---|---|
| Super + B | Microsoft Edge |
| Super + Q | Close focused window |
| Super + V | Toggle floating |
| Super + arrows | Focus adjacent window |
| Super + 1…0 | Select workspace 1…10 |
| Super + Alt + 1…0 | Move window to workspace |
| Super + left/right mouse drag | Move/resize floating window |
| Super + Shift + E | End the UWSM session |
More bindings, using the plain desktop tools
(home/rugbedbugg/keybinds.nix):
| Key | Action |
|---|---|
| Super (tap) | Fuzzel application launcher |
| Super + T / B / C / O | Foot / Edge / Neovim in Foot / LibreOffice |
| Super + / | Keybind cheatsheet |
| Super + E | Toggle the lf file manager overlay |
| Super + M | Toggle the rmpc music overlay |
| Super + D | Toggle the Discord (Vesktop) overlay |
| Super + W | Toggle the WhatsApp (ZapFast) overlay |
| Super + Y | Toggle the YouTube (youtube-tui) overlay |
| Super + S | Toggle the scratch terminal overlay |
| Ctrl + Shift + Esc | Toggle the btop overlay |
| Super + F | Maximize the window. The bar stays visible |
| Super + Shift + W | Wallpaper switcher |
| Super + Shift + T | Minimap of the focused window. Drag to move, scroll to resize, right-click for a menu. Press again to close |
| Super + Shift + arrows | Move window |
| Super + L | Lock session |
| Ctrl + Alt + Delete | Session menu: lock, logout, suspend, reboot, shutdown. Logout, reboot and shutdown ask first. |
| Super + N | Show the last dismissed notification |
| Ctrl + Alt + C | Dismiss all notifications |
| Screenshot the screen and open it in satty | |
| Super + Shift + S | Screenshot a region and open it in satty |
| Super + R | Record the screen. Press again to stop |
| Super + Shift + R | Record a region. Press again to stop |
| Ctrl + Alt + V | Pavucontrol |
| Ctrl + Super + Shift + R | Restart waybar |
| Ctrl + Super + Shift + L | Suspend |
lf runs in the Super + E overlay. It also opens for file dialogs in apps that use the desktop portal, such as Edge and Vesktop.
| Key | Action |
|---|---|
| j / k or ↓ / ↑ | Move down / up |
| l, → or Enter | Enter a folder or open a file |
| h or ← | Go to the parent folder |
| gg / G | Jump to the top / bottom |
| Ctrl + D / Ctrl + U | Move half a page down / up |
| gh | Go to the home folder |
| . | Show or hide hidden files |
| / then n / N | Search, then jump to the next / previous match |
| f then a letter | Jump to the next name starting with that letter. ; repeats it |
| :cd path | Go to a path. Tab completes |
| Space | Mark a file and move down |
| u | Clear all marks |
| y / d / p | Copy / cut / paste |
| r | Rename |
| a | Make a folder |
| Delete | Delete, after a prompt |
| q | Quit |
In a file dialog:
- Open a file to pick it.
- Mark several with Space, then open one to pick them all.
- Go into a folder and quit to pick that folder.
- Open the suggested file to save.
- Quit without opening anything to cancel.
Screenshots open in satty. Nothing is saved or copied until you ask.
| Key | Action |
|---|---|
| c | Crop |
| z / i / r / e | Arrow / line / rectangle / ellipse |
| t | Text |
| m | Numbered marker |
| u | Blur |
| g | Highlight |
| b | Brush |
| p | Pointer |
| 1…0 | Pick a palette colour |
| Ctrl + Z / Ctrl + Y | Undo / redo |
| Ctrl + S | Save to ~/Pictures/Screenshots |
| Ctrl + Shift + S | Save as, through the lf file dialog |
| Ctrl + C | Copy to the clipboard |
| Enter | Save and close |
| Esc | Close without saving |
-
Each recording starts with a menu to pick the audio: none, system audio, microphone, or system and microphone mixed. It remembers the last choice.
-
A red
REC m:sstimer shows left of the clock while it runs. Its tooltip lists the file, area, audio, encoder, size so far and start time. -
Only you see the timer. Recordings and screenshots get a black box in its place.
-
Click the timer or press the record key again to stop. A menu then asks whether to keep the video.
-
Kept recordings are saved as MP4 in
~/Videos/Recordings. Nothing is copied to the clipboard. -
Volume, microphone mute, media and display brightness keys are configured.
-
The session locks after ten idle minutes and requests a lock before suspend.
-
Runtime checks, including successful unlock, are still required before treating this as verified.
- Review and change pins deliberately, rebuild and inspect the resulting diff.
- Do not change
system.stateVersionorhome.stateVersionas an upgrade shortcut. checks.configuration-safetydeliberately rejects boot/storage changes. Changing that policy requires a deliberate baseline update inchecks/default.nix.










