feat: implement modular foundation and core system services

- Update flake.nix with 25.11 release and core inputs
- Add dedicated modules for audio (Pipewire), bluetooth, and networking
- Update GEMINI.md with the new Modular Merging Architecture blueprint
- Configure graphical installer ISO and test VM outputs
This commit is contained in:
Bernardo Magri
2026-04-03 21:06:42 +01:00
parent 33deeb494b
commit 29cc0d2547
49 changed files with 1628 additions and 855 deletions

View File

@@ -1,64 +1,40 @@
# Nomarchy - A NixOS-based distribution with Omarchy flavour - Agent Build Blueprint
## System Architecture Overview
You are tasked with generating a NixOS-based Linux distribution monorepo that perfectly replicates the Omarchy Wayland workflow. The architecture relies on a strictly declarative Nix Flake setup, separated into System-level configurations (NixOS) and User-level configurations (Standalone Home Manager).
Nomarchy uses a **Modular Merging Architecture**. The distro is distributed as a Nix Flake that exports two primary modules: `nixosModules.system` and `nixosModules.home`. This approach ensures strict separation between the "Upstream" core and the "Downstream" user configuration.
The goal is to provide an upstream repository that users can import into their own downstream `flake.nix` files, allowing them to keep the core Omarchy aesthetic while maintaining their own custom packages and development environments.
Users interact with the system by importing the distro's modules into their own `flake.nix` and then layering their own personal modules (`system.nix` and `home.nix`) on top. This follows the native NixOS design pattern for declarative, multi-module systems.
## Directory Structure
Generate the repository using the following exact structure:
* `flake.nix` (Master entry point)
* `installer/install-nomarchy.sh` (Bash/Gum interactive installer)
* `installer/disko-ext4.nix` (Standard drive layout)
* `installer/disko-btrfs-luks.nix` (Encrypted snapshot layout)
* `modules/system/default.nix` (Core OS module)
* `modules/system/plymouth.nix` (Boot splash)
* `modules/system/sddm.nix` (Display manager logic)
* `modules/home/default.nix` (Core Nomarchy user environment)
* `modules/home/hyprland.nix` (Window manager)
* `modules/home/waybar.nix` (Status bar)
* `modules/home/walker.nix` (App launcher and menus)
* `modules/home/theme-switcher.nix` (State file and scripts)
* `themes/nomarchy-palettes.nix` (Base16 Nix-colors dictionaries)
* `hosts/live-iso.nix` (Bootable USB configuration)
* `flake.nix` (Master entry point with core modules and test configurations)
* `installer/install-nomarchy.sh` (Interactive installer generating a clean downstream flake)
* `modules/system/default.nix` (Distro-wide OS defaults: SDDM, Plymouth, Audio, Network)
* `modules/home/default.nix` (Distro-wide user environment: Hyprland, Waybar, Styling)
* `bin/` (The collection of Omarchy productivity and config scripts)
* `themes/` (Distro-wide color palettes and backgrounds)
## Core Components & Logic
### 1. The Master Flake (`flake.nix`)
* **Inputs required:** `nixpkgs` (unstable), `nixos-hardware`, `disko`, `home-manager`, `nix-colors`.
* **Outputs required:** * `nixosModules.system`: Points to `modules/system`.
* `nixosModules.home`: Points to `modules/home`.
* `nixosConfigurations.installerIso`: Generates a bootable ISO importing standard minimal CD modules, adding `git`, `gum`, and `disko` to system packages, and copying `install-nomarchy.sh` to `/etc/`.
### 1. Separation of Concerns (Upstream vs. Downstream)
* **Upstream:** The `nomarchy/` directory contains the core logic. It is treated as an immutable input by the target system.
* **Downstream:** The user's `/etc/nixos/flake.nix` imports the upstream modules. The user's personal customizations are kept in `/etc/nixos/system.nix` and `/etc/nixos/home.nix`.
* **Merging:** NixOS automatically merges definitions. For example, if both the distro and the user add packages to `home.packages`, the final system includes the union of both lists.
### 2. The Interactive Installer (`installer/install-nomarchy.sh`)
Write a Bash script utilizing `gum` for UI prompts. The flow must execute as follows:
1. **Hardware Detection:** Read `/sys/class/dmi/id/product_name` and map it to a generic or specific `nixos-hardware` flake module.
2. **Storage Setup:** Prompt user for target drive. Prompt to choose between "Standard Ext4" or "Encrypted BTRFS (LUKS2)". Execute the corresponding Disko `.nix` file.
3. **User Details:** Prompt for target username.
4. **Login Preferences:** Prompt to choose between "SDDM Auto-login" (default) or "Require Password". Generate `/mnt/etc/nixos/login-preference.nix` based on the choice.
5. **Hardware Config:** Run `nixos-generate-config` into `/mnt/etc/nixos/`.
6. **Handoff Flake Generation:** Write a new `/mnt/etc/nixos/flake.nix` that imports the upstream Nomarchy distribution, the hardware config, the login preference, and sets up the user account.
7. **Version Control:** Initialize a git repository in `/mnt/etc/nixos/`, add files, and make an initial commit.
8. **Execution:** Run `nixos-install --flake /mnt/etc/nixos#default --no-root-passwd`.
The installer is designed to bootstrap a fresh system with this modular structure:
1. **Repo Detection:** Identifies the location of the Nomarchy source.
2. **Scaffolding:** Creates a new downstream `flake.nix` that imports Nomarchy core modules.
3. **User Files:** Generates skeleton `system.nix` and `home.nix` files for the user to customize.
4. **Bundling:** Copies the entire Nomarchy source to `/etc/nixos/nomarchy` so the system can be rebuilt offline.
### 3. Disko Configurations
* **Ext4:** Single EFI partition, single Ext4 root partition.
* **BTRFS+LUKS:** EFI partition, LUKS2 encrypted container holding a BTRFS filesystem. Subvolumes must include `@` (root), `@home` (user data), `@nix` (Nix store), and `@log` (logs).
### 3. Home Manager Integration
* **Hybrid Declarative State:** While the distro is declarative, it uses state files in `~/.config/home-manager/` (managed by the distro's scripts) to allow for instant UI feedback (theming, fonts, wallpapers) without needing a full system rebuild for every small tweak.
* **Script Wrapping:** All scripts in `bin/` are wrapped with their specific dependencies (`swayosd`, `pulseaudio`, `jq`, etc.) to ensure they work reliably across different hardware.
### 4. System Modules (`modules/system/`)
* **Boot:** Enable `systemd` initrd. Enable Plymouth with a custom Nomarchy theme derivation. Silence kernel logs completely (`quiet splash loglevel=3`).
* **Login:** Enable SDDM with Wayland support. Read the generated `login-preference.nix` to conditionally enable `autoLogin`. Enable Hyprland system-level dependencies.
### 4. Dynamic Theming
* **Palettes:** Themes are defined in simple `colors.toml` files. The distro dynamically generates Base16 palettes from these, allowing for infinite theme expansion without modifying Nix code.
### 5. Home Manager & Theming (`modules/home/`)
* **Architecture:** Must remain standalone (not built into the system NixOS config).
* **Aliases:** Define `sys-update` (`sudo nixos-rebuild switch`) and `env-update` (`home-manager switch`) in `home.shellAliases`.
* **Theme Engine:** Import `nix-colors`. Read a local untracked/state variable file (`~/.config/home-manager/theme-state.nix`) to determine the active theme from `nomarchy-palettes.nix`.
* **Styling:** Inject `nix-colors` variables (e.g., `${config.colorScheme.palette.base00}`) into Hyprland borders, Waybar CSS, Alacritty colors, and Walker CSS.
* **Walker & Scripting:** Configure Walker to run as a service. Write a `pkgs.writeShellScriptBin` script called `nomarchy-theme-selector` that uses Walker in `dmenu` mode to select a theme, overwrites `theme-state.nix`, stages it in git, and runs `env-update` to hot-reload the UI. Map this script to `Super + Alt + Space` in Hyprland.
## Execution Directives for Agent
1. Initialize the git repository.
2. Create the directory skeleton.
3. Generate the code for each file strictly adhering to declarative Nix principles, except for the installer script.
4. Ensure all Base16 variables used in Waybar and Walker CSS strings are properly escaped.
## Verification & Build
* **Test Installer:** `./bin/nomarchy-test-installer` (Builds a VM of the installer environment).
* **Check Integrity:** `nix flake check --impure` (Verifies all configurations evaluate).
* **Build ISO:** `nix build .#nixosConfigurations.installerIso.config.system.build.isoImage` (Generates the flashable USB image).

View File

@@ -1,46 +1,36 @@
#!/bin/bash
#!/usr/bin/env bash
# Set the system-wide monospace font that should be used by the terminal, hyprlock, waybar, swayosd, etc.
# The font name must be one of the ones returned by nomarchy-font-list.
# Declarative version for Nomarchy NixOS.
font_name="$1"
if [[ -n $font_name ]]; then
if fc-list | grep -iq "$font_name"; then
if [[ -f ~/.config/alacritty/alacritty.toml ]]; then
sed -i "s/family = \".*\"/family = \"$font_name\"/g" ~/.config/alacritty/alacritty.toml
fi
if [[ -z $font_name ]]; then
echo "Usage: nomarchy-font-set <font-name>"
exit 1
fi
if [[ -f ~/.config/kitty/kitty.conf ]]; then
sed -i "s/^font_family .*/font_family $font_name/g" ~/.config/kitty/kitty.conf
STATE_DIR="$HOME/.config/home-manager"
STATE_FILE="$STATE_DIR/font-state.nix"
mkdir -p "$STATE_DIR"
if fc-list | grep -iq "$font_name"; then
echo "$font_name" > "$STATE_FILE"
echo "Font set to $font_name declaratively. Applying changes..."
env-update
# Instant feedback for certain apps via IPC
if pgrep -x kitty; then
pkill -USR1 kitty
fi
if [[ -f ~/.config/ghostty/config ]]; then
sed -i "s/font-family = \".*\"/font-family = \"$font_name\"/g" ~/.config/ghostty/config
pkill -SIGUSR2 ghostty
fi
sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css
xmlstarlet ed -L \
-u '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' \
-v "$font_name" \
~/.config/fontconfig/fonts.conf
nomarchy-restart-waybar
nomarchy-restart-swayosd
if pgrep -x ghostty; then
pkill -SIGUSR2 ghostty
notify-send -u low " You must restart Ghostty to see font change"
fi
nomarchy-hook font-set "$font_name"
else
else
echo "Font '$font_name' not found."
exit 1
fi
else
echo "Usage: nomarchy-font-set <font-name>"
fi

View File

@@ -1,15 +1,27 @@
#!/bin/bash
#!/usr/bin/env bash
# Toggles the window gaps globally between no gaps and the default 10/5/2.
# Toggles the window gaps globally between no gaps and the default 10/5/2, declaratively and instantly.
gaps=$(hyprctl getoption general:gaps_out -j | jq -r '.custom' | awk '{print $1}')
STATE_FILE="$HOME/.config/home-manager/hyprland-state.json"
mkdir -p "$(dirname "$STATE_FILE")"
if [ ! -f "$STATE_FILE" ]; then
echo '{"gaps_out": 10, "gaps_in": 5, "border_size": 2}' > "$STATE_FILE"
fi
gaps=$(jq -r '.gaps_out' "$STATE_FILE")
if [[ $gaps == "0" ]]; then
NEW_STATE='{"gaps_out": 10, "gaps_in": 5, "border_size": 2}'
hyprctl keyword general:gaps_out 10
hyprctl keyword general:gaps_in 5
hyprctl keyword general:border_size 2
else
NEW_STATE='{"gaps_out": 0, "gaps_in": 0, "border_size": 0}'
hyprctl keyword general:gaps_out 0
hyprctl keyword general:gaps_in 0
hyprctl keyword general:border_size 0
fi
echo "$NEW_STATE" > "$STATE_FILE"
echo "Toggled gaps to $NEW_STATE declaratively."

View File

@@ -1,6 +1,7 @@
#!/bin/bash
#!/usr/bin/env bash
# Install one of the supported development environments. Usually called via Install > Development > * in the Nomarchy Menu.
# Install one of the supported development environments declaratively.
# Usually called via Install > Development > * in the Nomarchy Menu.
if [[ -z $1 ]]; then
echo "Usage: nomarchy-install-dev-env <ruby|node|bun|deno|go|laravel|symfony|php|python|elixir|phoenix|rust|java|zig|ocaml|dotnet|clojure|scala>" >&2
@@ -8,144 +9,78 @@ if [[ -z $1 ]]; then
fi
install_php() {
nomarchy-pkg-add php composer php-sqlite xdebug
# Install Path for Composer
if [[ :$PATH: != *:$HOME/.config/composer/vendor/bin:* ]]; then
echo 'export PATH="$HOME/.config/composer/vendor/bin:$PATH"' >>"$HOME/.bashrc"
source "$HOME/.bashrc"
echo "Added Composer global bin directory to PATH."
else
echo "Composer global bin directory already in PATH."
fi
# Enable some extensions
local php_ini_path="/etc/php/php.ini"
local extensions_to_enable=(
"bcmath"
"intl"
"iconv"
"openssl"
"pdo_sqlite"
"pdo_mysql"
)
# Enable Xdebug
sudo sed -i \
-e 's/^;zend_extension=xdebug.so/zend_extension=xdebug.so/' \
-e 's/^;xdebug.mode=debug/xdebug.mode=debug/' \
/etc/php/conf.d/xdebug.ini
for ext in "${extensions_to_enable[@]}"; do
sudo sed -i "s/^;extension=${ext}/extension=${ext}/" "$php_ini_path"
done
echo -e "Installing PHP environment declaratively...\n"
nomarchy-pkg-add php
nomarchy-pkg-add phpExtensions.bcmath
nomarchy-pkg-add phpExtensions.intl
nomarchy-pkg-add phpExtensions.iconv
nomarchy-pkg-add phpExtensions.openssl
nomarchy-pkg-add phpExtensions.pdo_sqlite
nomarchy-pkg-add phpExtensions.pdo_mysql
nomarchy-pkg-add phpPackages.composer
echo -e "\nPHP environment added to your packages."
}
install_node() {
echo -e "Installing Node.js...\n"
echo -e "Installing Node.js with mise...\n"
mise use --global node
}
case "$1" in
ruby)
echo -e "Installing Ruby on Rails...\n"
echo -e "Installing Ruby with mise...\n"
nomarchy-pkg-add libyaml
mise settings add ruby.compile false
mise settings add idiomatic_version_file_enable_tools ruby
mise use --global ruby@latest
echo "gem: --no-document" >~/.gemrc
mise x ruby -- gem install rails --no-document
echo -e "\nYou can now run: rails new myproject"
echo -e "\nYou can now use: ruby --version"
;;
node)
install_node
;;
bun)
echo -e "Installing Bun...\n"
echo -e "Installing Bun with mise...\n"
mise use -g bun@latest
;;
deno)
echo -e "Installing Deno...\n"
echo -e "Installing Deno with mise...\n"
mise use -g deno@latest
;;
go)
echo -e "Installing Go...\n"
echo -e "Installing Go with mise...\n"
mise use --global go@latest
;;
php)
echo -e "Installing PHP...\n"
install_php
;;
laravel)
echo -e "Installing PHP and Laravel...\n"
echo -e "Installing Laravel stack...\n"
install_php
install_node
# Composer global packages are imperative, but that's how they work.
composer global require laravel/installer
echo -e "\nYou can now run: laravel new myproject"
;;
symfony)
echo -e "Installing PHP and Symfony...\n"
install_php
nomarchy-pkg-add symfony-cli
echo -e "\nYou can now run: symfony new --webapp myproject"
;;
python)
echo -e "Installing Python...\n"
echo -e "Installing Python with mise...\n"
mise use --global python@latest
echo -e "\nInstalling uv...\n"
curl -fsSL https://astral.sh/uv/install.sh | sh
;;
elixir)
echo -e "Installing Elixir...\n"
mise use --global erlang@latest
mise use --global elixir@latest
mise x elixir -- mix local.hex --force
;;
phoenix)
echo -e "Installing Phoenix Framework...\n"
# Ensure Erlang/Elixir first
mise use --global erlang@latest
mise use --global elixir@latest
# Hex & Rebar
mise x elixir -- mix local.hex --force
mise x elixir -- mix local.rebar --force
# Phoenix project (phx_new)
mise x elixir -- mix archive.install hex phx_new --force
echo -e "\nYou can now run: mix phx.new my_app"
# uv can be installed via nix
nomarchy-pkg-add uv
;;
rust)
echo -e "Installing Rust...\n"
bash -c "$(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs)" -- -y
echo -e "Installing Rust declaratively...\n"
# Instead of shell script from website, use nixpkgs
nomarchy-pkg-add rustup
rustup-init -y
;;
java)
echo -e "Installing Java...\n"
mise use --global java@latest
;;
zig)
echo -e "Installing Zig...\n"
mise use --global zig@latest
mise use -g zls@latest
;;
ocaml)
echo -e "Installing OCaml...\n"
bash -c "$(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
opam init --yes
eval "$(opam env)"
opam install ocaml-lsp-server odoc ocamlformat utop --yes
;;
dotnet)
echo -e "Installing .NET...\n"
mise use --global dotnet@latest
;;
clojure)
echo -e "Installing Clojure...\n"
nomarchy-pkg-add rlwrap
mise use --global clojure@latest
;;
scala)
echo -e "Installing Scala...\n"
mise use --global java@latest
mise use --global scala@latest
mise use --global scala-cli@latest
# Add more language cases as needed, utilizing mise or nixpkgs.
*)
# Fallback to mise for languages that it supports
echo -e "Installing $1 with mise...\n"
if mise use --global "$1@latest"; then
echo "$1 installed successfully."
else
echo "Unsupported language: $1"
exit 1
fi
;;
esac

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Install one of the supported development environments declaratively for Nomarchy NixOS.
if [[ -z $1 ]]; then
echo "Usage: nomarchy-install-dev-env <ruby|node|bun|deno|go|laravel|symfony|php|python|elixir|phoenix|rust|java|zig|ocaml|dotnet|clojure|scala>" >&2
exit 1
fi
case "$1" in
php)
echo -e "Installing PHP and extensions declaratively...\n"
# This uses the already refactored declarative nomarchy-pkg-add
nomarchy-pkg-add php
nomarchy-pkg-add phpExtensions.bcmath
nomarchy-pkg-add phpExtensions.intl
nomarchy-pkg-add phpExtensions.iconv
nomarchy-pkg-add phpExtensions.openssl
nomarchy-pkg-add phpExtensions.pdo_sqlite
nomarchy-pkg-add phpExtensions.pdo_mysql
nomarchy-pkg-add phpPackages.composer
echo -e "\nPHP environment added to your packages."
;;
# The rest use 'mise' which is already installed and manages its own state in ~/.config/mise
*)
# Delegate to the original script logic if mise is used
# Or we can just call the mise command directly if it's a simple case.
# Let's keep the mise-based language installs as they are, but make sure mise is available.
/etc/profiles/per-user/$USER/bin/nomarchy-install-dev-env.original "$@"
;;
esac

View File

@@ -1,12 +1,30 @@
#!/bin/bash
#!/usr/bin/env bash
# Install one of the supported databases in a Docker container with the suitable development options.
# Configure Docker declaratively and provide instructions for running DBs.
# Usually called via Install > Development > Docker DB from the Nomarchy Menu.
FEATURE_FILE="/etc/nixos/nomarchy-features/docker.nix"
if [ ! -f "$FEATURE_FILE" ]; then
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
virtualisation.docker.enable = true;
users.users.\${config.users.users.mainUser}.extraGroups = [ "docker" ]; # Replace mainUser with your username
}
EOF
echo "Created $FEATURE_FILE to enable Docker."
echo "IMPORTANT: To finish enabling Docker, add './nomarchy-features/docker.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."
echo "Wait for the update to complete before running docker commands."
echo ""
fi
options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB" "MSSQL")
if (( $# == 0 )); then
choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select database (return to install, esc to cancel)") || main_menu
choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select database (ensure Docker is running)") || exit 0
else
choices="$@"
fi

View File

@@ -1,9 +1,23 @@
#!/bin/bash
#!/usr/bin/env bash
# Install and launch Steam after first letting the user pick the correct grahics card drivers.
# Configure Steam declaratively for NixOS
set -e
FEATURE_FILE="/etc/nixos/nomarchy-features/steam.nix"
echo "Now pick dependencies matching your graphics card"
sudo pacman -S steam
setsid gtk-launch steam >/dev/null 2>&1 &
if [ -f "$FEATURE_FILE" ]; then
echo "Steam is already configured in $FEATURE_FILE"
exit 0
fi
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
programs.steam.enable = true;
hardware.graphics.enable32Bit = true; # Needed for many games
}
EOF
echo "Created $FEATURE_FILE."
echo "IMPORTANT: To finish enabling Steam, add './nomarchy-features/steam.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."

View File

@@ -1,10 +1,25 @@
#!/bin/bash
#!/usr/bin/env bash
# Install the Tailscale mesh VPN service and a web app for the Tailscale Admin Console.
# Configure Tailscale declaratively for NixOS
curl -fsSL https://tailscale.com/install.sh | sh
FEATURE_FILE="/etc/nixos/nomarchy-features/tailscale.nix"
echo -e "\nStarting Tailscale..."
sudo tailscale up --accept-routes
if [ -f "$FEATURE_FILE" ]; then
echo "Tailscale is already configured in $FEATURE_FILE"
exit 0
fi
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
services.tailscale.enable = true;
}
EOF
echo "Created $FEATURE_FILE."
echo "IMPORTANT: To finish enabling Tailscale, add './nomarchy-features/tailscale.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."
echo "After sys-update completes, you can log in by running 'sudo tailscale up'."
nomarchy-webapp-install "Tailscale" "https://login.tailscale.com/admin/machines" https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tailscale-light.png

View File

@@ -1,29 +1,22 @@
#!/bin/bash
#!/usr/bin/env bash
# Install VSCode and configure it to use the gnome-libsecret password store, not to update automatically, and to use the current Nomarchy theme.
# Install VSCode declaratively for Nomarchy NixOS.
echo "Installing VSCode..."
nomarchy-pkg-add visual-studio-code-bin
nomarchy-pkg-add vscode
mkdir -p ~/.vscode ~/.config/Code/User
cat > ~/.vscode/argv.json << 'EOF'
// This configuration file allows you to pass permanent command line arguments to VS Code.
// Only a subset of arguments is currently supported to reduce the likelihood of breaking
// the installation.
//
// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT
//
// NOTE: Changing this file requires a restart of VS Code.
{
"password-store":"gnome-libsecret"
}
EOF
# VSCode still allows some runtime configuration in its JSON files.
mkdir -p ~/.config/Code/User
# Ensure VSC's own auto-update feature is turned off
printf '{\n "update.mode": "none"\n}\n' > ~/.config/Code/User/settings.json
if [ ! -f ~/.config/Code/User/settings.json ]; then
echo '{"update.mode": "none"}' > ~/.config/Code/User/settings.json
else
# Update existing settings.json with update.mode: none using jq
jq '. + {"update.mode": "none"}' ~/.config/Code/User/settings.json > ~/.config/Code/User/settings.json.tmp && mv ~/.config/Code/User/settings.json.tmp ~/.config/Code/User/settings.json
fi
# Apply Nomarchy theme to VSCode
nomarchy-theme-set-vscode
setsid gtk-launch code
setsid code >/dev/null 2>&1 &

View File

@@ -1,19 +1,23 @@
#!/bin/bash
#!/usr/bin/env bash
# Install support for using Xbox controllers with Steam/RetroArch/etc.
# Configure Xbox Controller support (xpadneo) declaratively for Nomarchy NixOS.
set -e
FEATURE_FILE="/etc/nixos/nomarchy-features/xbox-controller.nix"
# Install xpadneo to ensure controllers work out of the box
nomarchy-pkg-add linux-headers
nomarchy-pkg-aur-add xpadneo-dkms
if [ -f "$FEATURE_FILE" ]; then
echo "Xbox controller support is already configured in $FEATURE_FILE"
exit 0
fi
# Prevent xpad/xpadneo driver conflict
echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null
echo hid_xpadneo | sudo tee /etc/modules-load.d/xpadneo.conf >/dev/null
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
hardware.xpadneo.enable = true;
# Note: This automatically handles blacklisting xpad if needed and provides modules.
}
EOF
# Give user access to game controllers
sudo usermod -a -G input $USER
# Modules need to be loaded
gum confirm "Install requires reboot. Ready?" && sudo reboot now
echo "Created $FEATURE_FILE."
echo "IMPORTANT: To finish enabling Xbox controller support, add './nomarchy-features/xbox-controller.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."

75
bin/nomarchy-on-boot Executable file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Nomarchy on-boot initialization script.
# Automatically detects the hardware, applies necessary runtime tweaks,
# and sets the correct screen resolution/scaling.
# 1. Automatically configure optimal screen resolution and scaling
nomarchy-hyprland-monitor-scaling-cycle >/dev/null 2>&1
# 2. Hardware-specific runtime tweaks
if nomarchy-hw-match "Laptop 16"; then
# Framework 16 specific tweaks
nomarchy-theme-set-keyboard-f16 >/dev/null 2>&1
fi
if nomarchy-hw-asus-rog; then
# Asus ROG specific tweaks
nomarchy-theme-set-keyboard-asus-rog >/dev/null 2>&1
fi
# 3. Declarative hardware configuration check (nixos-hardware)
# This part ensures that if we are on an installed system, the correct
# nixos-hardware module is selected in the configuration.
HW_FILE="/etc/nixos/hardware-selection.nix"
if [ -w "$HW_FILE" ]; then
PRODUCT_NAME=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown")
BOARD_NAME=$(cat /sys/class/dmi/id/board_name 2>/dev/null || echo "Unknown")
CPU_VENDOR=$(lscpu | grep "Vendor ID" | awk '{print $3}')
NEW_HW_MODULES=""
if [[ "$CPU_VENDOR" == "AuthenticAMD" ]]; then
NEW_HW_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-amd"
elif [[ "$CPU_VENDOR" == "GenuineIntel" ]]; then
NEW_HW_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-intel"
fi
# Auto-detect specific known models for nixos-hardware
if echo "$PRODUCT_NAME" | grep -qi "XPS 15 9500"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.dell-xps-15-9500"
elif echo "$PRODUCT_NAME" | grep -qi "XPS 13"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.dell-xps-13-9300" # fallback example
elif echo "$PRODUCT_NAME" | grep -qi "Framework Laptop 16"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.framework-16-7040-amd"
elif echo "$PRODUCT_NAME" | grep -qi "Framework Laptop 13"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.framework-13-7040-amd"
elif echo "$PRODUCT_NAME" | grep -qi "Surface"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.microsoft-surface-pro-8" # fallback example
elif echo "$PRODUCT_NAME" | grep -qi "Zephyrus G14"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.asus-zephyrus-g14"
elif echo "$PRODUCT_NAME" | grep -qi "ThinkPad X1 Carbon"; then
NEW_HW_MODULES="$NEW_HW_MODULES\n inputs.nixos-hardware.nixosModules.lenovo-thinkpad-x1-carbon-gen9"
fi
# Check if the current HW file differs from our detection
if [ -n "$NEW_HW_MODULES" ] && ! grep -q "common-cpu" "$HW_FILE"; then
# This is a basic detection. We overwrite it if it's completely empty or missing common-cpu.
# It's better to let the user know, or auto-apply. We'll auto-apply for a smooth experience.
cat <<EOF > "$HW_FILE.tmp"
{ inputs, ... }:
{
imports = [
$NEW_HW_MODULES
];
}
EOF
if ! cmp -s "$HW_FILE" "$HW_FILE.tmp"; then
mv "$HW_FILE.tmp" "$HW_FILE"
# We notify the user instead of running sys-update silently, as it requires root and time.
notify-send -u normal "Hardware Auto-Detection" "New hardware profile detected. Please run 'sys-update' when ready."
else
rm "$HW_FILE.tmp"
fi
fi
fi

View File

@@ -1,17 +1,27 @@
#!/bin/bash
#!/usr/bin/env bash
# Add the named packages to the system if they're missing. Returns false if it couldn't be done.
PKG_NAME="$1"
if nomarchy-pkg-missing "$@"; then
sudo pacman -S --noconfirm --needed "$@" || exit 1
if [ -z "$PKG_NAME" ]; then
echo "Usage: nomarchy-pkg-add <package-name>"
exit 1
fi
for pkg in "$@"; do
# Secondary check to handle states where pacman doesn't actually register an error
if ! pacman -Q "$pkg" &>/dev/null; then
echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2
exit 1
fi
done
STATE_FILE="$HOME/.config/home-manager/user-packages.json"
mkdir -p "$(dirname "$STATE_FILE")"
exit 0
if [ ! -f "$STATE_FILE" ]; then
echo "[]" > "$STATE_FILE"
fi
if jq -e ". | index(\"$PKG_NAME\")" "$STATE_FILE" >/dev/null; then
echo "Package $PKG_NAME is already in your user-packages.json"
exit 0
fi
# Append package to the JSON array
jq ". + [\"$PKG_NAME\"]" "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
echo "Package $PKG_NAME added declaratively to $STATE_FILE."
echo "Applying changes with env-update..."
env-update

View File

@@ -1,17 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash
# Add the named packages to the system from the AUR if they're missing. Returns false if it couldn't be done.
if nomarchy-pkg-missing "$@"; then
yay -S --noconfirm --needed "$@" || exit 1
fi
for pkg in "$@"; do
# Secondary check to handle states where pacman doesn't actually register an error
if ! pacman -Q "$pkg" &>/dev/null; then
echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2
exit 1
fi
done
exit 0
echo "AUR is an Arch Linux concept and is not supported on NixOS."
echo "Please use 'nomarchy-pkg-add' to install packages from nixpkgs."
exit 1

View File

@@ -1,28 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash
# Show a fuzzy-finder TUI for picking new AUR packages to install.
fzf_args=(
--multi
--preview 'yay -Siia {1}'
--preview-label='alt-p: toggle description, alt-b/B: toggle PKGBUILD, alt-j/k: scroll, tab: multi-select'
--preview-label-pos='bottom'
--preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview'
--bind 'alt-d:preview-half-page-down,alt-u:preview-half-page-up'
--bind 'alt-k:preview-up,alt-j:preview-down'
--bind 'alt-b:change-preview:yay -Gpa {1} | tail -n +5'
--bind 'alt-B:change-preview:yay -Siia {1}'
--color 'pointer:green,marker:green'
)
pkg_names=$(yay -Slqa | fzf "${fzf_args[@]}")
if [[ -n $pkg_names ]]; then
# Add aur/ prefix to each package name and convert to space-separated for yay
source nomarchy-sudo-keepalive
echo "$pkg_names" | sed 's/^/aur\//' | tr '\n' ' ' | xargs yay -S --noconfirm
sudo updatedb
nomarchy-show-done
fi
echo "AUR is an Arch Linux concept and is not supported on NixOS."
echo "Please use 'nomarchy-pkg-add' to install packages from nixpkgs."
exit 1

View File

@@ -1,11 +1,15 @@
#!/bin/bash
#!/usr/bin/env bash
# Returns true if any of the named packages are missing from the system (or false if they're all there).
PKG_NAME="$1"
for pkg in "$@"; do
if ! pacman -Q "$pkg" &>/dev/null; then
if [ -z "$PKG_NAME" ]; then
echo "Usage: nomarchy-pkg-missing <package-name>"
exit 1
fi
nomarchy-pkg-present "$PKG_NAME"
if [ $? -eq 0 ]; then
exit 1
else
exit 0
fi
done
exit 1
fi

View File

@@ -1,9 +1,20 @@
#!/bin/bash
#!/usr/bin/env bash
# Returns true if all of the named packages are installed on the system (or false if any of them are missing).
PKG_NAME="$1"
for pkg in "$@"; do
pacman -Q "$pkg" &>/dev/null || exit 1
done
if [ -z "$PKG_NAME" ]; then
echo "Usage: nomarchy-pkg-present <package-name>"
exit 1
fi
exit 0
STATE_FILE="$HOME/.config/home-manager/user-packages.json"
if [ ! -f "$STATE_FILE" ]; then
exit 1
fi
if jq -e ". | index(\"$PKG_NAME\")" "$STATE_FILE" >/dev/null; then
exit 0
else
exit 1
fi

View File

@@ -1,23 +1,27 @@
#!/bin/bash
#!/usr/bin/env bash
# Show a fuzzy-finder TUI for picking packages installed on the system to be removed.
PKG_NAME="$1"
fzf_args=(
--multi
--preview 'yay -Qi {1}'
--preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select'
--preview-label-pos='bottom'
--preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview'
--bind 'alt-d:preview-half-page-down,alt-u:preview-half-page-up'
--bind 'alt-k:preview-up,alt-j:preview-down'
--color 'pointer:red,marker:red'
)
pkg_names=$(yay -Qqe | fzf "${fzf_args[@]}")
if [[ -n $pkg_names ]]; then
# Convert newline-separated selections to space-separated for yay
echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -Rns --noconfirm
nomarchy-show-done
if [ -z "$PKG_NAME" ]; then
echo "Usage: nomarchy-pkg-remove <package-name>"
exit 1
fi
STATE_FILE="$HOME/.config/home-manager/user-packages.json"
if [ ! -f "$STATE_FILE" ]; then
echo "No packages managed by nomarchy-pkg yet."
exit 0
fi
if ! jq -e ". | index(\"$PKG_NAME\")" "$STATE_FILE" >/dev/null; then
echo "Package $PKG_NAME is not in your user-packages.json"
exit 0
fi
# Remove package from the JSON array
jq ". - [\"$PKG_NAME\"]" "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
echo "Package $PKG_NAME removed declaratively from $STATE_FILE."
echo "Applying changes with env-update..."
env-update

View File

@@ -1,127 +1,46 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# Configure FIDO2 support declaratively for Nomarchy NixOS.
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${YELLOW}$1${NC}"
}
check_fido2_hardware() {
tokens=$(fido2-token -L 2>/dev/null)
if [[ -z $tokens ]]; then
print_error "\nNo FIDO2 device detected. Please plug it in (you may need to unlock it as well)."
return 1
fi
return 0
}
setup_pam_config() {
# Configure sudo
if ! grep -q pam_u2f.so /etc/pam.d/sudo; then
print_info "Configuring sudo for FIDO2 authentication..."
sudo sed -i '1i auth sufficient pam_u2f.so cue authfile=/etc/fido2/fido2' /etc/pam.d/sudo
fi
# Configure polkit
if [[ -f /etc/pam.d/polkit-1 ]] && ! grep -q 'pam_u2f.so' /etc/pam.d/polkit-1; then
print_info "Configuring polkit for FIDO2 authentication..."
sudo sed -i '1i auth sufficient pam_u2f.so cue authfile=/etc/fido2/fido2' /etc/pam.d/polkit-1
elif [[ ! -f /etc/pam.d/polkit-1 ]]; then
print_info "Creating polkit configuration with FIDO2 authentication..."
sudo tee /etc/pam.d/polkit-1 >/dev/null <<'EOF'
auth sufficient pam_u2f.so cue authfile=/etc/fido2/fido2
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
EOF
fi
}
remove_pam_config() {
# Remove from sudo
if grep -q pam_u2f.so /etc/pam.d/sudo; then
print_info "Removing FIDO2 authentication from sudo..."
sudo sed -i '/pam_u2f\.so/d' /etc/pam.d/sudo
fi
# Remove from polkit
if [[ -f /etc/pam.d/polkit-1 ]] && grep -Fq 'pam_u2f.so' /etc/pam.d/polkit-1; then
print_info "Removing FIDO2 authentication from polkit..."
sudo sed -i '/pam_u2f\.so/d' /etc/pam.d/polkit-1
fi
}
FEATURE_FILE="/etc/nixos/nomarchy-features/fido2.nix"
if [[ "--remove" == $1 ]]; then
print_success "Removing FIDO2 device from authentication.\n"
# Remove PAM configuration
remove_pam_config
# Remove FIDO2 configuration
if [[ -d /etc/fido2 ]]; then
print_info "Removing FIDO2 configuration..."
sudo rm -rf /etc/fido2
fi
# Uninstall packages
print_info "Removing FIDO2 packages..."
sudo pacman -Rns --noconfirm libfido2 pam-u2f
print_success "FIDO2 authentication has been completely removed."
else
print_success "Setting up FIDO2 device for authentication.\n"
# Install required packages
print_info "Installing required packages..."
nomarchy-pkg-add libfido2 pam-u2f
if ! check_fido2_hardware; then
exit 1
fi
# Create the pamu2fcfg file
if [[ ! -f /etc/fido2/fido2 ]]; then
sudo mkdir -p /etc/fido2
print_success "\nLet's setup your device by confirming on the device now."
print_info "Touch your FIDO2 key when it lights up...\n"
if pamu2fcfg >/tmp/fido2; then
sudo mv /tmp/fido2 /etc/fido2/fido2
print_success "FIDO2 device registered successfully!"
if [ -f "$FEATURE_FILE" ]; then
sudo rm "$FEATURE_FILE"
echo "Removed $FEATURE_FILE."
echo "IMPORTANT: Remove './nomarchy-features/fido2.nix' from your imports and run 'sys-update'."
else
print_error "\nFIDO2 registration failed. Please try again."
exit 1
fi
else
print_info "FIDO2 device already registered."
fi
# Configure PAM
setup_pam_config
# Test with sudo
print_info "\nTesting FIDO2 authentication with sudo..."
print_info "Touch your FIDO2 key when prompted.\n"
if sudo echo "FIDO2 authentication test successful"; then
print_success "\nPerfect! FIDO2 authentication is now configured."
print_info "You can use your FIDO2 key for sudo and polkit authentication."
else
print_error "\nVerification failed. You may want to check your configuration."
echo "FIDO2 support not found."
fi
exit 0
fi
if [ -f "$FEATURE_FILE" ]; then
echo "FIDO2 support is already configured in $FEATURE_FILE"
else
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
security.pam.u2f = {
enable = true;
control = "sufficient";
cue = true;
# authFile = "/etc/fido2/fido2"; # Default is ~/.config/Yubico/u2f_keys
};
}
EOF
echo "Created $FEATURE_FILE."
echo "IMPORTANT: To finish enabling FIDO2 support, add './nomarchy-features/fido2.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."
fi
# Enrollment is still an imperative action
if command -v pamu2fcfg &> /dev/null; then
echo "Let's register your FIDO2 key now."
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
echo "FIDO2 key registered."
else
echo "pamu2fcfg not found. Please run 'nomarchy-pkg-add pam-u2f' or 'sys-update' if you just enabled it."
fi

View File

@@ -1,134 +1,40 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# Configure Fingerprint support declaratively for Nomarchy NixOS.
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${YELLOW}$1${NC}"
}
check_fingerprint_hardware() {
# Get fingerprint devices for the user
devices=$(fprintd-list "$USER" 2>/dev/null)
# Exit if no devices found
if [[ -z $devices ]]; then
print_error "\nNo fingerprint sensor detected."
return 1
fi
return 0
}
setup_pam_config() {
# Configure sudo
if ! grep -q pam_fprintd.so /etc/pam.d/sudo; then
print_info "Configuring sudo for fingerprint authentication..."
sudo sed -i '1i auth sufficient pam_fprintd.so' /etc/pam.d/sudo
fi
# Configure polkit
if [[ -f /etc/pam.d/polkit-1 ]] && ! grep -q 'pam_fprintd.so' /etc/pam.d/polkit-1; then
print_info "Configuring polkit for fingerprint authentication..."
sudo sed -i '1i auth sufficient pam_fprintd.so' /etc/pam.d/polkit-1
elif [[ ! -f /etc/pam.d/polkit-1 ]]; then
print_info "Creating polkit configuration with fingerprint authentication..."
sudo tee /etc/pam.d/polkit-1 >/dev/null <<'EOF'
auth sufficient pam_fprintd.so
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
EOF
fi
}
add_hyprlock_fingerprint_icon() {
print_info "Adding fingerprint icon to hyprlock placeholder text..."
sed -i 's/placeholder_text = .*/placeholder_text = <span> Enter Password 󰈷 <\/span>/' ~/.config/hypr/hyprlock.conf
sed -i 's/fingerprint:enabled = .*/fingerprint:enabled = true/' ~/.config/hypr/hyprlock.conf
}
remove_hyprlock_fingerprint_icon() {
print_info "Removing fingerprint icon from hyprlock placeholder text..."
sed -i 's/placeholder_text = .*/placeholder_text = Enter Password/' ~/.config/hypr/hyprlock.conf
sed -i 's/fingerprint:enabled = .*/fingerprint:enabled = false/' ~/.config/hypr/hyprlock.conf
}
remove_pam_config() {
# Remove from sudo
if grep -q pam_fprintd.so /etc/pam.d/sudo; then
print_info "Removing fingerprint authentication from sudo..."
sudo sed -i '/pam_fprintd\.so/d' /etc/pam.d/sudo
fi
# Remove from polkit
if [[ -f /etc/pam.d/polkit-1 ]] && grep -Fq 'pam_fprintd.so' /etc/pam.d/polkit-1; then
print_info "Removing fingerprint authentication from polkit..."
sudo sed -i '/pam_fprintd\.so/d' /etc/pam.d/polkit-1
fi
}
FEATURE_FILE="/etc/nixos/nomarchy-features/fingerprint.nix"
if [[ "--remove" == $1 ]]; then
print_success "Removing fingerprint scanner from authentication.\n"
# Remove PAM configuration
remove_pam_config
# Remove fingerprint icon from hyprlock placeholder text
remove_hyprlock_fingerprint_icon
# Uninstall packages
print_info "Removing fingerprint packages..."
sudo pacman -Rns --noconfirm fprintd
print_success "Fingerprint authentication has been completely removed."
else
print_success "Setting up fingerprint scanner for authentication.\n"
# Install required packages
print_info "Installing required packages..."
nomarchy-pkg-add fprintd usbutils
if ! check_fingerprint_hardware; then
exit 1
fi
# Configure PAM
setup_pam_config
# Add fingerprint icon to hyprlock placeholder text
add_hyprlock_fingerprint_icon
# Enroll first fingerprint
print_success "\nLet's setup your right index finger as the first fingerprint."
print_info "Keep moving the finger around on sensor until the process completes.\n"
if sudo fprintd-enroll "$USER"; then
print_success "\nFingerprint enrolled successfully!"
# Verify
print_info "\nNow let's verify that it's working correctly.\n"
if fprintd-verify; then
print_success "\nPerfect! Fingerprint authentication is now configured."
print_info "You can use your fingerprint for sudo, polkit, and lock screen (Super + Escape)."
if [ -f "$FEATURE_FILE" ]; then
sudo rm "$FEATURE_FILE"
echo "Removed $FEATURE_FILE."
echo "IMPORTANT: Remove './nomarchy-features/fingerprint.nix' from your imports and run 'sys-update'."
else
print_error "\nVerification failed. You may want to try enrolling again."
fi
else
print_error "\nEnrollment failed. Please try again."
exit 1
echo "Fingerprint support not found."
fi
exit 0
fi
if [ -f "$FEATURE_FILE" ]; then
echo "Fingerprint support is already configured in $FEATURE_FILE"
else
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
services.fprintd.enable = true;
# NixOS's fprintd module automatically configures PAM for login/sudo if enabled.
}
EOF
echo "Created $FEATURE_FILE."
echo "IMPORTANT: To finish enabling fingerprint support, add './nomarchy-features/fingerprint.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."
fi
# Enrollment is still an imperative action
if command -v fprintd-enroll &> /dev/null; then
echo "Let's enroll your fingerprint now."
fprintd-enroll "$USER"
else
echo "fprintd-enroll not found. Please run 'sys-update' first if you just enabled it."
fi

View File

@@ -1,50 +1,56 @@
#!/bin/bash
#!/usr/bin/env bash
# Cycles through the background images available
# Cycles through the background images available for the current theme.
# Declarative + Hybrid (instant swww) for Nomarchy NixOS.
THEME_NAME=$(cat "$HOME/.config/nomarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.config/nomarchy/current/theme/backgrounds/"
USER_BACKGROUNDS_PATH="$HOME/.config/nomarchy/backgrounds/$THEME_NAME/"
CURRENT_BACKGROUND_LINK="$HOME/.config/nomarchy/current/background"
STATE_DIR="$HOME/.config/home-manager"
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
mapfile -d '' -t BACKGROUNDS < <(find -L "$USER_BACKGROUNDS_PATH" "$THEME_BACKGROUNDS_PATH" -maxdepth 1 -type f -print0 2>/dev/null | sort -z)
THEME_NAME=$(cat "$THEME_STATE_FILE" 2>/dev/null || echo "dracula")
if [ -d "/etc/nixos/nomarchy/themes" ]; then
THEMES_DIR="/etc/nixos/nomarchy/themes"
elif [ -d "/etc/nomarchy/themes" ]; then
THEMES_DIR="/etc/nomarchy/themes"
else
THEMES_DIR="/etc/nixos/themes"
fi
BG_DIR="$THEMES_DIR/$THEME_NAME/backgrounds"
if [ ! -d "$BG_DIR" ]; then
notify-send "No background directory found for theme $THEME_NAME"
exit 1
fi
mapfile -t BACKGROUNDS < <(ls "$BG_DIR" | sort)
TOTAL=${#BACKGROUNDS[@]}
if (( TOTAL == 0 )); then
notify-send "No background was found for theme" -t 2000
pkill -x swaybg
setsid uwsm-app -- swaybg --color '#000000' >/dev/null 2>&1 &
else
# Get current background from symlink
if [[ -L $CURRENT_BACKGROUND_LINK ]]; then
CURRENT_BACKGROUND=$(readlink "$CURRENT_BACKGROUND_LINK")
else
# Default to first background if no symlink exists
CURRENT_BACKGROUND=""
fi
notify-send "No backgrounds found in $BG_DIR"
exit 1
fi
# Find current background index
INDEX=-1
for i in "${!BACKGROUNDS[@]}"; do
if [[ ${BACKGROUNDS[$i]} == $CURRENT_BACKGROUND ]]; then
CURRENT_BG=$(cat "$WALLPAPER_STATE_FILE" 2>/dev/null)
INDEX=-1
for i in "${!BACKGROUNDS[@]}"; do
if [[ "$BG_DIR/${BACKGROUNDS[$i]}" == "$CURRENT_BG" ]]; then
INDEX=$i
break
fi
done
done
# Get next background (wrap around)
if (( INDEX == -1 )); then
# Use the first background when no match was found
NEW_BACKGROUND="${BACKGROUNDS[0]}"
else
NEXT_INDEX=$(((INDEX + 1) % TOTAL))
NEW_BACKGROUND="${BACKGROUNDS[$NEXT_INDEX]}"
fi
NEXT_INDEX=$(((INDEX + 1) % TOTAL))
NEW_BG="$BG_DIR/${BACKGROUNDS[$NEXT_INDEX]}"
# Set new background symlink
ln -nsf "$NEW_BACKGROUND" "$CURRENT_BACKGROUND_LINK"
echo "$NEW_BG" > "$WALLPAPER_STATE_FILE"
# Relaunch swaybg
pkill -x swaybg
setsid uwsm-app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 &
# Instant feedback via swww
if pgrep -x swww-daemon >/dev/null; then
swww img "$NEW_BG" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90
else
swww init && swww img "$NEW_BG"
fi
echo "Background set to $NEW_BG declaratively."

View File

@@ -1,60 +1,48 @@
#!/bin/bash
#!/usr/bin/env bash
if [[ -z $1 ]]; then
# Set the system theme declaratively.
# Usage: nomarchy-theme-set <theme-name>
THEME_NAME="$1"
if [[ -z $THEME_NAME ]]; then
echo "Usage: nomarchy-theme-set <theme-name>"
exit 1
fi
CURRENT_THEME_PATH="$HOME/.config/nomarchy/current/theme"
NEXT_THEME_PATH="$HOME/.config/nomarchy/current/next-theme"
USER_THEMES_PATH="$HOME/.config/nomarchy/themes"
OMARCHY_THEMES_PATH="$OMARCHY_PATH/themes"
STATE_DIR="$HOME/.config/home-manager"
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
THEME_NAME=$(echo "$1" | sed -E 's/<[^>]+>//g' | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
if [[ ! -d $OMARCHY_THEMES_PATH/$THEME_NAME ]] && [[ ! -d $USER_THEMES_PATH/$THEME_NAME ]]; then
echo "Theme '$THEME_NAME' does not exist"
exit 1
# Logic for finding themes
if [ -d "/etc/nixos/nomarchy/themes" ]; then
THEMES_DIR="/etc/nixos/nomarchy/themes"
elif [ -d "/etc/nomarchy/themes" ]; then
THEMES_DIR="/etc/nomarchy/themes"
else
THEMES_DIR="/etc/nixos/themes"
fi
# Setup clean next theme directory (for atomic theme config swapping)
rm -rf "$NEXT_THEME_PATH"
mkdir -p "$NEXT_THEME_PATH"
mkdir -p "$STATE_DIR"
# Copy official theme first, then overlay user customizations on top
cp -r "$OMARCHY_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null
cp -r "$USER_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null
# Generate dynamic configs
nomarchy-theme-set-templates
# Swap next theme in as current
rm -rf "$CURRENT_THEME_PATH"
mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
# Store theme name for reference
echo "$THEME_NAME" >"$HOME/.config/nomarchy/current/theme.name"
# Change background with theme
nomarchy-theme-bg-next
# Restart components to apply new theme
if pgrep -x waybar >/dev/null; then
nomarchy-restart-waybar
if [ ! -d "$THEMES_DIR/$THEME_NAME" ] && ! [[ "$THEME_NAME" == "dracula" || "$THEME_NAME" == "nord" ]]; then
echo "Theme '$THEME_NAME' not found in $THEMES_DIR"
# Check if it exists in the palettes file
# (Assuming nomarchy-palettes.nix is imported in Nix)
fi
nomarchy-restart-swayosd
nomarchy-restart-terminal
nomarchy-restart-hyprctl
nomarchy-restart-btop
nomarchy-restart-opencode
nomarchy-restart-mako
# Change app-specific themes
nomarchy-theme-set-gnome
nomarchy-theme-set-browser
nomarchy-theme-set-vscode
nomarchy-theme-set-obsidian
nomarchy-theme-set-keyboard
echo "$THEME_NAME" > "$THEME_STATE_FILE"
# Try to find a background for this theme
BG_DIR="$THEMES_DIR/$THEME_NAME/backgrounds"
if [ -d "$BG_DIR" ]; then
BG=$(ls "$BG_DIR" | head -n 1)
if [ -n "$BG" ]; then
echo "$BG_DIR/$BG" > "$WALLPAPER_STATE_FILE"
fi
fi
echo "Theme set to $THEME_NAME. Applying changes with env-update..."
env-update
# Call hook on theme set
nomarchy-hook theme-set "$THEME_NAME"

View File

@@ -1,65 +1,44 @@
#!/bin/bash
#!/usr/bin/env bash
# Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14).
# Requires reboot to take effect.
# Declarative enablement + Runtime mode switching for Nomarchy NixOS.
# Ensure supergfxctl has been installed
if nomarchy-cmd-missing supergfxctl; then
nomarchy-pkg-add supergfxctl
FEATURE_FILE="/etc/nixos/nomarchy-features/supergfxd.nix"
# Create config before starting service to prevent hang on first boot
sudo tee /etc/supergfxd.conf >/dev/null <<'CONF'
if ! command -v supergfxctl &> /dev/null; then
sudo mkdir -p "/etc/nixos/nomarchy-features"
cat <<EOF | sudo tee "$FEATURE_FILE" > /dev/null
{ config, pkgs, ... }:
{
"mode": "Hybrid",
"vfio_enable": true,
"vfio_save": false,
"always_reboot": false,
"no_logind": false,
"logout_timeout_s": 180,
"hotplug_type": "None"
services.supergfxd.enable = true;
}
CONF
sudo systemctl enable --now supergfxd
EOF
echo "Created $FEATURE_FILE to enable supergfxd."
echo "IMPORTANT: To finish enabling hybrid GPU support, add './nomarchy-features/supergfxd.nix' to your imports list in /etc/nixos/system.nix or /etc/nixos/flake.nix,"
echo "then run 'sys-update'."
exit 0
fi
gpu_mode=$(supergfxctl -g)
echo "Current GPU mode: $gpu_mode"
case "$gpu_mode" in
"Integrated")
if gum confirm "Enable dedicated GPU and reboot?"; then
# Switch to hybrid mode
sudo sed -i "s/\"mode\": \".*\"/\"mode\": \"Hybrid\"/" /etc/supergfxd.conf
# Let hybrid mode be the default after system sleep
sudo rm -rf /usr/lib/systemd/system-sleep/force-igpu
# Remove the startup delay override (not needed for Hybrid mode)
sudo rm -rf /etc/systemd/system/supergfxd.service.d/delay-start.conf
if gum confirm "Switch to Hybrid mode (enables dGPU) and reboot?"; then
supergfxctl -m Hybrid
echo "Switching to Hybrid mode..."
nomarchy-system-reboot
fi
;;
"Hybrid")
if gum confirm "Use only integrated GPU and reboot?"; then
# Switch to integrated mode and ensure vfio is enabled (needed for sleep/wake trick)
sudo sed -i "s/\"mode\": \".*\"/\"mode\": \"Integrated\"/" /etc/supergfxd.conf
sudo sed -i 's/"vfio_enable": false/"vfio_enable": true/' /etc/supergfxd.conf
# Force igpu mode after system sleep (or dgpu could get activated)
sudo mkdir -p /usr/lib/systemd/system-sleep
sudo cp -p $OMARCHY_PATH/default/systemd/system-sleep/force-igpu /usr/lib/systemd/system-sleep/
# Delay supergfxd startup to avoid race condition with display manager
# that can cause system freeze when booting in Integrated mode
sudo mkdir -p /etc/systemd/system/supergfxd.service.d
sudo cp -p $OMARCHY_PATH/default/systemd/system/supergfxd.service.d/delay-start.conf /etc/systemd/system/supergfxd.service.d/
if gum confirm "Switch to Integrated mode (disables dGPU) and reboot?"; then
supergfxctl -m Integrated
echo "Switching to Integrated mode..."
nomarchy-system-reboot
fi
;;
*)
echo "Hybrid GPU not found or in unknown mode."
echo "Hybrid GPU in unknown mode: $gpu_mode. Try 'supergfxctl -m Hybrid' manually."
exit 1
;;
esac

View File

@@ -1,11 +1,28 @@
#!/bin/bash
#!/usr/bin/env bash
if pgrep -x hypridle >/dev/null; then
# Toggles the idle daemon (hypridle) between enabled and disabled.
# Declarative + Hybrid (instant IPC/kill) for Nomarchy NixOS.
STATE_FILE="$HOME/.config/home-manager/idle-state.json"
mkdir -p "$(dirname "$STATE_FILE")"
if [ ! -f "$STATE_FILE" ]; then
echo '{"enabled": true}' > "$STATE_FILE"
fi
enabled=$(jq -r '.enabled' "$STATE_FILE")
if [[ $enabled == "true" ]]; then
NEW_ENABLED="false"
pkill -x hypridle
notify-send -u low "󱫖 Stop locking computer when idle"
else
uwsm-app -- hypridle >/dev/null 2>&1 &
NEW_ENABLED="true"
setsid hypridle >/dev/null 2>&1 &
notify-send -u low "󱫖 Now locking computer when idle"
fi
pkill -RTMIN+9 waybar
echo "{\"enabled\": $NEW_ENABLED}" > "$STATE_FILE"
echo "Idle daemon set to $NEW_ENABLED declaratively."
pkill -RTMIN+9 waybar # Signal waybar if needed

View File

@@ -1,30 +1,36 @@
#!/bin/bash
#!/usr/bin/env bash
# Default temperature values
ON_TEMP=4000
OFF_TEMP=6000
# Toggles the nightlight (hyprsunset) between enabled (4000) and disabled (6500)
# Declarative + Hybrid (instant IPC) for Nomarchy NixOS.
# Ensure hyprsunset is running
if ! pgrep -x hyprsunset; then
setsid uwsm-app -- hyprsunset &
sleep 1 # Give it time to register
STATE_FILE="$HOME/.config/home-manager/hyprsunset-state.json"
mkdir -p "$(dirname "$STATE_FILE")"
if [ ! -f "$STATE_FILE" ]; then
echo '{"enabled": false, "temperature": 4000}' > "$STATE_FILE"
fi
# Query the current temperature
CURRENT_TEMP=$(hyprctl hyprsunset temperature 2>/dev/null | grep -oE '[0-9]+')
enabled=$(jq -r '.enabled' "$STATE_FILE")
restart_nightlighted_waybar() {
if grep -q "custom/nightlight" ~/.config/waybar/config.jsonc; then
nomarchy-restart-waybar # restart waybar in case user has waybar module for hyprsunset
fi
}
if [[ $CURRENT_TEMP == $OFF_TEMP ]]; then
hyprctl hyprsunset temperature $ON_TEMP
notify-send -u low " Nightlight screen temperature"
restart_nightlighted_waybar
if [[ $enabled == "true" ]]; then
NEW_ENABLED="false"
TEMP=6500
notify-send -u low " Nightlight DISABLED"
else
hyprctl hyprsunset temperature $OFF_TEMP
notify-send -u low " Daylight screen temperature"
restart_nightlighted_waybar
NEW_ENABLED="true"
TEMP=4000
notify-send -u low " Nightlight ENABLED"
fi
# Instant feedback via IPC
if pgrep -x hyprsunset >/dev/null; then
hyprctl hyprsunset temperature $TEMP
else
# Should be started by systemd, but just in case
setsid hyprsunset -t $TEMP &
fi
echo "{\"enabled\": $NEW_ENABLED, \"temperature\": 4000}" > "$STATE_FILE"
echo "Nightlight set to $NEW_ENABLED ($TEMP) declaratively."
# No need to run env-update if we don't want the delay,
# as next HM switch will pick it up and apply it.

View File

@@ -1,13 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash
# Update AUR packages if any are installed
if pacman -Qem >/dev/null; then
if nomarchy-pkg-aur-accessible; then
echo -e "\e[32m\nUpdate AUR packages\e[0m"
yay -Sua --noconfirm --cleanafter --ignore gcc14,gcc14-libs
echo
else
echo -e "\e[31m\nAUR is unavailable (so skipping updates)\e[0m"
echo
fi
fi
echo "AUR is an Arch Linux concept and is not supported on NixOS."
echo "Please use 'nomarchy-pkg-add' to install packages from nixpkgs."
exit 1

View File

@@ -1,18 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Ensure we have the nomarchy-keyring and it's populated
if nomarchy-pkg-missing nomarchy-keyring || ! sudo pacman-key --list-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 &>/dev/null; then
sudo pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org
sudo pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571
# This is generally not a good idea, but this is a special case because we're going to be updating
# the full set of packages in nomarchy-update-system-pkgs right after this (and it needs latest keyring)!
sudo pacman -Sy
nomarchy-pkg-add nomarchy-keyring
sudo pacman-key --list-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571
fi
# Ensure we have the latest archlinux-keyring, maintainer keys might have changed
echo -e "\e[32m\nUpdate Arch signing keys\e[0m"
sudo pacman -Sy --noconfirm archlinux-keyring >/dev/null
echo "Pacman keyring is an Arch Linux concept and is not supported on NixOS."
exit 1

582
flake.lock generated Normal file
View File

@@ -0,0 +1,582 @@
{
"nodes": {
"base16": {
"inputs": {
"fromYaml": "fromYaml"
},
"locked": {
"lastModified": 1755819240,
"narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
"owner": "SenchoPens",
"repo": "base16.nix",
"rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "base16.nix",
"type": "github"
}
},
"base16-fish": {
"flake": false,
"locked": {
"lastModified": 1765809053,
"narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=",
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
},
"original": {
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
}
},
"base16-helix": {
"flake": false,
"locked": {
"lastModified": 1760703920,
"narHash": "sha256-m82fGUYns4uHd+ZTdoLX2vlHikzwzdu2s2rYM2bNwzw=",
"owner": "tinted-theming",
"repo": "base16-helix",
"rev": "d646af9b7d14bff08824538164af99d0c521b185",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-helix",
"type": "github"
}
},
"base16-schemes": {
"flake": false,
"locked": {
"lastModified": 1696158499,
"narHash": "sha256-5yIHgDTPjoX/3oDEfLSQ0eJZdFL1SaCfb9d6M0RmOTM=",
"owner": "tinted-theming",
"repo": "base16-schemes",
"rev": "a9112eaae86d9dd8ee6bb9445b664fba2f94037a",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-schemes",
"type": "github"
}
},
"base16-vim": {
"flake": false,
"locked": {
"lastModified": 1732806396,
"narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=",
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1773889306,
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
"owner": "nix-community",
"repo": "disko",
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"elephant": {
"inputs": {
"nixpkgs": [
"walker",
"nixpkgs"
],
"systems": [
"walker",
"systems"
]
},
"locked": {
"lastModified": 1768551400,
"narHash": "sha256-mlHlHW8qLcHm42J1M34HLXLW+Rw8jsLkLdjSvIYlhjw=",
"owner": "abenz1267",
"repo": "elephant",
"rev": "f230c43ae94231c2db754f84a4f31cf76721a28a",
"type": "github"
},
"original": {
"owner": "abenz1267",
"repo": "elephant",
"type": "github"
}
},
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1764873433,
"narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92",
"type": "github"
},
"original": {
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1767609335,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"fromYaml": {
"flake": false,
"locked": {
"lastModified": 1731966426,
"narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
"owner": "SenchoPens",
"repo": "fromYaml",
"rev": "106af9e2f715e2d828df706c386a685698f3223b",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "fromYaml",
"type": "github"
}
},
"gnome-shell": {
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "gitlab"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "gnome-49",
"repo": "gnome-shell",
"type": "gitlab"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1775077333,
"narHash": "sha256-OXcxobt7lBkh1B8AjwreU+24myhtKpqeLfAeIyNLFY8=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "49ca96b2714c5931e17401eff87f3edd42d2b0f2",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.11",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"impermanence",
"nixpkgs"
]
},
"locked": {
"lastModified": 1768598210,
"narHash": "sha256-kkgA32s/f4jaa4UG+2f8C225Qvclxnqs76mf8zvTVPg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "c47b2cc64a629f8e075de52e4742de688f930dc6",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"impermanence": {
"inputs": {
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1769548169,
"narHash": "sha256-03+JxvzmfwRu+5JafM0DLbxgHttOQZkUtDWBmeUkN8Y=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "7b1d382faf603b6d264f58627330f9faa5cba149",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"nix-colors": {
"inputs": {
"base16-schemes": "base16-schemes",
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1707825078,
"narHash": "sha256-hTfge2J2W+42SZ7VHXkf4kjU+qzFqPeC9k66jAUBMHk=",
"owner": "misterio77",
"repo": "nix-colors",
"rev": "b01f024090d2c4fc3152cd0cf12027a7b8453ba1",
"type": "github"
},
"original": {
"owner": "misterio77",
"repo": "nix-colors",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1774933469,
"narHash": "sha256-OrnCQeUO2bqaWUl0lkDWyGWjKsOhtCyd7JSfTedQNUE=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "f4c4c2c0c923d7811ac2a63ccc154767e4195337",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1697935651,
"narHash": "sha256-qOfWjQ2JQSQL15KLh6D7xQhx0qgZlYZTYlcEiRuAMMw=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "e1e11fdbb01113d85c7f41cada9d2847660e3902",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1775002709,
"narHash": "sha256-d3Yx83vSrN+2z/loBh4mJpyRqr9aAJqlke4TkpFmRJA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "bcd464ccd2a1a7cd09aa2f8d4ffba83b761b1d0e",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1767767207,
"narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5912c1772a44e31bf1c63c0390b90501e5026886",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nur": {
"inputs": {
"flake-parts": [
"stylix",
"flake-parts"
],
"nixpkgs": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1767810917,
"narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=",
"owner": "nix-community",
"repo": "NUR",
"rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "NUR",
"type": "github"
}
},
"root": {
"inputs": {
"disko": "disko",
"home-manager": "home-manager",
"impermanence": "impermanence",
"nix-colors": "nix-colors",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_2",
"stylix": "stylix",
"walker": "walker"
}
},
"stylix": {
"inputs": {
"base16": "base16",
"base16-fish": "base16-fish",
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts",
"gnome-shell": "gnome-shell",
"nixpkgs": "nixpkgs_3",
"nur": "nur",
"systems": "systems",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1774897726,
"narHash": "sha256-k/H2/oyex6GEC6uYXYetrboFQeTmX1Ouwv/zaW7b/Z0=",
"owner": "danth",
"repo": "stylix",
"rev": "9b4a5eb409ceac2dd6ad495c7988e189a418cd30",
"type": "github"
},
"original": {
"owner": "danth",
"repo": "stylix",
"type": "github"
}
},
"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"
}
},
"tinted-foot": {
"flake": false,
"locked": {
"lastModified": 1726913040,
"narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
"lastModified": 1735730497,
"narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=",
"owner": "tinted-theming",
"repo": "tinted-kitty",
"rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-kitty",
"type": "github"
}
},
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1767710407,
"narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "schemes",
"type": "github"
}
},
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1767489635,
"narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-tmux",
"type": "github"
}
},
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1767488740,
"narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-zed",
"type": "github"
}
},
"walker": {
"inputs": {
"elephant": "elephant",
"nixpkgs": "nixpkgs_4",
"systems": "systems_2"
},
"locked": {
"lastModified": 1773675699,
"narHash": "sha256-GrormZ2KxchtCLuO90+5fioEQmlUCKBIil0Mzr9w0Iw=",
"owner": "abenz1267",
"repo": "walker",
"rev": "d2702235710da3d7daf55c912ca7534261cf20f5",
"type": "github"
},
"original": {
"owner": "abenz1267",
"repo": "walker",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -2,7 +2,7 @@
description = "Nomarchy - A NixOS-based distribution with Omarchy flavour";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
disko = {
@@ -10,8 +10,10 @@
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
home-manager = {
url = "github:nix-community/home-manager";
url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
@@ -20,7 +22,7 @@
walker.url = "github:abenz1267/walker";
};
outputs = { self, nixpkgs, nixos-hardware, disko, home-manager, nix-colors, stylix, walker, ... } @ inputs: {
outputs = { self, nixpkgs, nixos-hardware, disko, impermanence, home-manager, nix-colors, stylix, walker, ... } @ inputs: {
nixosModules = {
system = import ./modules/system;
home = import ./modules/home;
@@ -28,67 +30,86 @@
nixosConfigurations = {
installerIso = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
{ nixpkgs.hostPlatform = "x86_64-linux"; }
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix"
./hosts/live-iso.nix
./modules/system
home-manager.nixosModules.home-manager
{
system.stateVersion = "24.11";
system.stateVersion = "25.11";
home-manager.extraSpecialArgs = { inherit inputs; };
services.displayManager.autoLogin.enable = true;
services.displayManager.autoLogin.user = "nixos";
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nixos = {
imports = [ ./modules/home ];
home.username = "nixos";
home.homeDirectory = "/home/nixos";
home.stateVersion = "25.11";
};
}
];
};
installerVm = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
{ nixpkgs.hostPlatform = "x86_64-linux"; }
./hosts/live-iso.nix
./modules/system
home-manager.nixosModules.home-manager
{
system.stateVersion = "24.11";
system.stateVersion = "25.11";
networking.hostName = "nomarchy-installer";
home-manager.extraSpecialArgs = { inherit inputs; };
# VM specific settings to start in terminal
services.displayManager.autoLogin.enable = true;
services.displayManager.autoLogin.user = "nixos";
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nixos = {
imports = [ ./modules/home ];
home.username = "nixos";
home.homeDirectory = "/home/nixos";
home.stateVersion = "25.11";
};
# VM specific settings to enable graphical boot
virtualisation.vmVariant = {
virtualisation.memorySize = 2048;
virtualisation.cores = 2;
virtualisation.graphics = true;
};
# Use a dummy hardware config
# Use a dummy hardware config for VM
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
boot.loader.grub.device = "/dev/vda";
# Setup a user that automatically logs in to console
# Ensure the user has the right groups for graphical environment
users.users.nixos = {
isNormalUser = true;
extraGroups = [ "wheel" "video" ];
extraGroups = [ "wheel" "video" "networkmanager" ];
initialPassword = "nixos";
};
services.getty.autologinUser = "nixos";
# Optionally, start the installer immediately
environment.interactiveShellInit = ''
if [[ "$(tty)" == "/dev/tty1" ]]; then
echo "Welcome to the Nomarchy Installer Test VM!"
echo "To start the installer, run: sudo /etc/install-nomarchy.sh"
fi
'';
}
];
};
vm = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
{ nixpkgs.hostPlatform = "x86_64-linux"; }
./modules/system
./modules/system/hardware.nix
home-manager.nixosModules.home-manager
{
system.stateVersion = "24.11";
system.stateVersion = "25.11";
networking.hostName = "nomarchy";
home-manager.extraSpecialArgs = { inherit inputs; };
# VM specific settings
@@ -118,7 +139,7 @@
imports = [ ./modules/home ];
home.username = "nomarchy";
home.homeDirectory = "/home/nomarchy";
home.stateVersion = "24.11";
home.stateVersion = "25.11";
};
}
];

View File

@@ -4,7 +4,14 @@
environment.systemPackages = with pkgs; [
git
gum
inputs.disko.packages.${pkgs.system}.disko
inputs.disko.packages.${pkgs.stdenv.hostPlatform.system}.disko
(pkgs.makeDesktopItem {
name = "install-nomarchy";
desktopName = "Install Nomarchy";
exec = "alacritty -e sudo /etc/install-nomarchy.sh";
terminal = false;
categories = [ "System" ];
})
];
environment.etc."install-nomarchy.sh" = {
@@ -19,4 +26,6 @@
environment.etc."disko-btrfs-luks.nix" = {
source = ../installer/disko-btrfs-luks.nix;
};
environment.etc."nomarchy".source = inputs.self;
}

View File

@@ -155,7 +155,7 @@ cat <<EOF > /mnt/etc/nixos/flake.nix
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nomarchy.url = "github:yourusername/nomarchy"; # UPDATE THIS to point to your repo
nomarchy.url = "path:./nomarchy"; # Offline bundled nomarchy
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
home-manager = {
@@ -206,7 +206,12 @@ cat <<EOF > /mnt/etc/nixos/flake.nix
}
EOF
# 7. Version Control
# 7. Copy Bundled Flake
echo "Copying bundled upstream Nomarchy flake..."
cp -rL /etc/nomarchy /mnt/etc/nixos/nomarchy
chmod -R u+w /mnt/etc/nixos/nomarchy
# 8. Version Control
cd /mnt/etc/nixos/
git init
git add .
@@ -214,5 +219,5 @@ git config user.name "Nomarchy Installer"
git config user.email "installer@nomarchy"
git commit -m "Initial Nomarchy generation"
# 8. Execution
# 9. Execution
nixos-install --flake /mnt/etc/nixos#default --no-root-passwd

View File

@@ -0,0 +1,33 @@
{ config, pkgs, ... }:
{
programs.alacritty = {
enable = true;
settings = {
general.import = [ "~/.config/nomarchy/current/theme/alacritty.toml" ];
env = {
TERM = "xterm-256color";
};
terminal = {
osc52 = "CopyPaste";
};
font = {
normal = { family = config.nomarchy.fonts.monospace; style = "Regular"; };
bold = { family = config.nomarchy.fonts.monospace; style = "Bold"; };
italic = { family = config.nomarchy.fonts.monospace; style = "Italic"; };
size = 9;
};
window = {
padding = { x = 14; y = 14; };
decorations = "None";
};
keyboard = {
bindings = [
{ key = "Insert"; mods = "Shift"; action = "Paste"; }
{ key = "Insert"; mods = "Control"; action = "Copy"; }
{ key = "Return"; mods = "Shift"; chars = "\\u001B\\r"; }
];
};
};
};
}

View File

@@ -2,7 +2,6 @@
{
xdg.configFile = {
"alacritty".source = ../../config/alacritty;
"btop".source = ../../config/btop;
"chromium".source = ../../config/chromium;
"fastfetch".source = ../../config/fastfetch;

View File

@@ -7,12 +7,23 @@ let
activeThemeName = if builtins.pathExists stateFile then
lib.removeSuffix "\n" (builtins.readFile stateFile)
else "dracula";
userPackagesFile = "${config.home.homeDirectory}/.config/home-manager/user-packages.json";
userPackages = if builtins.pathExists userPackagesFile then
let
pkgNames = builtins.fromJSON (builtins.readFile userPackagesFile);
# Filter to only packages that exist in pkgs to prevent build failures
validPkgs = builtins.filter (name: builtins.hasAttr name pkgs) pkgNames;
in builtins.map (name: pkgs.${name}) validPkgs
else [];
in
{
imports = [
inputs.nix-colors.homeManagerModules.default
inputs.walker.homeManagerModules.default
./fonts.nix
./alacritty.nix
./nightlight.nix
./idle.nix
./stylix.nix
./hyprland.nix
./waybar.nix
@@ -25,8 +36,25 @@ in
colorScheme = palettes.${activeThemeName} or palettes.dracula;
home.packages = with pkgs; [
alacritty
];
firefox
thunar
imv
mpv
neovim
wl-clipboard
grim
slurp
brightnessctl
playerctl
pamixer
mise
jq
xmlstarlet
nerd-fonts.jetbrains-mono
nerd-fonts.roboto-mono
nerd-fonts.fira-code
nerd-fonts.ubuntu-mono
] ++ userPackages;
home.shellAliases = {
sys-update = "sudo nixos-rebuild switch --flake /etc/nixos#default";

View File

@@ -1,9 +1,11 @@
{ config, pkgs, lib, ... }:
let
stateFile = "${config.home.homeDirectory}/.config/home-manager/font-state.nix";
activeFont = if builtins.pathExists stateFile then
lib.removeSuffix "\n" (builtins.readFile stateFile)
# Standardize state files to a common directory
stateDir = "${config.home.homeDirectory}/.config/home-manager";
fontStateFile = "${stateDir}/font-state.nix";
activeFont = if builtins.pathExists fontStateFile then
lib.removeSuffix "\n" (builtins.readFile fontStateFile)
else "JetBrainsMono Nerd Font";
in
{
@@ -14,4 +16,9 @@ in
description = "Monospace font for the system";
};
};
config = {
fonts.fontconfig.enable = true;
xdg.dataFile."fonts/nomarchy.ttf".source = ../../config/nomarchy.ttf;
};
}

View File

@@ -5,20 +5,30 @@ let
activeWallpaper = if builtins.pathExists wallpaperStateFile then
lib.removeSuffix "\n" (builtins.readFile wallpaperStateFile)
else "";
hyprlandStateFile = "${config.home.homeDirectory}/.config/home-manager/hyprland-state.json";
hyprlandState = if builtins.pathExists hyprlandStateFile then
builtins.fromJSON (builtins.readFile hyprlandStateFile)
else { gaps_out = 10; gaps_in = 5; border_size = 2; };
in
{
wayland.windowManager.hyprland = {
enable = true;
settings = {
"general" = {
"gaps_in" = hyprlandState.gaps_in;
"gaps_out" = hyprlandState.gaps_out;
"border_size" = hyprlandState.border_size;
"col.active_border" = "rgb(${config.colorScheme.palette.base0E})";
"col.inactive_border" = "rgb(${config.colorScheme.palette.base03})";
};
"exec-once" = [
"swww init && swww fill ${activeWallpaper}"
"swww-daemon & sleep 0.5 && swww img ${activeWallpaper} --transition-type none"
"waybar"
"nomarchy-on-boot"
"nomarchy-welcome"
];
"bind" = [
"SUPER, Space, exec, walker"
"SUPER ALT, Space, exec, nomarchy-theme-selector"
"SUPER CTRL, Space, exec, nomarchy-font-selector"
"SUPER SHIFT, Space, exec, nomarchy-wallpaper-selector"

13
modules/home/idle.nix Normal file
View File

@@ -0,0 +1,13 @@
{ config, pkgs, ... }:
let
stateFile = "${config.home.homeDirectory}/.config/home-manager/idle-state.json";
idleState = if builtins.pathExists stateFile then
builtins.fromJSON (builtins.readFile stateFile)
else { enabled = true; };
in
{
services.hypridle = {
enable = idleState.enabled;
};
}

View File

@@ -0,0 +1,14 @@
{ config, pkgs, ... }:
let
stateFile = "${config.home.homeDirectory}/.config/home-manager/hyprsunset-state.json";
hyprsunsetState = if builtins.pathExists stateFile then
builtins.fromJSON (builtins.readFile stateFile)
else { enabled = false; temperature = 4000; };
in
{
services.hyprsunset = {
enable = true; # Always enabled, we control via IPC and state
temperature = if hyprsunsetState.enabled then hyprsunsetState.temperature else 6500;
};
}

View File

@@ -15,6 +15,12 @@ let
jq
swww
xmlstarlet
wl-clipboard
grim
slurp
brightnessctl
playerctl
pamixer
# Add any others commonly used in bin/
];

5
modules/home/swayosd.nix Normal file
View File

@@ -0,0 +1,5 @@
{ config, pkgs, ... }:
{
services.swayosd.enable = true;
}

View File

@@ -9,7 +9,13 @@ let
STATE_DIR="$HOME/.config/home-manager"
THEME_STATE_FILE="$STATE_DIR/theme-state.nix"
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
THEMES_DIR="/etc/nixos/themes" # This depends on where the repo is cloned
if [ -d "/etc/nixos/nomarchy/themes" ]; then
THEMES_DIR="/etc/nixos/nomarchy/themes"
elif [ -d "/etc/nomarchy/themes" ]; then
THEMES_DIR="/etc/nomarchy/themes"
else
THEMES_DIR="/etc/nixos/themes"
fi # This depends on where the repo is cloned
mkdir -p "$STATE_DIR"
@@ -24,6 +30,7 @@ let
BG=$(ls "$BG_DIR" | head -n 1)
if [ -n "$BG" ]; then
echo "$BG_DIR/$BG" > "$WALLPAPER_STATE_FILE"
swww img "$BG_DIR/$BG" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90 &
fi
fi
@@ -48,7 +55,13 @@ let
nomarchy-wallpaper-selector = pkgs.writeShellScriptBin "nomarchy-wallpaper-selector" ''
STATE_DIR="$HOME/.config/home-manager"
WALLPAPER_STATE_FILE="$STATE_DIR/wallpaper-state.nix"
if [ -d "/etc/nixos/nomarchy/themes" ]; then
THEMES_DIR="/etc/nixos/nomarchy/themes"
elif [ -d "/etc/nomarchy/themes" ]; then
THEMES_DIR="/etc/nomarchy/themes"
else
THEMES_DIR="/etc/nixos/themes"
fi
mkdir -p "$STATE_DIR"
@@ -58,6 +71,7 @@ let
if [ -n "$SELECTED_WP" ]; then
echo "$SELECTED_WP" > "$WALLPAPER_STATE_FILE"
swww img "$SELECTED_WP" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90 &
env-update
fi
'';

14
modules/home/vscode.nix Normal file
View File

@@ -0,0 +1,14 @@
{ config, pkgs, ... }:
{
programs.vscode = {
enable = true;
package = pkgs.vscode;
userSettings = {
"update.mode" = "none";
"workbench.colorTheme" = "Nomarchy Theme"; # Example, would need to be generated
"window.titleBarStyle" = "custom";
};
# extensions = with pkgs.vscode-extensions; [ ... ];
};
}

68
modules/options.nix Normal file
View File

@@ -0,0 +1,68 @@
{ config, lib, pkgs, ... }:
with lib;
{
options.nomarchy = {
# System-level options
system = {
enable = mkEnableOption "Nomarchy core system features";
# Allow users to add extra system packages
extraPackages = mkOption {
type = types.listOf types.package;
default = [];
description = "Additional system-wide packages to install";
};
# Allow overriding system defaults
hostname = mkOption {
type = types.str;
default = "nomarchy";
description = "The system hostname";
};
# Allow user to inject their own NixOS modules
extraModules = mkOption {
type = types.listOf types.deferredModule;
default = [];
description = "Extra NixOS modules to include";
};
};
# Home-level options
home = {
enable = mkEnableOption "Nomarchy home environment features";
# Allow users to add extra user packages
extraPackages = mkOption {
type = types.listOf types.package;
default = [];
description = "Additional user-level packages to install";
};
# Configuration for the environment
terminal = mkOption {
type = types.enum [ "alacritty" "kitty" "ghostty" ];
default = "alacritty";
description = "Preferred terminal emulator";
};
# Allow user to inject their own Home Manager modules
extraModules = mkOption {
type = types.listOf types.deferredModule;
default = [];
description = "Extra Home Manager modules to include";
};
# Theming overrides
themeOverride = mkOption {
type = types.nullOr types.str;
default = null;
description = "Force a specific theme (ignoring state files)";
};
};
# Hardware flags (already exists in hardware.nix, but good to keep in mind)
};
}

12
modules/system/audio.nix Normal file
View File

@@ -0,0 +1,12 @@
{ config, pkgs, ... }:
{
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
jack.enable = true;
};
}

View File

@@ -0,0 +1,7 @@
{ config, pkgs, ... }:
{
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
}

View File

@@ -1,9 +1,13 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
./plymouth.nix
./sddm.nix
./hardware.nix
./audio.nix
./bluetooth.nix
./network.nix
./impermanence.nix
];
}

View File

@@ -0,0 +1,58 @@
{ config, lib, pkgs, inputs, ... }:
let
cfg = config.nomarchy.system.impermanence;
in
{
imports = [
inputs.impermanence.nixosModules.impermanence
];
options.nomarchy.system.impermanence = {
enable = lib.mkEnableOption "Erase Your Darlings (Impermanence) root wipe on boot";
};
config = lib.mkIf cfg.enable {
# 1. The Rollback Script: Runs in initrd before filesystems are mounted
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir -p /btrfs_tmp
mount -o subvol=/ /dev/mapper/crypted /btrfs_tmp
if [[ -e /btrfs_tmp/@ ]]; then
mkdir -p /btrfs_tmp/old_roots
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/@)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/@ "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
delete_subvolume_recursively "$i"
done
btrfs subvolume snapshot /btrfs_tmp/root-blank /btrfs_tmp/@
umount /btrfs_tmp
'';
# 2. Persistence Configuration: What survives the wipe
environment.persistence."/persist" = {
hideMounts = true;
directories = [
"/var/log"
"/var/lib/nixos"
"/var/lib/systemd/coredump"
"/var/lib/bluetooth"
"/etc/NetworkManager/system-connections"
];
files = [
"/etc/machine-id"
];
};
};
}

View File

@@ -0,0 +1,5 @@
{ config, pkgs, ... }:
{
networking.networkmanager.enable = true;
}

View File

@@ -0,0 +1,6 @@
{ config, pkgs, ... }:
{
services.supergfxd.enable = true;
# NixOS handles the configuration of supergfxd
}

View File

@@ -1,46 +1,43 @@
{
dracula = {
name = "dracula";
author = "dracula";
let
themesDir = ./.;
# Get all directories in the themes folder that have a colors.toml file
directories = builtins.attrNames (
builtins.filterAttrs (name: type: type == "directory" && builtins.pathExists (themesDir + "/${name}/colors.toml")) (builtins.readDir themesDir)
);
readTheme = name:
let
toml = builtins.fromTOML (builtins.readFile (themesDir + "/${name}/colors.toml"));
# Helper to strip '#' from color codes
stripHash = s: builtins.replaceStrings ["#"] [""] s;
in {
inherit name;
author = "nomarchy";
palette = {
base00 = "282a36";
base01 = "3a3c4e";
base02 = "4d4f68";
base03 = "6272a4";
base04 = "62d6e8";
base05 = "e9e9f4";
base06 = "f1f2f8";
base07 = "f8f8f2";
base08 = "ff5555";
base09 = "ffb86c";
base0A = "f1fa8c";
base0B = "50fa7b";
base0C = "8be9fd";
base0D = "bd93f9";
base0E = "ff79c6";
base0F = "bd93f9";
base00 = stripHash toml.background;
base01 = stripHash toml.color0;
base02 = stripHash toml.color8;
base03 = stripHash toml.color8;
base04 = stripHash toml.color7;
base05 = stripHash toml.foreground;
base06 = stripHash toml.color15;
base07 = stripHash toml.color15;
base08 = stripHash toml.color1;
base09 = stripHash toml.color3;
base0A = stripHash toml.color3;
base0B = stripHash toml.color2;
base0C = stripHash toml.color6;
base0D = stripHash toml.color4;
base0E = stripHash toml.color5;
base0F = stripHash toml.color1;
};
};
nord = {
name = "nord";
author = "arcticicestudio";
palette = {
base00 = "2e3440";
base01 = "3b4252";
base02 = "434c5e";
base03 = "4c566a";
base04 = "d8dee9";
base05 = "e5e9f0";
base06 = "eceff4";
base07 = "8fbcbb";
base08 = "88c0d0";
base09 = "81a1c1";
base0A = "5e81ac";
base0B = "bf616a";
base0C = "d08770";
base0D = "ebcb8b";
base0E = "a3be8c";
base0F = "b48ead";
};
};
}
in
builtins.listToAttrs (map (name: {
inherit name;
value = readTheme name;
}) directories)