Initial commit: Nomarchy NixOS configuration

An opinionated NixOS configuration with Hyprland, featuring:

- Modular flake-based architecture
- Parameterized user configuration (username, timezone, locale, etc.)
- Classical/antiquity theme with Thomas Cole wallpapers
- Full Hyprland setup with waybar, rofi, swaync
- Custom utility scripts (screenshots, screen recording, WiFi QR)
- Neovim with LSP support
- Interactive installer for existing NixOS systems
- ISO builder for fresh installations

Flake outputs:
- nixosConfigurations.example - Test configuration
- nixosConfigurations.installer - ISO installer
- packages.iso - Bootable ISO image
- apps.default - Interactive installer
- lib.mkHost - Host builder function
- templates.default - Starter template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 02:44:33 -05:00
commit 58e4232f2f
50 changed files with 3853 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
# Nix build artifacts
result
result-*
# Secrets (never commit unencrypted secrets)
secrets/*.age
!secrets/secrets.nix
# Editor files
*.swp
*.swo
*~
.idea/
.vscode/
# OS files
.DS_Store
Thumbs.db
# Local user config (generated by installer)
config.local.nix

115
README.md Normal file
View File

@@ -0,0 +1,115 @@
# Nomarchy
An opinionated NixOS configuration featuring Hyprland, designed for developers who want a beautiful, functional, and reproducible desktop environment.
## Quick Start
### For Existing NixOS Systems
```bash
nix run github:blu/nomarchy
```
This launches an interactive installer that:
1. Prompts for your username, timezone, keyboard layout, etc.
2. Generates a configuration in `~/.config/nomarchy/`
3. Applies the configuration to your system
### From ISO (Coming Soon)
Download the ISO from the releases page and boot from it for a fresh installation with LUKS encryption.
## Features
- **Hyprland** - Modern Wayland compositor with smooth animations
- **Waybar** - Customizable status bar
- **Rofi** - Application launcher and quick actions
- **SwayNC** - Notification center
- **Neovim** - Fully configured with LSP support
- **Classical Theme** - Earthy, vintage aesthetic inspired by historical paintings
## Keybindings
| Key | Action |
|-----|--------|
| `Super + Q` | Terminal |
| `Super + R` | App Launcher |
| `Super + E` | File Manager |
| `Super + B` | Browser |
| `Super + W` | Close Window |
| `Super + F` | Fullscreen |
| `Super + V` | Toggle Float |
| `Super + /` | Quick Actions |
| `Super + A` | Notifications |
| `Super + Escape` | Power Menu |
| `Super + 1-9` | Workspaces |
| `Print` | Screenshot |
| `Super + Shift + R` | Record Screen |
## Customization
### Changing Theme
Edit `~/.config/nomarchy/config.nix`:
```nix
{
theme = "classical"; # Currently the only theme, more coming soon
}
```
### Adding Packages
Create a custom module:
```nix
# ~/.config/nomarchy/my-packages.nix
{ pkgs, ... }: {
environment.systemPackages = with pkgs; [
my-package
];
}
```
Add it to your flake:
```nix
extraModules = [
./my-packages.nix
];
```
### Wallpapers
Copy your wallpapers to `~/.config/nomarchy/wallpapers/` and they'll be used for the random rotation.
## Structure
```
nomarchy/
├── flake.nix # Main flake
├── lib/ # Helper functions
├── modules/
│ ├── core/ # Boot, networking, hardware
│ ├── desktop/ # Hyprland, display manager
│ ├── services/ # Syncthing, printing, VPN
│ ├── programs/ # System packages
│ ├── performance/ # Optimizations
│ └── home/ # Home-manager configs
├── themes/
│ └── classical/ # Default theme
├── installer/ # Installation scripts
└── iso/ # ISO builder
```
## Security Note
The `enableMitigationsOff` option disables CPU vulnerability mitigations (Spectre, Meltdown, etc.) for improved performance. This is **disabled by default** and should only be enabled if you understand the security implications.
## Credits
Inspired by [Omarchy](https://github.com/basecamp/omarchy) and the NixOS community.
## License
MIT

154
docs/CUSTOMIZATION.md Normal file
View File

@@ -0,0 +1,154 @@
# Customization Guide
## Configuration File
Your configuration lives in `~/.config/nomarchy/config.nix`:
```nix
{
# User settings
username = "yourname";
hostname = "yourhostname";
timezone = "America/New_York";
locale = "en_US.UTF-8";
# Keyboard (supports multiple layouts)
keyboardLayouts = ["us" "gr"];
keyboardVariants = ["" "polytonic"];
# Location for night light
location = {
lat = 40.7;
lon = -74.0;
};
# Features
enableSyncthing = true;
enableMullvad = false;
enablePrinting = true;
enableBluetooth = true;
# Performance (security tradeoff!)
enableMitigationsOff = false;
# Theme
theme = "classical";
}
```
## Adding Custom Modules
Create a module in `~/.config/nomarchy/`:
```nix
# ~/.config/nomarchy/custom.nix
{ config, pkgs, ... }: {
# System packages
environment.systemPackages = with pkgs; [
discord
spotify
];
# Services
services.docker.enable = true;
# User groups
users.users.${config.nomarchy.username}.extraGroups = ["docker"];
}
```
Add it to your flake:
```nix
extraModules = [
./custom.nix
];
```
## Wallpapers
1. Copy images to `~/.config/nomarchy/wallpapers/`
2. Supported formats: `.jpg`, `.png`
3. Wallpapers rotate every 5 minutes automatically
4. Use Quick Actions (`Super + /`) → "Change Wallpaper" for immediate change
## Theme Colors
The classical theme colors are defined in the theme module. To override colors in your waybar or rofi, you can create custom CSS files.
### Color Palette
| Name | Hex | Usage |
|------|-----|-------|
| bg.primary | `#1a1611` | Main background |
| bg.secondary | `#2d2620` | Panels, inputs |
| fg.primary | `#d4c4a8` | Main text |
| accent.gold | `#d4a857` | Primary accent |
| accent.terracotta | `#c67b5c` | Secondary accent |
| status.success | `#8a9a5b` | Success states |
| status.error | `#a63d40` | Error states |
## Shell Aliases
Default aliases (in `~/.zshrc` via home-manager):
```bash
ls → eza --icons
ll → eza -l --icons
la → eza -la --icons
update → sudo nixos-rebuild switch --flake ~/.config/nomarchy#
gc → sudo nix-collect-garbage -d
du → dust
```
## Neovim
The default Neovim configuration includes:
- LSP support for Nix, Lua, TypeScript, Rust, Go, Python, Markdown
- Telescope for fuzzy finding
- Treesitter for syntax highlighting
- Git integration with gitsigns
To customize, create `~/.config/nvim/lua/custom/init.lua` (loaded after main config).
## Terminal (Ghostty)
Customize in `~/.config/ghostty/config`:
```
font-size = 16
background-opacity = 0.9
```
## Hyprland
For advanced Hyprland customization, you can add settings via home-manager:
```nix
# In your custom module
{ config, ... }: {
home-manager.users.${config.nomarchy.username} = {
wayland.windowManager.hyprland.settings = {
# Add your custom settings here
windowrulev2 = [
"float,class:^(pavucontrol)$"
];
};
};
}
```
## Rebuilding
After making changes:
```bash
cd ~/.config/nomarchy
sudo nixos-rebuild switch --flake .#yourhostname
```
Or use the alias:
```bash
update
```

92
docs/KEYBINDINGS.md Normal file
View File

@@ -0,0 +1,92 @@
# Nomarchy Keybindings
## Window Management
| Key | Action |
|-----|--------|
| `Super + Q` | Open terminal (Ghostty) |
| `Super + W` | Close active window |
| `Super + M` | Exit Hyprland |
| `Super + F` | Toggle fullscreen (windowed) |
| `Super + Shift + F` | Toggle fullscreen (standalone) |
| `Super + V` | Toggle floating |
| `Super + P` | Pseudo tile |
| `Super + J` | Toggle split direction |
## Focus & Movement
| Key | Action |
|-----|--------|
| `Super + Left/Right/Up/Down` | Move focus |
| `Super + 1-9, 0` | Switch to workspace 1-10 |
| `Super + Shift + 1-9, 0` | Move window to workspace 1-10 |
| `Super + S` | Toggle scratchpad |
| `Super + Shift + S` | Move window to scratchpad |
| `Super + Mouse Wheel` | Scroll through workspaces |
## Mouse Bindings
| Key | Action |
|-----|--------|
| `Super + Left Click + Drag` | Move window |
| `Super + Right Click + Drag` | Resize window |
## Applications
| Key | Action |
|-----|--------|
| `Super + R` | Open app launcher (Rofi) |
| `Super + E` | Open file manager (Dolphin) |
| `Super + B` | Open browser (Firefox) |
## Quick Actions
| Key | Action |
|-----|--------|
| `Super + /` or `Super + Space` | Quick Actions menu |
| `Super + Escape` | Power menu |
| `Super + A` | Notification center |
## Screenshots & Recording
| Key | Action |
|-----|--------|
| `Print` | Screenshot to clipboard |
| `Super + Print` | Screenshot region (with Satty editor) |
| `Super + Shift + Print` | Screenshot region to clipboard |
| `Super + Alt + Print` | Screenshot active window |
| `Super + Shift + R` | Toggle screen recording |
## Media & Brightness
| Key | Action |
|-----|--------|
| `XF86AudioRaiseVolume` | Volume +5% |
| `XF86AudioLowerVolume` | Volume -5% |
| `XF86AudioMute` | Toggle mute |
| `XF86AudioMicMute` | Toggle mic mute |
| `XF86MonBrightnessUp` | Brightness +10% |
| `XF86MonBrightnessDown` | Brightness -10% |
| `XF86AudioNext/Prev/Play` | Media controls |
## Keyboard Layout
| Key | Action |
|-----|--------|
| `Right Alt` | Switch keyboard layout |
## Quick Actions Menu Options
The Quick Actions menu (`Super + /`) provides access to:
- Screenshot Region
- Screenshot Window
- Record Screen
- Clipboard History
- Share WiFi (QR Code)
- Change Wallpaper
- Color Picker
- Notifications
- System Settings
- Keybindings Help
- Lock/Logout/Reboot/Shutdown

649
flake.lock generated Normal file
View File

@@ -0,0 +1,649 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1770165109,
"narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=",
"owner": "ryantm",
"repo": "agenix",
"rev": "b027ee29d959fda4b60b57566d64c98a202e0feb",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"aquamarine": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1770895474,
"narHash": "sha256-JBcrq1Y0uw87VZdYsByVbv+GBuT6ECaCNb9txLX9UuU=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "a494d50d32b5567956b558437ceaa58a380712f7",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "aquamarine",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1744478979,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"hyprland",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1745494811,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1771132481,
"narHash": "sha256-Tc+YqZ/Q1K35vJK4ji4RbLB/qKGcEq6yh7p4CKoZF60=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "1e53254671f36cb7d0e2dcca08730f066d5e69b4",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"hyprcursor": {
"inputs": {
"hyprlang": [
"hyprland",
"hyprlang"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1753964049,
"narHash": "sha256-lIqabfBY7z/OANxHoPeIrDJrFyYy9jAM4GQLzZ2feCM=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "44e91d467bdad8dcf8bbd2ac7cf49972540980a5",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprcursor",
"type": "github"
}
},
"hyprgraphics": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1770511807,
"narHash": "sha256-suKmSbSk34uPOJDTg/GbPrKEJutzK08vj0VoTvAFBCA=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "7c75487edd43a71b61adb01cae8326d277aab683",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprgraphics",
"type": "github"
}
},
"hyprland": {
"inputs": {
"aquamarine": "aquamarine",
"hyprcursor": "hyprcursor",
"hyprgraphics": "hyprgraphics",
"hyprland-guiutils": "hyprland-guiutils",
"hyprland-protocols": "hyprland-protocols",
"hyprlang": "hyprlang",
"hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner",
"hyprwire": "hyprwire",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems_2",
"xdph": "xdph"
},
"locked": {
"lastModified": 1771109637,
"narHash": "sha256-Tm3gxMhwoJGORXMnH4eZyJKQPQr6fWG5njd9I+k/sVI=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "e6ca1413648407c9a7b14f33673f67c31b296410",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "Hyprland",
"type": "github"
}
},
"hyprland-guiutils": {
"inputs": {
"aquamarine": [
"hyprland",
"aquamarine"
],
"hyprgraphics": [
"hyprland",
"hyprgraphics"
],
"hyprlang": [
"hyprland",
"hyprlang"
],
"hyprtoolkit": "hyprtoolkit",
"hyprutils": [
"hyprland",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1767023960,
"narHash": "sha256-R2HgtVS1G3KSIKAQ77aOZ+Q0HituOmPgXW9nBNkpp3Q=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "c2e906261142f5dd1ee0bfc44abba23e2754c660",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"type": "github"
}
},
"hyprland-protocols": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1765214753,
"narHash": "sha256-P9zdGXOzToJJgu5sVjv7oeOGPIIwrd9hAUAP3PsmBBs=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "3f3860b869014c00e8b9e0528c7b4ddc335c21ab",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-protocols",
"type": "github"
}
},
"hyprlang": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1767983607,
"narHash": "sha256-8C2co8NYfR4oMOUEsPROOJ9JHrv9/ktbJJ6X1WsTbXc=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "d4037379e6057246b408bbcf796cf3e9838af5b2",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprlang",
"type": "github"
}
},
"hyprtoolkit": {
"inputs": {
"aquamarine": [
"hyprland",
"hyprland-guiutils",
"aquamarine"
],
"hyprgraphics": [
"hyprland",
"hyprland-guiutils",
"hyprgraphics"
],
"hyprlang": [
"hyprland",
"hyprland-guiutils",
"hyprlang"
],
"hyprutils": [
"hyprland",
"hyprland-guiutils",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprland-guiutils",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"hyprland-guiutils",
"nixpkgs"
],
"systems": [
"hyprland",
"hyprland-guiutils",
"systems"
]
},
"locked": {
"lastModified": 1764592794,
"narHash": "sha256-7CcO+wbTJ1L1NBQHierHzheQGPWwkIQug/w+fhTAVuU=",
"owner": "hyprwm",
"repo": "hyprtoolkit",
"rev": "5cfe0743f0e608e1462972303778d8a0859ee63e",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprtoolkit",
"type": "github"
}
},
"hyprutils": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1770139857,
"narHash": "sha256-bCqxcXjavgz5KBJ/1CBLqnagMMf9JvU1m9HmYVASKoc=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "9038eec033843c289b06b83557a381a2648d8fa5",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprutils",
"type": "github"
}
},
"hyprwayland-scanner": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1770501770,
"narHash": "sha256-NWRM6+YxTRv+bT9yvlhhJ2iLae1B1pNH3mAL5wi2rlQ=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "0bd8b6cde9ec27d48aad9e5b4deefb3746909d40",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"type": "github"
}
},
"hyprwire": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1770203293,
"narHash": "sha256-PR/KER+yiHabFC/h1Wjb+9fR2Uy0lWM3Qld7jPVaWkk=",
"owner": "hyprwm",
"repo": "hyprwire",
"rev": "37bc90eed02b0c8b5a77a0b00867baf3005cfb98",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprwire",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1770882871,
"narHash": "sha256-nw5g+xl3veea+maxJ2/81tMEA/rPq9aF1H5XF35X+OE=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "af04cb78aa85b2a4d1c15fc7270347e0d0eda97b",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770841267,
"narHash": "sha256-9xejG0KoqsoKEGp2kVbXRlEYtFFcDTHjidiuX8hGO44=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ec7c70d12ce2fc37cb92aff673dcdca89d187bae",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1751274312,
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1771008912,
"narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a82ccc39b39b621151d6732718e3e250109076fa",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1770726378,
"narHash": "sha256-kck+vIbGOaM/dHea7aTBxdFYpeUl/jHOy5W3eyRvVx8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "5eaaedde414f6eb1aea8b8525c466dc37bba95ae",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"home-manager": "home-manager_2",
"hyprland": "hyprland",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"xdph": {
"inputs": {
"hyprland-protocols": [
"hyprland",
"hyprland-protocols"
],
"hyprlang": [
"hyprland",
"hyprlang"
],
"hyprutils": [
"hyprland",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1761431178,
"narHash": "sha256-xzjC1CV3+wpUQKNF+GnadnkeGUCJX+vgaWIZsnz9tzI=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "4b8801228ff958d028f588f0c2b911dbf32297f9",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

162
flake.nix Normal file
View File

@@ -0,0 +1,162 @@
{
description = "Nomarchy - An opinionated NixOS configuration with Hyprland";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11";
hyprland.url = "github:hyprwm/Hyprland";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
# Secrets management
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
};
# Hardware quirks database
nixos-hardware.url = "github:NixOS/nixos-hardware";
};
outputs = {
self,
nixpkgs,
nixpkgs-stable,
hyprland,
home-manager,
agenix,
nixos-hardware,
...
} @ inputs: let
lib = nixpkgs.lib;
supportedSystems = ["x86_64-linux" "aarch64-linux"];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
# Import helper functions
mkHost = import ./lib/mkHost.nix {inherit inputs lib;};
# Default configuration options
defaultConfig = {
username = "user";
hostname = "nomarchy";
timezone = "UTC";
locale = "en_US.UTF-8";
keyboardLayouts = ["us"];
keyboardVariants = [""];
# Features (opinionated defaults, user can disable)
enableSyncthing = true;
enableMullvad = false;
enablePrinting = true;
enableBluetooth = true;
# Performance (security-conscious defaults)
enableMitigationsOff = false; # Opt-in only
# Theme
theme = "classical";
};
in {
# NixOS configurations
nixosConfigurations = {
# Example configuration (requires hardware-configuration.nix)
# Users create their own configuration via the installer
example = mkHost {
system = "x86_64-linux";
config = defaultConfig // {
hostname = "nomarchy";
};
extraModules = [
# Minimal test hardware config
({...}: {
boot.loader.systemd-boot.enable = true;
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
})
];
};
# ISO installer configuration
installer = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {inherit inputs;};
modules = [
./iso/default.nix
];
};
};
# Flake apps
apps = forAllSystems (system: {
# Main installer app: nix run github:blu/nomarchy
default = {
type = "app";
program = "${self.packages.${system}.nomarchy-install}/bin/nomarchy-install";
};
# Interactive installer
install = {
type = "app";
program = "${self.packages.${system}.nomarchy-install}/bin/nomarchy-install";
};
});
# Packages
packages = forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
# Installer script
nomarchy-install = pkgs.writeShellScriptBin "nomarchy-install" (builtins.readFile ./installer/install.sh);
# ISO image
iso = self.nixosConfigurations.installer.config.system.build.isoImage;
default = self.packages.${system}.nomarchy-install;
});
# NixOS modules for users who want to import individual pieces
nixosModules = {
default = import ./modules;
hyprland = import ./modules/desktop/hyprland.nix;
theme = import ./themes/theme.nix;
performance = import ./modules/performance;
};
# Home-manager modules
homeManagerModules = {
default = import ./modules/home;
};
# Templates for users to bootstrap their own config
templates = {
default = {
path = ./templates/default;
description = "Basic nomarchy configuration";
};
};
# Export lib functions for users
lib = {
inherit mkHost;
};
# Development shell
devShells = forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
default = pkgs.mkShell {
buildInputs = with pkgs; [
nil # Nix LSP
alejandra # Nix formatter
nixpkgs-fmt
];
};
});
};
}

334
installer/install.sh Executable file
View File

@@ -0,0 +1,334 @@
#!/usr/bin/env bash
# Nomarchy Installer
# Interactive TUI installer for existing NixOS systems
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Detect if we're running from flake or locally
NOMARCHY_FLAKE="${NOMARCHY_FLAKE:-github:blu/nomarchy}"
print_banner() {
echo -e "${CYAN}"
cat << 'EOF'
_ __ __
/ | / /___ ____ ___ ____ _____/ /___ __
/ |/ / __ \/ __ `__ \/ __ `/ __/ / __/ / /
/ /| / /_/ / / / / / / /_/ / / / / /__ / /
/_/ |_/\____/_/ /_/ /_/\__,_/_/ /_/\___//_/
EOF
echo -e "${NC}"
echo -e "${BOLD}An opinionated NixOS configuration with Hyprland${NC}"
echo ""
}
check_requirements() {
echo -e "${BLUE}Checking requirements...${NC}"
if [ ! -f /etc/NIXOS ]; then
echo -e "${RED}Error: This installer requires NixOS.${NC}"
echo "For other Linux distributions, please use the ISO installer."
exit 1
fi
if [ "$(id -u)" = "0" ]; then
echo -e "${RED}Error: Do not run this installer as root.${NC}"
echo "The installer will use sudo when needed."
exit 1
fi
echo -e "${GREEN}Requirements met!${NC}"
echo ""
}
prompt_username() {
local current_user
current_user=$(whoami)
echo -e "${BOLD}Username${NC}"
echo -e "Current user: ${CYAN}${current_user}${NC}"
read -rp "Enter username (press Enter for '${current_user}'): " username
username="${username:-$current_user}"
echo ""
}
prompt_hostname() {
local current_hostname
current_hostname=$(hostname)
echo -e "${BOLD}Hostname${NC}"
echo -e "Current hostname: ${CYAN}${current_hostname}${NC}"
read -rp "Enter hostname (press Enter for '${current_hostname}'): " hostname_input
hostname_input="${hostname_input:-$current_hostname}"
echo ""
}
prompt_timezone() {
local current_tz
current_tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "UTC")
echo -e "${BOLD}Timezone${NC}"
echo -e "Current timezone: ${CYAN}${current_tz}${NC}"
echo "Common timezones: America/New_York, America/Los_Angeles, Europe/London, Asia/Tokyo"
read -rp "Enter timezone (press Enter for '${current_tz}'): " timezone
timezone="${timezone:-$current_tz}"
echo ""
}
prompt_locale() {
echo -e "${BOLD}Locale${NC}"
echo "Default: en_US.UTF-8"
read -rp "Enter locale (press Enter for 'en_US.UTF-8'): " locale
locale="${locale:-en_US.UTF-8}"
echo ""
}
prompt_keyboard() {
echo -e "${BOLD}Keyboard Layout${NC}"
echo "Default: us"
echo "Examples: us, uk, de, fr, es, us,gr (multiple separated by comma)"
read -rp "Enter keyboard layout(s): " keyboard
keyboard="${keyboard:-us}"
echo "Keyboard variants (leave empty for default):"
echo "Example: ,polytonic (for Greek polytonic as second layout)"
read -rp "Enter keyboard variant(s): " keyboard_variant
keyboard_variant="${keyboard_variant:-}"
echo ""
}
prompt_location() {
echo -e "${BOLD}Location (for Gammastep night light)${NC}"
echo "Enter coordinates for automatic night light adjustment."
echo "Leave empty to disable or set manually later."
read -rp "Latitude (e.g., 40.7): " lat
read -rp "Longitude (e.g., -74.0): " lon
lat="${lat:-0}"
lon="${lon:-0}"
echo ""
}
prompt_features() {
echo -e "${BOLD}Optional Features${NC}"
read -rp "Enable Syncthing file sync? [Y/n]: " syncthing
syncthing="${syncthing:-y}"
[[ "$syncthing" =~ ^[Yy] ]] && enable_syncthing="true" || enable_syncthing="false"
read -rp "Enable Mullvad VPN? [y/N]: " mullvad
mullvad="${mullvad:-n}"
[[ "$mullvad" =~ ^[Yy] ]] && enable_mullvad="true" || enable_mullvad="false"
read -rp "Enable printing support? [Y/n]: " printing
printing="${printing:-y}"
[[ "$printing" =~ ^[Yy] ]] && enable_printing="true" || enable_printing="false"
echo ""
echo -e "${YELLOW}WARNING: The following option disables CPU security mitigations.${NC}"
echo "This improves performance but reduces security. Only enable if you understand the risks."
read -rp "Enable mitigations=off (insecure)? [y/N]: " mitigations
mitigations="${mitigations:-n}"
[[ "$mitigations" =~ ^[Yy] ]] && enable_mitigations_off="true" || enable_mitigations_off="false"
echo ""
}
generate_config() {
local config_dir="$HOME/.config/nomarchy"
mkdir -p "$config_dir/wallpapers"
echo -e "${BLUE}Generating configuration...${NC}"
# Parse keyboard layouts into Nix list format
local kb_layouts_nix
kb_layouts_nix=$(echo "$keyboard" | sed 's/,/" "/g' | sed 's/^/"/' | sed 's/$/"/')
local kb_variants_nix
if [ -n "$keyboard_variant" ]; then
kb_variants_nix=$(echo "$keyboard_variant" | sed 's/,/" "/g' | sed 's/^/"/' | sed 's/$/"/')
else
kb_variants_nix='""'
fi
cat > "$config_dir/config.nix" << EOF
# Nomarchy User Configuration
# Generated by nomarchy-install on $(date)
{
username = "${username}";
hostname = "${hostname_input}";
timezone = "${timezone}";
locale = "${locale}";
keyboardLayouts = [${kb_layouts_nix}];
keyboardVariants = [${kb_variants_nix}];
# Location for Gammastep (night light)
location = {
lat = ${lat};
lon = ${lon};
};
# Features
enableSyncthing = ${enable_syncthing};
enableMullvad = ${enable_mullvad};
enablePrinting = ${enable_printing};
enableBluetooth = true;
# Performance (security tradeoff)
enableMitigationsOff = ${enable_mitigations_off};
# Theme
theme = "classical";
}
EOF
echo -e "${GREEN}Configuration saved to ${config_dir}/config.nix${NC}"
echo ""
}
setup_flake() {
local config_dir="$HOME/.config/nomarchy"
echo -e "${BLUE}Setting up flake...${NC}"
cat > "$config_dir/flake.nix" << EOF
{
description = "My Nomarchy Configuration";
inputs = {
nomarchy.url = "${NOMARCHY_FLAKE}";
nixpkgs.follows = "nomarchy/nixpkgs";
};
outputs = { self, nomarchy, nixpkgs, ... }@inputs: let
userConfig = import ./config.nix;
in {
nixosConfigurations.\${userConfig.hostname} = nomarchy.lib.mkHost {
system = "x86_64-linux";
config = userConfig;
extraModules = [
# Add your hardware-configuration.nix here
/etc/nixos/hardware-configuration.nix
# Add any custom modules here
# ./my-custom-module.nix
];
};
};
}
EOF
echo -e "${GREEN}Flake created at ${config_dir}/flake.nix${NC}"
echo ""
}
download_wallpapers() {
local wallpaper_dir="$HOME/.config/nomarchy/wallpapers"
echo -e "${BLUE}Setting up wallpapers...${NC}"
# Create a default wallpaper (simple gradient)
# In production, this would download from the nomarchy repo
if command -v convert &> /dev/null; then
convert -size 1920x1080 gradient:'#1a1611-#2d2620' "$wallpaper_dir/default.jpg" 2>/dev/null || true
fi
echo -e "${YELLOW}Note: Copy your wallpapers to ${wallpaper_dir}${NC}"
echo ""
}
show_summary() {
echo -e "${BOLD}Configuration Summary${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "Username: ${CYAN}${username}${NC}"
echo -e "Hostname: ${CYAN}${hostname_input}${NC}"
echo -e "Timezone: ${CYAN}${timezone}${NC}"
echo -e "Locale: ${CYAN}${locale}${NC}"
echo -e "Keyboard: ${CYAN}${keyboard}${NC}"
echo -e "Syncthing: ${CYAN}${enable_syncthing}${NC}"
echo -e "Mullvad: ${CYAN}${enable_mullvad}${NC}"
echo -e "Printing: ${CYAN}${enable_printing}${NC}"
echo -e "Mitigations: ${CYAN}${enable_mitigations_off}${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
}
apply_config() {
local config_dir="$HOME/.config/nomarchy"
echo -e "${YELLOW}Ready to apply configuration.${NC}"
read -rp "Apply now? This will rebuild NixOS. [y/N]: " apply
if [[ "$apply" =~ ^[Yy] ]]; then
echo -e "${BLUE}Applying configuration...${NC}"
echo ""
cd "$config_dir"
# Update flake inputs
nix flake update
# Rebuild
sudo nixos-rebuild switch --flake ".#${hostname_input}"
echo ""
echo -e "${GREEN}Configuration applied successfully!${NC}"
echo -e "Please ${BOLD}log out and log back in${NC} to start Hyprland."
else
echo ""
echo -e "${YELLOW}Configuration saved but not applied.${NC}"
echo "To apply later, run:"
echo -e " ${CYAN}cd ~/.config/nomarchy && sudo nixos-rebuild switch --flake .#${hostname_input}${NC}"
fi
}
main() {
print_banner
check_requirements
echo -e "${BOLD}Let's configure your Nomarchy installation.${NC}"
echo ""
prompt_username
prompt_hostname
prompt_timezone
prompt_locale
prompt_keyboard
prompt_location
prompt_features
show_summary
read -rp "Proceed with this configuration? [Y/n]: " proceed
proceed="${proceed:-y}"
if [[ ! "$proceed" =~ ^[Yy] ]]; then
echo "Installation cancelled."
exit 0
fi
generate_config
setup_flake
download_wallpapers
apply_config
echo ""
echo -e "${GREEN}${BOLD}Nomarchy installation complete!${NC}"
echo ""
echo "Next steps:"
echo " 1. Log out and select 'Hyprland' from the session menu"
echo " 2. Press Super+/ for Quick Actions menu"
echo " 3. Press Super+R for app launcher"
echo " 4. See ~/.config/nomarchy/README.md for more info"
echo ""
}
main "$@"

116
iso/default.nix Normal file
View File

@@ -0,0 +1,116 @@
# ISO Installer Configuration
{
config,
lib,
pkgs,
modulesPath,
inputs,
...
}: {
imports = [
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
"${modulesPath}/installer/cd-dvd/channel.nix"
];
# ISO naming
isoImage.isoName = "nomarchy-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.iso";
isoImage.volumeID = "NOMARCHY";
# Boot settings - use LTS kernel for ISO stability
boot.kernelPackages = pkgs.linuxPackages;
# Disable ZFS (broken with latest kernels)
boot.supportedFilesystems = lib.mkForce ["btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" "ext4"];
# Limine bootloader for ISO (commented out until properly configured)
# boot.loader.limine.enable = true;
# Enable SSH for headless installs
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
};
# Networking
networking = {
hostName = "nomarchy-installer";
networkmanager.enable = true;
wireless.enable = lib.mkForce false;
};
# Installer environment packages
environment.systemPackages = with pkgs; [
# Disk partitioning
parted
gptfdisk
dosfstools
cryptsetup
# Filesystem tools
e2fsprogs
btrfs-progs
ntfs3g
# Network
networkmanager
wpa_supplicant
# TUI
dialog
newt # provides whiptail
# Utilities
vim
git
curl
wget
jq
# NixOS installation
nixos-install-tools
];
# Auto-login to installer
services.getty.autologinUser = "nixos";
# Welcome message
environment.etc."motd".text = ''
Welcome to the Nomarchy Installer
Run 'nomarchy-install' to begin installation
For more information: https://github.com/blu/nomarchy
'';
# Copy installer script
system.activationScripts.installer = ''
mkdir -p /usr/local/bin
cat > /usr/local/bin/nomarchy-install << 'INSTALLER'
#!/usr/bin/env bash
# Nomarchy ISO Installer - coming soon
echo "ISO installer not yet implemented."
echo "Please use the NixOS manual installation process,"
echo "then run: nix run github:blu/nomarchy"
INSTALLER
chmod +x /usr/local/bin/nomarchy-install
'';
# User account
users.users.nixos = {
isNormalUser = true;
extraGroups = ["wheel" "networkmanager"];
initialPassword = "nomarchy";
};
# Allow passwordless sudo
security.sudo.wheelNeedsPassword = false;
# System state version
system.stateVersion = "24.11";
}

4
lib/default.nix Normal file
View File

@@ -0,0 +1,4 @@
# Nomarchy library functions
{inputs, lib}: {
mkHost = import ./mkHost.nix {inherit inputs lib;};
}

92
lib/mkHost.nix Normal file
View File

@@ -0,0 +1,92 @@
# Helper function to create a NixOS host configuration
{inputs, lib}: {
system,
config,
extraModules ? [],
}: let
pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
};
pkgs-stable = import inputs.nixpkgs-stable {
inherit system;
config.allowUnfree = true;
};
in
inputs.nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit inputs pkgs-stable;
nomarchyConfig = config;
};
modules =
[
# Core system modules
../modules/core
../modules/desktop
../modules/services
../modules/programs
../modules/performance
# Secrets management
inputs.agenix.nixosModules.default
# Home-manager integration
inputs.home-manager.nixosModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = {
inherit inputs pkgs-stable;
nomarchyConfig = config;
};
users.${config.username} = import ../modules/home;
};
}
# Theme
../themes/theme.nix
# Dynamic configuration based on user settings
({...}: {
# Networking
networking.hostName = config.hostname;
# Locale and timezone
time.timeZone = config.timezone;
i18n.defaultLocale = config.locale;
i18n.extraLocaleSettings = let
locale = config.locale;
in {
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 = locale;
};
# User account
users.users.${config.username} = {
isNormalUser = true;
description = config.username;
extraGroups = ["networkmanager" "wheel" "adbusers" "video" "audio"];
shell = pkgs.zsh;
};
# Enable flakes
nix.settings.experimental-features = ["nix-command" "flakes"];
# State version
system.stateVersion = "24.11";
})
]
++ extraModules;
}

25
modules/core/boot.nix Normal file
View File

@@ -0,0 +1,25 @@
# Boot configuration
# Supports both systemd-boot (default) and Limine
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: let
# For ISO builds, we'll use Limine; for regular installs, systemd-boot
useSystemdBoot = nomarchyConfig.bootloader or "systemd-boot" == "systemd-boot";
in {
# Systemd-boot (default for NixOS installs)
boot.loader.systemd-boot = lib.mkIf useSystemdBoot {
enable = true;
configurationLimit = 10;
};
boot.loader.efi.canTouchEfiVariables = useSystemdBoot;
# Limine support (for ISO)
boot.loader.limine = lib.mkIf (!useSystemdBoot) {
enable = true;
};
}

8
modules/core/default.nix Normal file
View File

@@ -0,0 +1,8 @@
# Core system modules
{...}: {
imports = [
./boot.nix
./networking.nix
./hardware.nix
];
}

37
modules/core/hardware.nix Normal file
View File

@@ -0,0 +1,37 @@
# Hardware configuration
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: {
# Bluetooth
hardware.bluetooth = lib.mkIf (nomarchyConfig.enableBluetooth or true) {
enable = true;
powerOnBoot = true;
};
services.blueman.enable = nomarchyConfig.enableBluetooth or true;
# Graphics - hardware acceleration
hardware.graphics = {
enable = true;
enable32Bit = true;
};
# Audio - PipeWire (modern audio stack)
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# Bluetooth audio support
environment.systemPackages = lib.mkIf (nomarchyConfig.enableBluetooth or true) (with pkgs; [
blueman
bluez
bluez-tools
]);
}

View File

@@ -0,0 +1,34 @@
# Networking configuration
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: {
# NetworkManager with iwd backend (better WiFi handling)
networking.wireless.enable = false;
networking.networkmanager = {
enable = true;
wifi.backend = "iwd";
};
# Firewall - enabled by default, ports configurable
networking.firewall = {
enable = true;
# Syncthing ports (if enabled)
allowedTCPPorts = lib.optionals (nomarchyConfig.enableSyncthing or true) [
8384 # Syncthing GUI
22000 # Syncthing transfer
];
allowedUDPPorts = lib.optionals (nomarchyConfig.enableSyncthing or true) [
22000 # Syncthing transfer
21027 # Syncthing discovery
];
};
# DNS resolution
services.resolved.enable = true;
}

10
modules/default.nix Normal file
View File

@@ -0,0 +1,10 @@
# Main modules index
{...}: {
imports = [
./core
./desktop
./services
./programs
./performance
];
}

View File

@@ -0,0 +1,7 @@
# Desktop environment modules
{...}: {
imports = [
./hyprland.nix
./display-manager.nix
];
}

View File

@@ -0,0 +1,25 @@
# Display manager configuration
{
config,
lib,
pkgs,
...
}: {
# X11 server (for SDDM and fallback)
services.xserver.enable = true;
# SDDM display manager with Wayland support
services.displayManager.sddm = {
enable = true;
wayland.enable = true;
};
# Plasma 6 as fallback desktop (optional)
services.desktopManager.plasma6.enable = true;
# KDE Connect for phone integration
programs.kdeconnect.enable = true;
# X keyboard layout (for SDDM)
services.xserver.xkb.layout = "us";
}

View File

@@ -0,0 +1,78 @@
# Hyprland window manager configuration
{
config,
lib,
pkgs,
inputs,
nomarchyConfig,
...
}: {
# Enable Hyprland as a session option
services.displayManager.sessionPackages = [
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland
];
# Enable polkit for privilege escalation
security.polkit.enable = true;
# XDG portal for screen sharing and file dialogs
xdg.portal = {
enable = true;
extraPortals = [pkgs.xdg-desktop-portal-hyprland];
};
# Hyprland ecosystem packages
environment.systemPackages = with pkgs; [
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland
# Core utilities
waybar
swaynotificationcenter
rofi-wayland
hyprpaper
hyprlock
hypridle
hyprpicker
# Screenshot tools
grim
slurp
swappy
satty
# Screen recording
wf-recorder
ffmpeg
# Clipboard
wl-clipboard
cliphist
# Brightness and audio control
brightnessctl
playerctl
# System utilities
pavucontrol
wdisplays
networkmanagerapplet
# Night light
gammastep
# QR code generation (for WiFi sharing)
qrencode
imv
# Debugging
wev
];
# Wayland environment variables
environment.sessionVariables = {
NIXOS_OZONE_WL = "1";
XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "Hyprland";
};
}

62
modules/home/default.nix Normal file
View File

@@ -0,0 +1,62 @@
# Home-manager configuration
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: let
username = nomarchyConfig.username;
homeDir = "/home/${username}";
# Keyboard layout formatting
kbLayouts = builtins.concatStringsSep "," nomarchyConfig.keyboardLayouts;
kbVariants = builtins.concatStringsSep "," nomarchyConfig.keyboardVariants;
in {
imports = [
./hyprland.nix
./waybar.nix
./rofi.nix
./scripts.nix
./shell.nix
./notifications.nix
./neovim.nix
];
home = {
inherit username;
homeDirectory = homeDir;
stateVersion = "24.11";
packages = with pkgs; [
# Fonts
font-awesome
nerd-fonts.jetbrains-mono
nerd-fonts.iosevka
nerd-fonts.victor-mono
nerd-fonts.fantasque-sans-mono
nerd-fonts.fira-code
nerd-fonts.monaspace
];
sessionVariables = {
PATH = "$HOME/.cargo/bin:$HOME/.local/bin:$PATH";
EDITOR = "nvim";
VISUAL = "nvim";
};
};
fonts.fontconfig.enable = true;
# Pass keyboard config to hyprland module
_module.args.keyboardConfig = {
layouts = kbLayouts;
variants = kbVariants;
};
# Enable programs
programs.nix-init.enable = true;
programs.cmus.enable = true;
programs.satty.enable = true;
programs.yazi.enable = true;
}

258
modules/home/hyprland.nix Normal file
View File

@@ -0,0 +1,258 @@
# Hyprland user configuration
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: let
username = nomarchyConfig.username;
homeDir = "/home/${username}";
# Keyboard layouts
kbLayouts = builtins.concatStringsSep "," nomarchyConfig.keyboardLayouts;
kbVariants = builtins.concatStringsSep "," nomarchyConfig.keyboardVariants;
# Detect location for gammastep (default to UTC/0,0 if not set)
location = nomarchyConfig.location or {lat = 0; lon = 0;};
in {
wayland.windowManager.hyprland = {
enable = true;
systemd.enable = true;
settings = {
"$mod" = "SUPER";
"$terminal" = "ghostty";
"$fileManager" = "dolphin";
"$menu" = "rofi -show drun";
"$browser" = "firefox";
monitor = ",preferred,auto,auto";
exec-once = [
"$terminal"
"waybar & hyprpaper & firefox"
"nm-applet --indicator"
"blueman-applet"
"wl-paste --type text --watch cliphist store"
"wl-paste --type image --watch cliphist store"
"swaync"
"gammastep -l ${toString location.lat}:${toString location.lon} -t 6500:3500"
];
env = [
"XCURSOR_SIZE,24"
"HYPRCURSOR_SIZE,24"
];
general = {
gaps_in = 5;
gaps_out = 20;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
resize_on_border = false;
allow_tearing = false;
layout = "dwindle";
};
decoration = {
rounding = 10;
active_opacity = 1.0;
inactive_opacity = 1.0;
shadow = {
enabled = true;
range = 4;
render_power = 3;
color = "rgba(1a1a1aee)";
};
blur = {
enabled = true;
size = 3;
passes = 1;
vibrancy = 0.1696;
};
};
animations = {
enabled = true;
bezier = [
"easeOutQuint,0.23,1,0.32,1"
"easeInOutCubic,0.65,0.05,0.36,1"
"linear,0,0,1,1"
"almostLinear,0.5,0.5,0.75,1.0"
"quick,0.15,0,0.1,1"
];
animation = [
"global, 1, 10, default"
"border, 1, 5.39, easeOutQuint"
"windows, 1, 4.79, easeOutQuint"
"windowsIn, 1, 4.1, easeOutQuint, popin 87%"
"windowsOut, 1, 1.49, linear, popin 87%"
"fadeIn, 1, 1.73, almostLinear"
"fadeOut, 1, 1.46, almostLinear"
"fade, 1, 3.03, quick"
"layers, 1, 3.81, easeOutQuint"
"layersIn, 1, 4, easeOutQuint, fade"
"layersOut, 1, 1.5, linear, fade"
"fadeLayersIn, 1, 1.79, almostLinear"
"fadeLayersOut, 1, 1.39, almostLinear"
"workspaces, 1, 1.94, almostLinear, fade"
"workspacesIn, 1, 1.21, almostLinear, fade"
"workspacesOut, 1, 1.94, almostLinear, fade"
];
};
dwindle = {
pseudotile = true;
preserve_split = true;
};
master = {
new_status = "master";
};
misc = {
force_default_wallpaper = 1;
disable_hyprland_logo = true;
disable_splash_rendering = true;
};
input = {
kb_layout = kbLayouts;
kb_variant = kbVariants;
kb_options = "grp:ralt_toggle";
repeat_delay = 150;
repeat_rate = 50;
follow_mouse = 1;
sensitivity = 0;
touchpad = {
natural_scroll = false;
};
};
device = {
name = "epic-mouse-v1";
sensitivity = "-0.5";
};
bindm = [
"$mod, mouse:272, movewindow"
"$mod, mouse:273, resizewindow"
];
bindel = [
",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"
",XF86MonBrightnessUp, exec, brightnessctl s 10%+"
",XF86MonBrightnessDown, exec, brightnessctl s 10%-"
];
bindl = [
", XF86AudioNext, exec, playerctl next"
", XF86AudioPause, exec, playerctl play-pause"
", XF86AudioPlay, exec, playerctl play-pause"
", XF86AudioPrev, exec, playerctl previous"
];
bind = [
"$mod, Q, exec, $terminal"
"$mod, W, killactive,"
"$mod, M, exit,"
"$mod, E, exec, $fileManager"
"$mod, V, togglefloating,"
"$mod, R, exec, $menu"
"$mod, P, pseudo,"
"$mod, J, togglesplit,"
"$mod, B, exec, $browser"
"$mod, F, fullscreen, 0"
"$mod SHIFT, F, fullscreen, 1"
# Focus movement
"$mod, left, movefocus, l"
"$mod, right, movefocus, r"
"$mod, up, movefocus, u"
"$mod, down, movefocus, d"
# Workspaces
"$mod, 1, workspace, 1"
"$mod, 2, workspace, 2"
"$mod, 3, workspace, 3"
"$mod, 4, workspace, 4"
"$mod, 5, workspace, 5"
"$mod, 6, workspace, 6"
"$mod, 7, workspace, 7"
"$mod, 8, workspace, 8"
"$mod, 9, workspace, 9"
"$mod, 0, workspace, 10"
# Move to workspace
"$mod SHIFT, 1, movetoworkspace, 1"
"$mod SHIFT, 2, movetoworkspace, 2"
"$mod SHIFT, 3, movetoworkspace, 3"
"$mod SHIFT, 4, movetoworkspace, 4"
"$mod SHIFT, 5, movetoworkspace, 5"
"$mod SHIFT, 6, movetoworkspace, 6"
"$mod SHIFT, 7, movetoworkspace, 7"
"$mod SHIFT, 8, movetoworkspace, 8"
"$mod SHIFT, 9, movetoworkspace, 9"
"$mod SHIFT, 0, movetoworkspace, 10"
# Special workspace (scratchpad)
"$mod, S, togglespecialworkspace, magic"
"$mod SHIFT, S, movetoworkspace, special:magic"
# Scroll through workspaces
"$mod, mouse_down, workspace, e+1"
"$mod, mouse_up, workspace, e-1"
# Screenshots
", Print, exec, grim - | wl-copy -t image/png"
"$mod, Print, exec, ~/.local/bin/screenshot-region"
"$mod SHIFT, Print, exec, grim -g \"$(slurp)\" - | wl-copy -t image/png"
"$mod ALT, Print, exec, ~/.local/bin/screenshot-window"
# Screen recording toggle
"$mod SHIFT, R, exec, ~/.local/bin/screen-record"
# Quick Actions menu
"$mod, Space, exec, ~/.local/bin/quick-actions"
"$mod, slash, exec, ~/.local/bin/quick-actions"
# Power menu
"$mod, Escape, exec, ~/.local/bin/power-menu"
# Notification center
"$mod, A, exec, swaync-client -t -sw"
];
};
};
# Hyprpaper for wallpapers
services.hyprpaper = {
enable = true;
settings = {
splash = false;
# Default wallpaper - users can override
preload = [
"${homeDir}/.config/nomarchy/wallpapers/default.jpg"
];
wallpaper = ["eDP-1,${homeDir}/.config/nomarchy/wallpapers/default.jpg"];
};
};
# Ghostty terminal
programs.ghostty = {
enable = true;
settings = {
font-size = 14;
background-opacity = 0.85;
keybind = "shift+enter=text:\n";
};
};
}

156
modules/home/neovim.nix Normal file
View File

@@ -0,0 +1,156 @@
# Neovim configuration (basic setup - can be extended)
{
config,
lib,
pkgs,
...
}: {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
extraPackages = with pkgs; [
# LSP servers
nil # Nix
lua-language-server
nodePackages.typescript-language-server
nodePackages.vscode-langservers-extracted # HTML, CSS, JSON
rust-analyzer
zls # Zig
gopls
pyright
marksman # Markdown
taplo # TOML
yaml-language-server
ltex-ls # Grammar
# Formatters
nixfmt
stylua
prettierd
black
rustfmt
# Tools
ripgrep
fd
tree-sitter
wl-clipboard
];
plugins = with pkgs.vimPlugins; [
# Core
plenary-nvim
nvim-web-devicons
# Fuzzy finder
telescope-nvim
# Treesitter
nvim-treesitter.withAllGrammars
# LSP
nvim-lspconfig
# Completion
nvim-cmp
cmp-nvim-lsp
cmp-buffer
cmp-path
luasnip
cmp_luasnip
# UI
lualine-nvim
bufferline-nvim
indent-blankline-nvim
# Git
gitsigns-nvim
# File tree
nvim-tree-lua
# Theme (can be customized to match nomarchy theme)
tokyonight-nvim
];
extraLuaConfig = /* backwards compat */ ''
-- Basic settings
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.expandtab = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.smartindent = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
vim.opt.updatetime = 250
vim.opt.clipboard = "unnamedplus"
-- Leader key
vim.g.mapleader = " "
-- Theme
vim.cmd.colorscheme("tokyonight-night")
-- Telescope keymaps
local telescope = require("telescope.builtin")
vim.keymap.set("n", "<leader>ff", telescope.find_files, { desc = "Find files" })
vim.keymap.set("n", "<leader>fg", telescope.live_grep, { desc = "Live grep" })
vim.keymap.set("n", "<leader>fb", telescope.buffers, { desc = "Buffers" })
-- LSP setup
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
local servers = {
"nil_ls", "lua_ls", "ts_ls", "html", "cssls", "jsonls",
"rust_analyzer", "zls", "gopls", "pyright", "marksman",
"taplo", "yamlls"
}
for _, server in ipairs(servers) do
lspconfig[server].setup({ capabilities = capabilities })
end
-- Completion
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
}, {
{ name = "buffer" },
{ name = "path" },
}),
})
-- File tree
require("nvim-tree").setup()
vim.keymap.set("n", "<leader>e", ":NvimTreeToggle<CR>", { silent = true })
-- Git signs
require("gitsigns").setup()
-- Status line
require("lualine").setup()
-- Buffer line
require("bufferline").setup()
'';
};
}

View File

@@ -0,0 +1,228 @@
# SwayNotificationCenter configuration
{
config,
lib,
pkgs,
...
}: {
services.swaync = {
enable = true;
settings = {
positionX = "right";
positionY = "top";
layer = "overlay";
control-center-layer = "top";
layer-shell = true;
cssPriority = "application";
control-center-margin-top = 10;
control-center-margin-bottom = 10;
control-center-margin-right = 10;
control-center-margin-left = 10;
notification-icon-size = 64;
notification-body-image-height = 100;
notification-body-image-width = 200;
timeout = 10;
timeout-low = 5;
timeout-critical = 0;
fit-to-screen = true;
control-center-width = 400;
control-center-height = 600;
notification-window-width = 400;
keyboard-shortcuts = true;
image-visibility = "when-available";
transition-time = 200;
hide-on-clear = false;
hide-on-action = true;
script-fail-notify = true;
widgets = [
"inhibitors"
"title"
"dnd"
"notifications"
"mpris"
];
widget-config = {
inhibitors = {
text = "Inhibitors";
button-text = "Clear All";
clear-all-button = true;
};
title = {
text = "Notifications";
clear-all-button = true;
button-text = "Clear All";
};
dnd = {
text = "Do Not Disturb";
};
mpris = {
image-size = 96;
image-radius = 12;
};
};
};
style = ''
* {
font-family: "JetBrainsMono Nerd Font Mono";
font-size: 13px;
}
.notification-row {
outline: none;
}
.notification-row:focus,
.notification-row:hover {
background: rgba(139, 90, 43, 0.15);
}
.notification {
border-radius: 12px;
margin: 6px;
box-shadow: 0 0 0 1px rgba(139, 90, 43, 0.4);
padding: 0;
background: rgba(26, 22, 17, 0.95);
}
.notification-content {
background: transparent;
padding: 10px;
border-radius: 12px;
}
.close-button {
background: rgba(166, 61, 64, 0.6);
color: #d4c4a8;
text-shadow: none;
padding: 0;
border-radius: 100%;
margin-top: 10px;
margin-right: 10px;
box-shadow: none;
border: none;
min-width: 24px;
min-height: 24px;
}
.close-button:hover {
box-shadow: none;
background: rgba(166, 61, 64, 0.9);
}
.notification-default-action,
.notification-action {
padding: 4px;
margin: 0;
box-shadow: none;
background: transparent;
border: none;
color: #d4c4a8;
}
.notification-default-action:hover,
.notification-action:hover {
background: rgba(139, 90, 43, 0.2);
}
.summary {
font-size: 14px;
font-weight: bold;
color: #d4a857;
}
.body {
font-size: 13px;
color: #d4c4a8;
}
.control-center {
background: rgba(26, 22, 17, 0.95);
border: 2px solid rgba(139, 90, 43, 0.6);
border-radius: 12px;
}
.control-center-list {
background: transparent;
}
.control-center-list-placeholder {
opacity: 0.5;
}
.floating-notifications {
background: transparent;
}
.blank-window {
background: alpha(black, 0.1);
}
.widget-title {
margin: 8px;
font-size: 1.2em;
color: #d4a857;
}
.widget-title > button {
font-size: 0.9em;
color: #d4c4a8;
background: rgba(139, 90, 43, 0.3);
border: none;
border-radius: 8px;
padding: 4px 12px;
}
.widget-title > button:hover {
background: rgba(139, 90, 43, 0.5);
}
.widget-dnd {
margin: 8px;
padding: 4px;
background: transparent;
}
.widget-dnd > switch {
background: rgba(92, 83, 70, 0.6);
border-radius: 12px;
}
.widget-dnd > switch:checked {
background: rgba(212, 168, 87, 0.6);
}
.widget-dnd > switch slider {
background: #d4c4a8;
border-radius: 12px;
}
.widget-mpris {
background: rgba(45, 38, 32, 0.85);
border-radius: 12px;
margin: 8px;
padding: 8px;
}
.widget-mpris-player {
padding: 8px;
}
.widget-mpris-title {
font-weight: bold;
font-size: 1.1em;
color: #d4a857;
}
.widget-mpris-subtitle {
font-size: 0.9em;
color: #8b7355;
}
.widget-inhibitors {
margin: 8px;
padding: 4px;
background: transparent;
}
'';
};
}

82
modules/home/rofi.nix Normal file
View File

@@ -0,0 +1,82 @@
# Rofi application launcher configuration
{
config,
lib,
pkgs,
...
}: {
home.file.".config/rofi/config.rasi".text = ''
configuration {
modi: "drun,run";
show-icons: true;
icon-theme: "Papirus";
font: "JetBrainsMono Nerd Font 13";
}
* {
bg: rgba(26, 22, 17, 0.9);
bg-alt: rgba(45, 38, 32, 0.95);
fg: #d4c4a8;
fg-alt: #8b7355;
accent: #d4a857;
urgent: #a63d40;
background-color: transparent;
text-color: @fg;
}
window {
width: 500px;
background-color: @bg;
border: 2px solid;
border-color: rgba(212, 168, 87, 0.5);
border-radius: 12px;
padding: 20px;
}
inputbar {
background-color: @bg-alt;
border-radius: 8px;
padding: 12px;
margin: 0 0 15px 0;
children: [prompt, entry];
}
prompt {
text-color: @accent;
padding: 0 10px 0 0;
}
entry {
text-color: @fg;
placeholder: "Search...";
placeholder-color: @fg-alt;
cursor-color: @accent;
}
listview {
lines: 12;
spacing: 5px;
scrollbar: false;
}
element {
padding: 10px 15px;
border-radius: 8px;
}
element selected {
background-color: rgba(212, 168, 87, 0.2);
text-color: @accent;
}
element-icon {
size: 24px;
padding: 0 10px 0 0;
}
element-text {
text-color: inherit;
}
'';
}

331
modules/home/scripts.nix Normal file
View File

@@ -0,0 +1,331 @@
# Custom utility scripts
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: let
homeDir = "/home/${nomarchyConfig.username}";
in {
# Screenshot region script
home.file.".local/bin/screenshot-region" = {
executable = true;
text = ''
#!/usr/bin/env bash
grim -g "$(slurp)" - | satty -f -
'';
};
# Screenshot active window script
home.file.".local/bin/screenshot-window" = {
executable = true;
text = ''
#!/usr/bin/env bash
GEOM=$(hyprctl activewindow -j | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')
grim -g "$GEOM" - | satty -f -
'';
};
# Screen recording toggle script
home.file.".local/bin/screen-record" = {
executable = true;
text = ''
#!/usr/bin/env bash
PIDFILE="/tmp/wf-recorder.pid"
STATUSFILE="/tmp/recording-status"
OUTDIR="$HOME/Videos/Recordings"
mkdir -p "$OUTDIR"
if [ -f "$PIDFILE" ]; then
kill -INT "$(cat $PIDFILE)" 2>/dev/null
rm -f "$PIDFILE" "$STATUSFILE"
notify-send -u normal "Recording Saved" "$(ls -t $OUTDIR/*.mp4 2>/dev/null | head -1)"
else
FILENAME="$OUTDIR/recording_$(date +%Y%m%d_%H%M%S).mp4"
CHOICE=$(echo -e "󰍹 Region\n󰹑 Fullscreen" | rofi -dmenu -p "Record")
case "$CHOICE" in
*"Region"*)
GEOM=$(slurp)
[ -z "$GEOM" ] && exit 1
wf-recorder -g "$GEOM" -f "$FILENAME" &
;;
*"Fullscreen"*)
wf-recorder -f "$FILENAME" &
;;
*)
exit 1
;;
esac
echo $! > "$PIDFILE"
echo "recording" > "$STATUSFILE"
notify-send -u critical "Recording" "Click waybar or Super+/ to stop"
fi
'';
};
# Quick Actions menu
home.file.".local/bin/quick-actions" = {
executable = true;
text = ''
#!/usr/bin/env bash
ACTION=$(cat << 'EOF' | rofi -dmenu -i -p ""
󰍹 Screenshot Region
󰹑 Screenshot Window
󰕧 Record Screen
󰆏 Clipboard History
󰖩 Share WiFi (QR Code)
󱂵 Change Wallpaper
󰈈 Color Picker
󰂜 Notifications
System Settings
󰌌 Keybindings
󰗼 Lock
󰍃 Logout
󰜉 Reboot
󰐥 Shutdown
EOF
)
case "$ACTION" in
*"Screenshot Region"*) ~/.local/bin/screenshot-region ;;
*"Screenshot Window"*) ~/.local/bin/screenshot-window ;;
*"Record Screen"*) ~/.local/bin/screen-record ;;
*"Clipboard History"*) cliphist list | rofi -dmenu -p '󰆏' | cliphist decode | wl-copy ;;
*"Share WiFi"*) ~/.local/bin/wifi-share ;;
*"Change Wallpaper"*) ~/.local/bin/wallpaper-rotate && notify-send "Wallpaper changed" ;;
*"Color Picker"*) hyprpicker -a && notify-send "Color copied to clipboard" ;;
*"Notifications"*) swaync-client -t -sw ;;
*"System Settings"*) ~/.local/bin/system-settings ;;
*"Keybindings"*) ~/.local/bin/keybindings-help ;;
*"Lock"*) hyprlock ;;
*"Logout"*) hyprctl dispatch exit ;;
*"Reboot"*) systemctl reboot ;;
*"Shutdown"*) systemctl poweroff ;;
esac
'';
};
# Keybindings help
home.file.".local/bin/keybindings-help" = {
executable = true;
text = ''
#!/usr/bin/env bash
cat << 'EOF' | rofi -dmenu -i -p "Keybindings (Super+)" -theme-str 'window {width: 400px;} listview {lines: 16;}'
Q Terminal
R App Launcher
E File Manager
B Browser
W Close Window
F Fullscreen
V Float/Tile
Arrows Move Focus
1-9 Workspace
/ Quick Actions
A Notifications
Space Switch Layout
EOF
'';
};
# Power menu
home.file.".local/bin/power-menu" = {
executable = true;
text = ''
#!/usr/bin/env bash
ACTION=$(echo -e "󰗼 Lock\n󰍃 Logout\n󰜉 Reboot\n󰐥 Shutdown" | rofi -dmenu -i -p "")
case "$ACTION" in
*"Lock"*) hyprlock ;;
*"Logout"*) hyprctl dispatch exit ;;
*"Reboot"*) systemctl reboot ;;
*"Shutdown"*) systemctl poweroff ;;
esac
'';
};
# WiFi sharing with QR code
home.file.".local/bin/wifi-share" = {
executable = true;
text = ''
#!/usr/bin/env bash
SSID=$(nmcli -t -f active,ssid dev wifi | grep '^yes' | cut -d: -f2)
if [ -z "$SSID" ]; then
notify-send "WiFi Share" "Not connected to WiFi"
exit 1
fi
PASSWORD=$(nmcli -s -g 802-11-wireless-security.psk connection show "$SSID" 2>/dev/null)
if [ -z "$PASSWORD" ]; then
notify-send "WiFi Share" "Could not retrieve password"
exit 1
fi
WIFI_STRING="WIFI:T:WPA;S:$SSID;P:$PASSWORD;;"
QR_FILE="/tmp/wifi-qr.png"
qrencode -o "$QR_FILE" -s 10 "$WIFI_STRING"
ACTION=$(echo -e "󰐲 View QR Code\n󰆏 Copy Password\n󰖩 Copy SSID" | rofi -dmenu -i -p "󰖩 $SSID")
case "$ACTION" in
*"View QR"*)
if command -v imv &> /dev/null; then
imv "$QR_FILE" &
else
xdg-open "$QR_FILE" &
fi
notify-send "WiFi QR Code" "Scan to connect to $SSID"
;;
*"Copy Password"*)
echo -n "$PASSWORD" | wl-copy
notify-send "Password Copied" "$SSID password copied to clipboard"
;;
*"Copy SSID"*)
echo -n "$SSID" | wl-copy
notify-send "SSID Copied" "$SSID copied to clipboard"
;;
esac
'';
};
# System settings menu
home.file.".local/bin/system-settings" = {
executable = true;
text = ''
#!/usr/bin/env bash
ACTION=$(cat << 'EOF' | rofi -dmenu -i -p ""
󰖩 WiFi Settings
󰂯 Bluetooth
󰕾 Sound Settings
󰃟 Display Settings
NixOS Generations
󰚰 Update System
󰃨 Garbage Collect
EOF
)
case "$ACTION" in
*"WiFi"*) nm-connection-editor ;;
*"Bluetooth"*) blueman-manager 2>/dev/null || notify-send "Bluetooth" "blueman not installed" ;;
*"Sound"*) pavucontrol 2>/dev/null || notify-send "Sound" "pavucontrol not installed" ;;
*"Display"*) wdisplays 2>/dev/null || notify-send "Display" "wdisplays not installed" ;;
*"Generations"*) ghostty -e bash -c "sudo nix-env --profile /nix/var/nix/profiles/system --list-generations | tail -20; echo; read -p 'Press Enter to close...'" ;;
*"Update"*) ghostty -e bash -c "cd ~/.config/nomarchy && nix flake update && sudo nixos-rebuild switch --flake .#; echo; read -p 'Press Enter to close...'" ;;
*"Garbage"*) ghostty -e bash -c "sudo nix-collect-garbage -d; echo; read -p 'Press Enter to close...'" ;;
esac
'';
};
# WiFi menu
home.file.".local/bin/wifi-menu" = {
executable = true;
text = ''
#!/usr/bin/env bash
CURRENT=$(nmcli -t -f active,ssid dev wifi | grep '^yes' | cut -d: -f2)
MENU="󰖩 Scan for networks\n"
if [ -n "$CURRENT" ]; then
MENU+="󰐲 Share WiFi (QR Code)\n"
MENU+="󰖪 Disconnect ($CURRENT)\n"
fi
MENU+="󰤨 Toggle WiFi\n"
MENU+="\n"
NETWORKS=$(nmcli -t -f ssid,signal,security dev wifi list | grep -v '^$' | head -10)
while IFS=: read -r ssid signal security; do
if [ -n "$ssid" ]; then
if [ "$ssid" = "$CURRENT" ]; then
MENU+="󰤨 $ssid ($signal%) \n"
elif [ -n "$security" ]; then
MENU+="󰤡 $ssid ($signal%)\n"
else
MENU+="󰤨 $ssid ($signal%)\n"
fi
fi
done <<< "$NETWORKS"
CHOICE=$(echo -e "$MENU" | rofi -dmenu -i -p "󰖩" | sed 's/^[^ ]* *//' | sed 's/ ([0-9]*%).*$//' | sed 's/ $//')
case "$CHOICE" in
"Scan for networks")
notify-send "WiFi" "Scanning..."
nmcli dev wifi rescan
sleep 2
~/.local/bin/wifi-menu
;;
"Share WiFi"*)
~/.local/bin/wifi-share
;;
"Disconnect"*)
nmcli dev disconnect wlan0
notify-send "WiFi" "Disconnected"
;;
"Toggle WiFi")
if nmcli radio wifi | grep -q "enabled"; then
nmcli radio wifi off
notify-send "WiFi" "Disabled"
else
nmcli radio wifi on
notify-send "WiFi" "Enabled"
fi
;;
""*) ;;
"") ;;
*)
if nmcli -t -f name connection show | grep -q "^$CHOICE$"; then
nmcli connection up "$CHOICE" && notify-send "WiFi" "Connected to $CHOICE"
else
PASS=$(rofi -dmenu -p "Password for $CHOICE" -password)
if [ -n "$PASS" ]; then
nmcli dev wifi connect "$CHOICE" password "$PASS" && notify-send "WiFi" "Connected to $CHOICE"
fi
fi
;;
esac
'';
};
# Bluetooth toggle
home.file.".local/bin/bluetooth-toggle" = {
executable = true;
text = ''
#!/usr/bin/env bash
if bluetoothctl show | grep -q "Powered: yes"; then
bluetoothctl power off
notify-send "Bluetooth" "Disabled"
else
bluetoothctl power on
notify-send "Bluetooth" "Enabled"
fi
'';
};
# Wallpaper rotation script
home.file.".local/bin/wallpaper-rotate" = {
executable = true;
text = ''
#!/usr/bin/env bash
WALLPAPER_DIR="${homeDir}/.config/nomarchy/wallpapers"
MONITOR="eDP-1"
if [ -z "$HYPRLAND_INSTANCE_SIGNATURE" ]; then
XDG_RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
HYPRLAND_INSTANCE_SIGNATURE="$(ls "$XDG_RUNTIME_DIR/hypr/" 2>/dev/null | head -1)"
fi
export HYPRLAND_INSTANCE_SIGNATURE
if [ -z "$HYPRLAND_INSTANCE_SIGNATURE" ]; then
echo "No Hyprland instance found"
exit 1
fi
WALLPAPER=$(find "$WALLPAPER_DIR" -type f \( -name "*.jpg" -o -name "*.png" \) | shuf -n 1)
if [ -n "$WALLPAPER" ]; then
hyprctl hyprpaper wallpaper "$MONITOR,$WALLPAPER"
fi
'';
};
}

48
modules/home/shell.nix Normal file
View File

@@ -0,0 +1,48 @@
# Shell configuration (Zsh + Starship)
{
config,
lib,
pkgs,
...
}: {
programs.zsh = {
enable = true;
shellAliases = {
ls = "eza --icons";
ll = "eza -l --icons";
la = "eza -la --icons";
update = "sudo nixos-rebuild switch --flake ~/.config/nomarchy#";
gc = "sudo nix-collect-garbage -d";
du = "dust";
dua = "dust -d 1";
duh = "dust ~";
dus = "dust /nix/store -d 2";
};
};
# Zoxide for smart directory jumping
programs.zoxide = {
enable = true;
enableZshIntegration = true;
};
# Starship prompt
programs.starship = {
enable = true;
enableZshIntegration = true;
settings = {
character = {
success_symbol = "[>](bold green)";
error_symbol = "[x](bold red)";
};
git_branch = {
symbol = " ";
style = "purple";
};
directory = {
style = "blue";
truncate_to_repo = true;
};
};
};
}

267
modules/home/waybar.nix Normal file
View File

@@ -0,0 +1,267 @@
# Waybar status bar configuration
{
config,
lib,
pkgs,
...
}: {
programs.waybar = {
enable = true;
style = ''
* {
font-family: "JetBrainsMono Nerd Font Mono", "JetBrainsMono NF", monospace;
font-size: 14px;
min-height: 0;
}
window#waybar {
background-color: rgba(26, 22, 17, 0.92);
color: #d4c4a8;
border-bottom: 2px solid rgba(139, 90, 43, 0.6);
}
#workspaces button {
padding: 0 8px;
color: #8b7355;
border-radius: 4px;
margin: 4px 2px;
}
#workspaces button.active {
color: #d4a857;
background-color: rgba(180, 134, 11, 0.2);
}
#workspaces button:hover {
background-color: rgba(139, 90, 43, 0.15);
}
#custom-help {
padding: 0 10px;
margin: 4px 2px;
border-radius: 4px;
background-color: rgba(212, 168, 87, 0.3);
color: #d4a857;
font-weight: bold;
}
#custom-help:hover {
background-color: rgba(212, 168, 87, 0.5);
}
#clock, #battery, #network, #pulseaudio, #cpu, #memory, #tray {
padding: 0 12px;
margin: 4px 2px;
border-radius: 4px;
background-color: rgba(45, 38, 32, 0.85);
}
#clock {
color: #d4a857;
font-weight: bold;
}
#battery {
color: #8a9a5b;
}
#battery.charging {
color: #d4a857;
}
#battery.warning:not(.charging) {
color: #c9a227;
}
#battery.critical:not(.charging) {
color: #a63d40;
animation: blink 0.5s linear infinite alternate;
}
#network {
color: #7a9cb8;
}
#network.disconnected {
color: #a63d40;
}
#bluetooth {
color: #7a9cb8;
}
#bluetooth.connected {
color: #8a9a5b;
}
#bluetooth.disabled {
color: #5c5346;
}
#language {
color: #c67b5c;
font-weight: bold;
min-width: 20px;
}
#pulseaudio {
color: #c9a227;
}
#pulseaudio.muted {
color: #5c5346;
}
#cpu {
color: #b85c38;
}
#memory {
color: #c67b5c;
}
#tray {
padding: 0 8px;
}
@keyframes blink {
to {
background-color: #722f37;
color: #d4c4a8;
}
}
#custom-recording {
color: #ff4444;
font-weight: bold;
animation: blink 1s linear infinite;
padding: 0 10px;
}
'';
settings = {
mainBar = {
layer = "top";
position = "top";
height = 34;
spacing = 4;
modules-left = ["custom/help" "hyprland/workspaces" "hyprland/window"];
modules-center = ["custom/recording" "clock"];
modules-right = ["hyprland/language" "tray" "cpu" "memory" "pulseaudio" "bluetooth" "network" "battery"];
"custom/recording" = {
exec = "[ -f /tmp/recording-status ] && echo '󰑊 REC' || echo ''";
interval = 1;
format = "{}";
on-click = "~/.local/bin/screen-record";
tooltip = "Click to stop recording";
};
"custom/help" = {
format = "?";
tooltip = "Quick Actions (Super+/)";
on-click = "~/.local/bin/quick-actions";
};
"hyprland/workspaces" = {
format = "{name}";
on-click = "activate";
};
"hyprland/window" = {
max-length = 50;
separate-outputs = true;
};
clock = {
format = "{:%H:%M %a %b %d}";
format-alt = "{:%I:%M %p %a %b %d}";
tooltip-format = "<tt><small>{calendar}</small></tt>";
calendar = {
mode = "month";
weeks-pos = "right";
format = {
months = "<span color='#d4a857'><b>{}</b></span>";
days = "<span color='#d4c4a8'>{}</span>";
weeks = "<span color='#8b7355'>W{}</span>";
weekdays = "<span color='#c9a227'>{}</span>";
today = "<span color='#a63d40'><b><u>{}</u></b></span>";
};
};
};
cpu = {
format = "CPU {usage}%";
tooltip = true;
interval = 2;
};
memory = {
format = "RAM {percentage}%";
tooltip-format = "{used:0.1f}GB / {total:0.1f}GB";
interval = 2;
};
battery = {
states = {
warning = 30;
critical = 15;
};
format = "BAT {capacity}%";
format-charging = "CHR {capacity}%";
format-plugged = "PLG {capacity}%";
format-icons = ["" "" "" "" ""];
tooltip-format = "{timeTo}";
};
network = {
format-wifi = "󰖩 {essid}";
format-ethernet = "󰈀 {ipaddr}";
format-disconnected = "󰖪 ";
tooltip-format-wifi = "{essid} {signalStrength}% {ipaddr}";
tooltip-format-ethernet = "IP: {ipaddr}";
on-click = "~/.local/bin/wifi-menu";
on-click-right = "nm-connection-editor";
};
bluetooth = {
format = "󰂯";
format-connected = "󰂱 {device_alias}";
format-disabled = "󰂲";
tooltip-format = "{controller_alias}\n{status}";
tooltip-format-connected = "{controller_alias}\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}";
on-click = "blueman-manager";
on-click-right = "~/.local/bin/bluetooth-toggle";
};
"hyprland/language" = {
format = "{}";
format-en = "EN";
format-gr = "ΕΛ";
tooltip-format = "{long} ({variant})";
on-click = "hyprctl switchxkblayout all next";
};
pulseaudio = {
format = "{icon} {volume}%";
format-muted = "󰖁 ";
format-icons = {
default = ["󰕿" "󰖀" "󰕾"];
headphone = "󰋋";
};
tooltip-format = "{desc}";
on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
on-click-right = "pavucontrol";
on-scroll-up = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
on-scroll-down = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
};
tray = {
icon-size = 18;
spacing = 8;
};
};
};
};
}

View File

@@ -0,0 +1,70 @@
# Performance optimizations
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: {
# Zram swap for better memory management
zramSwap = {
enable = true;
algorithm = "zstd";
memoryPercent = 50;
};
# Tmpfs for /tmp (faster, auto-cleans)
boot.tmp = {
useTmpfs = true;
tmpfsSize = "50%";
};
# Kernel parameters for performance
boot.kernelParams =
[
"quiet"
"splash"
]
# SECURITY WARNING: mitigations=off disables CPU vulnerability protections
# Only enable if you understand the security implications
++ lib.optionals (nomarchyConfig.enableMitigationsOff or false) [
"mitigations=off"
];
# Better I/O scheduler for SSDs
services.udev.extraRules = ''
ACTION=="add|change", KERNEL=="sd[a-z]*|nvme[0-9]*", ATTR{queue/scheduler}="mq-deadline"
'';
# Kernel sysctl tuning
boot.kernel.sysctl = {
# Increase inotify watches for large projects (IDEs, file watchers)
"fs.inotify.max_user_watches" = 524288;
"fs.inotify.max_user_instances" = 1024;
# Memory management
"vm.swappiness" = 10; # Prefer RAM over swap
"vm.vfs_cache_pressure" = 50; # Balance inode/dentry cache
};
# Nix garbage collection
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
# Nix store optimization
nix.settings = {
auto-optimise-store = true;
max-jobs = "auto";
cores = 0; # Use all cores
};
# Earlyoom to prevent OOM freezes
services.earlyoom = {
enable = true;
freeMemThreshold = 5;
freeSwapThreshold = 10;
};
}

View File

@@ -0,0 +1,136 @@
# System programs
{
config,
lib,
pkgs,
pkgs-stable,
nomarchyConfig,
...
}: {
# Shell
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestions.enable = true;
syntaxHighlighting.enable = true;
};
# nix-ld for dynamically linked libraries
programs.nix-ld = {
enable = true;
libraries = with pkgs; [
zlib
stdenv.cc.cc
openssl
];
};
environment.systemPackages = with pkgs; [
# Core utilities
wget
git
unzip
jq
lsof
file
ripgrep
fd
# Development
zig
bun
nodejs_22
lazygit
# Networking
wireguard-tools
nmap
arp-scan
rclone
rsync
# Privacy
tor-browser
gnupg
pinentry-curses
# Media
mpv
yt-dlp
imagemagick
viu
chafa
# Documents
libreoffice-qt
nb
mdbook
exiftool
# File management
ranger
dolphin
# Shell enhancements
eza
bat
fzf
starship
btop
zsh
zoxide
# Browsers
firefox
chromium
# Applications
anki
# NixOS tools
nh
nvd
nix-tree
# Disk usage
dust
ncdu
gdu
duf
# Android
android-tools
# Filesystem
exfatprogs
# Graphviz
graphviz
# Qt multimedia
qt6.qtmultimedia
# Signal Desktop (from stable for reliability)
pkgs-stable.signal-desktop
# Kate editor (KDE)
kdePackages.kate
# FHS environment for non-NixOS binaries
(let
base = pkgs.appimageTools.defaultFhsEnvArgs;
in
pkgs.buildFHSEnv (base
// {
name = "fhs";
targetPkgs = pkgs:
(base.targetPkgs pkgs)
++ (with pkgs; [
pkg-config
]);
profile = "export FHS=1";
runScript = "bash";
extraOutputsToInstall = ["dev"];
}))
];
}

View File

@@ -0,0 +1,57 @@
# System services
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: {
# Printing service
services.printing = lib.mkIf (nomarchyConfig.enablePrinting or true) {
enable = true;
browsed.enable = true;
drivers = with pkgs; [brlaser gutenprint];
};
# Avahi for mDNS discovery (network printers)
services.avahi = lib.mkIf (nomarchyConfig.enablePrinting or true) {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
# Mullvad VPN
services.mullvad-vpn.enable = nomarchyConfig.enableMullvad or false;
# Syncthing - parameterized user
services.syncthing = lib.mkIf (nomarchyConfig.enableSyncthing or true) {
enable = true;
user = nomarchyConfig.username;
dataDir = "/home/${nomarchyConfig.username}/.config/syncthing";
configDir = "/home/${nomarchyConfig.username}/.config/syncthing";
openDefaultPorts = true;
guiAddress = "127.0.0.1:8384";
};
# Auto-cpufreq for automatic CPU power management
services.auto-cpufreq = {
enable = true;
settings = {
battery = {
governor = "powersave";
turbo = "never";
scaling_min_freq = 800000;
scaling_max_freq = 2000000;
};
charger = {
governor = "performance";
turbo = "auto";
scaling_min_freq = 800000;
scaling_max_freq = 4500000;
};
};
};
# Disable power-profiles-daemon (conflicts with auto-cpufreq)
services.power-profiles-daemon.enable = false;
}

View File

@@ -0,0 +1,47 @@
{
description = "My Nomarchy Configuration";
inputs = {
nomarchy.url = "github:blu/nomarchy";
nixpkgs.follows = "nomarchy/nixpkgs";
};
outputs = { self, nomarchy, nixpkgs, ... }: let
# Edit this configuration
userConfig = {
username = "myuser";
hostname = "myhostname";
timezone = "America/New_York";
locale = "en_US.UTF-8";
keyboardLayouts = ["us"];
keyboardVariants = [""];
# Location for night light (gammastep)
location = { lat = 40.7; lon = -74.0; };
# Features
enableSyncthing = true;
enableMullvad = false;
enablePrinting = true;
enableBluetooth = true;
# Performance (security tradeoff - leave false unless you understand the risks)
enableMitigationsOff = false;
# Theme
theme = "classical";
};
in {
nixosConfigurations.${userConfig.hostname} = nomarchy.lib.mkHost {
system = "x86_64-linux";
config = userConfig;
extraModules = [
# Import your hardware configuration
./hardware-configuration.nix
# Add custom modules here
# ./my-custom-module.nix
];
};
};
}

View File

@@ -0,0 +1,94 @@
# Classical / Antiquity Theme
# Inspired by Thomas Cole's "Course of Empire" series
{
name = "classical";
description = "Earthy, vintage aesthetic with gold and bronze accents";
colors = {
# Backgrounds (dark to light)
bg = {
primary = "#1a1611"; # Very dark brown (main background)
secondary = "#2d2620"; # Dark brown (panels, inputs)
tertiary = "#3d3428"; # Medium brown (hover states)
transparent = "rgba(26, 22, 17, 0.92)";
panelTransparent = "rgba(45, 38, 32, 0.85)";
};
# Foregrounds (text)
fg = {
primary = "#d4c4a8"; # Light tan (main text)
secondary = "#b8a88c"; # Muted tan (secondary text)
muted = "#8b7355"; # Brown (disabled/placeholder)
dark = "#5c5346"; # Dark muted (very subtle text)
};
# Accent colors
accent = {
gold = "#d4a857"; # Primary accent (buttons, highlights)
terracotta = "#c67b5c"; # Warm accent (memory, alt highlights)
olive = "#7a8450"; # Green accent (success, battery)
sky = "#6b98a6"; # Blue accent (info, network)
bronze = "#b85c38"; # Orange accent (CPU, warnings)
};
# Semantic colors
status = {
success = "#8a9a5b"; # Olive green
warning = "#c9a227"; # Amber gold
error = "#a63d40"; # Deep red
info = "#7a9cb8"; # Muted blue
};
# Border colors
border = {
primary = "rgba(139, 90, 43, 0.6)";
accent = "rgba(212, 168, 87, 0.5)";
subtle = "rgba(139, 90, 43, 0.4)";
};
# Hyprland-specific (gradients for borders)
hyprland = {
activeBorder = "rgba(33ccffee) rgba(00ff99ee) 45deg";
inactiveBorder = "rgba(595959aa)";
shadow = "rgba(1a1a1aee)";
};
};
# Font configuration
fonts = {
mono = "JetBrainsMono Nerd Font";
monoAlt = "VictorMono Nerd Font Mono";
sans = "Inter";
icon = "Font Awesome 6 Free";
size = {
small = 12;
normal = 14;
large = 16;
xlarge = 18;
};
};
# Spacing and sizing
spacing = {
small = 4;
normal = 8;
large = 12;
xlarge = 20;
};
# Border radius
radius = {
small = 4;
normal = 8;
large = 12;
};
# Opacity
opacity = {
panel = 0.92;
window = 0.85;
inactive = 1.0;
active = 1.0;
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

54
themes/theme.nix Normal file
View File

@@ -0,0 +1,54 @@
# Theme module - provides colors and styling to all nomarchy components
{
config,
lib,
pkgs,
nomarchyConfig,
...
}: let
# Load the selected theme
themeName = nomarchyConfig.theme or "classical";
# Available themes
themes = {
classical = import ./classical/colors.nix;
# Future themes can be added here:
# nord = import ./nord/colors.nix;
# catppuccin = import ./catppuccin/colors.nix;
};
# Get the active theme, falling back to classical
theme = themes.${themeName} or themes.classical;
in {
# Export theme as a module option for other modules to consume
options.nomarchy.theme = lib.mkOption {
type = lib.types.attrs;
default = theme;
description = "The active nomarchy theme configuration";
};
config = {
# Set the theme in config
nomarchy.theme = theme;
# Install theme fonts
fonts.packages = with pkgs; [
font-awesome
nerd-fonts.jetbrains-mono
nerd-fonts.iosevka
nerd-fonts.victor-mono
nerd-fonts.fantasque-sans-mono
nerd-fonts.fira-code
nerd-fonts.monaspace
inter
];
fonts.fontconfig = {
enable = true;
defaultFonts = {
monospace = [theme.fonts.mono];
sansSerif = [theme.fonts.sans];
};
};
};
}