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>
21
.gitignore
vendored
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,4 @@
|
||||
# Nomarchy library functions
|
||||
{inputs, lib}: {
|
||||
mkHost = import ./mkHost.nix {inherit inputs lib;};
|
||||
}
|
||||
92
lib/mkHost.nix
Normal 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
@@ -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
@@ -0,0 +1,8 @@
|
||||
# Core system modules
|
||||
{...}: {
|
||||
imports = [
|
||||
./boot.nix
|
||||
./networking.nix
|
||||
./hardware.nix
|
||||
];
|
||||
}
|
||||
37
modules/core/hardware.nix
Normal 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
|
||||
]);
|
||||
}
|
||||
34
modules/core/networking.nix
Normal 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
@@ -0,0 +1,10 @@
|
||||
# Main modules index
|
||||
{...}: {
|
||||
imports = [
|
||||
./core
|
||||
./desktop
|
||||
./services
|
||||
./programs
|
||||
./performance
|
||||
];
|
||||
}
|
||||
7
modules/desktop/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
# Desktop environment modules
|
||||
{...}: {
|
||||
imports = [
|
||||
./hyprland.nix
|
||||
./display-manager.nix
|
||||
];
|
||||
}
|
||||
25
modules/desktop/display-manager.nix
Normal 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";
|
||||
}
|
||||
78
modules/desktop/hyprland.nix
Normal 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
@@ -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
@@ -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
@@ -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()
|
||||
'';
|
||||
};
|
||||
}
|
||||
228
modules/home/notifications.nix
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
70
modules/performance/default.nix
Normal 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;
|
||||
};
|
||||
}
|
||||
136
modules/programs/default.nix
Normal 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"];
|
||||
}))
|
||||
];
|
||||
}
|
||||
57
modules/services/default.nix
Normal 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;
|
||||
}
|
||||
47
templates/default/flake.nix
Normal 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
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
94
themes/classical/colors.nix
Normal 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;
|
||||
};
|
||||
}
|
||||
|
After Width: | Height: | Size: 572 KiB |
|
After Width: | Height: | Size: 648 KiB |
|
After Width: | Height: | Size: 493 KiB |
|
After Width: | Height: | Size: 517 KiB |
|
After Width: | Height: | Size: 573 KiB |
|
After Width: | Height: | Size: 791 KiB |
|
After Width: | Height: | Size: 469 KiB |
BIN
themes/classical/wallpapers/David_-_The_Death_of_Socrates.jpg
Normal file
|
After Width: | Height: | Size: 677 KiB |
|
After Width: | Height: | Size: 326 KiB |
BIN
themes/classical/wallpapers/Paris_-_The_Venus_de_Milo_-_2381.jpg
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 249 KiB |
BIN
themes/classical/wallpapers/The_Return_A31154.jpg
Normal file
|
After Width: | Height: | Size: 639 KiB |
|
After Width: | Height: | Size: 8.2 MiB |
|
After Width: | Height: | Size: 235 KiB |
|
After Width: | Height: | Size: 881 KiB |
BIN
themes/classical/wallpapers/Thomas_Cole_-_The_Mountain_Ford.jpg
Normal file
|
After Width: | Height: | Size: 795 KiB |
BIN
themes/classical/wallpapers/parthenon.jpg
Normal file
|
After Width: | Height: | Size: 499 KiB |
BIN
themes/classical/wallpapers/washington-delaware.jpg
Normal file
|
After Width: | Height: | Size: 121 KiB |
54
themes/theme.nix
Normal 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];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||