Compare commits
106 Commits
877da19770
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72f7e7b93d | ||
|
|
20de3d4f97 | ||
|
|
2a301a049f | ||
| bd7e5a5706 | |||
|
|
af8fa321ff | ||
|
|
6238f41e43 | ||
|
|
fb4d5d7acc | ||
|
|
99a6c7d547 | ||
|
|
85ef8745d7 | ||
|
|
b82954a7b5 | ||
|
|
66c98949ab | ||
| 07e2d5c51c | |||
| 2529ca114f | |||
| 94927952db | |||
| 0930458418 | |||
|
|
95101fda3f | ||
|
|
6e0d17b859 | ||
|
|
27d1506b54 | ||
|
|
90f07ae75c | ||
|
|
bfd95cb40b | ||
|
|
9283403d8f | ||
|
|
7bf4c3c637 | ||
|
|
ec6046793e | ||
|
|
2b6d452509 | ||
|
|
ac846f4b03 | ||
|
|
03968e5d0d | ||
|
|
d264371b46 | ||
|
|
9c672953bc | ||
|
|
7fa909ddf4 | ||
|
|
5ddb15ffef | ||
|
|
46738c3663 | ||
|
|
9be4363f4b | ||
|
|
f93eb7435f | ||
|
|
6b2c678669 | ||
|
|
ac4d66e54d | ||
|
|
098cd42ac8 | ||
|
|
158ae308cc | ||
|
|
c1895eefd4 | ||
|
|
74e2dc34e3 | ||
|
|
3510a51492 | ||
|
|
7064108ce7 | ||
|
|
bef7be01b8 | ||
|
|
d4f50afc62 | ||
|
|
2f18d4efcf | ||
|
|
329dc009b6 | ||
|
|
0af1395df2 | ||
|
|
f2b99e0f75 | ||
|
|
6411395d9f | ||
|
|
39b1a9c1b3 | ||
|
|
c5544e56c8 | ||
|
|
0306dff092 | ||
|
|
3b977f181d | ||
|
|
61cd993e54 | ||
|
|
1e9481849b | ||
|
|
27f5663cdf | ||
|
|
28cc41abdd | ||
|
|
5fc9f5ee34 | ||
|
|
5c5b377bd6 | ||
|
|
4b99fa3846 | ||
|
|
a741b0936c | ||
|
|
f318585dc4 | ||
|
|
386da51178 | ||
|
|
d06ef86bb9 | ||
|
|
3aadc36bff | ||
|
|
55f0653e59 | ||
|
|
dd48411013 | ||
|
|
c66f0b19cd | ||
|
|
6de8ecd093 | ||
|
|
21230a05eb | ||
|
|
4b2f16c2f0 | ||
|
|
21ee9c6035 | ||
|
|
8266dc7ee2 | ||
|
|
16ed8f1df1 | ||
|
|
e9c9342965 | ||
|
|
5b014cfa29 | ||
|
|
034da701a3 | ||
|
|
7086a6f29c | ||
|
|
1545e63c7d | ||
|
|
f965f0be2c | ||
|
|
fb22e390e8 | ||
|
|
074dc3576c | ||
|
|
0728da4374 | ||
|
|
983ade0f55 | ||
|
|
d2b508485a | ||
|
|
cc93491232 | ||
|
|
aa20399210 | ||
|
|
86bc0e570b | ||
|
|
bf30cd07d8 | ||
|
|
c9ff6f26f3 | ||
|
|
133ef9ddfc | ||
|
|
f09bfbc4e7 | ||
|
|
2950dd171e | ||
|
|
6ef28f022b | ||
|
|
3cb012bcba | ||
|
|
e438004cec | ||
|
|
a7e7fa9562 | ||
|
|
7fd0f78d7c | ||
|
|
6203413425 | ||
|
|
4ddc91b930 | ||
|
|
220fc7f699 | ||
|
|
f0bd25f902 | ||
|
|
955269f9a2 | ||
|
|
bb435a47bb | ||
|
|
e66537523a | ||
|
|
04512eabcd | ||
|
|
528447cc19 |
102
.forgejo/workflows/check.yml
Normal file
102
.forgejo/workflows/check.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
# Nomarchy CI — eval + lint.
|
||||
#
|
||||
# Catches the regressions that hurt today:
|
||||
# 1. Flake stops evaluating (broken option ref, missing import, etc.).
|
||||
# 2. A `nomarchy-*` shell script has a syntax error or a shellcheck
|
||||
# error-severity issue.
|
||||
# 3. `docs/SCRIPTS.md` drifts from the repo state because somebody
|
||||
# added / removed / renamed a script and didn't run the generator
|
||||
# (the pre-commit hook handles this, but only when enabled per-clone).
|
||||
#
|
||||
# Doesn't build ISOs — that needs a binary cache. Add a separate job
|
||||
# once Cachix/Attic is in place.
|
||||
|
||||
name: Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
eval-and-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
# Match the runner's effective channel. Nomarchy itself tracks
|
||||
# nixos-25.11 via flake.nix; the installer-action default is fine.
|
||||
extra-conf: |
|
||||
experimental-features = nix-command flakes
|
||||
|
||||
- name: nix flake check --no-build
|
||||
run: nix flake check --no-build
|
||||
|
||||
- name: Lint nomarchy-* scripts (bash -n + shellcheck)
|
||||
run: |
|
||||
# Mirror what .githooks/pre-commit runs locally, but across the
|
||||
# whole tree instead of just changed files. Pre-commit gates
|
||||
# individual commits; CI gates branches (including --no-verify
|
||||
# bypasses).
|
||||
set -e
|
||||
fail=0
|
||||
while IFS= read -r script; do
|
||||
[[ -f "$script" ]] || continue
|
||||
# Python helpers ship under the same nomarchy- prefix
|
||||
# (e.g. nomarchy-haptic-touchpad). Skip non-bash.
|
||||
head -1 "$script" | grep -qE '^#!.*\bbash\b' || continue
|
||||
if ! bash -n "$script"; then
|
||||
echo "::error file=$script::bash syntax error"
|
||||
fail=1
|
||||
fi
|
||||
if ! nix shell nixpkgs#shellcheck --command shellcheck \
|
||||
--severity=error --shell=bash "$script"; then
|
||||
echo "::error file=$script::shellcheck error-severity issue"
|
||||
fail=1
|
||||
fi
|
||||
done < <(find features/scripts/utils core/system/scripts \
|
||||
themes/engine/scripts \
|
||||
-maxdepth 1 -type f -name 'nomarchy-*')
|
||||
exit "$fail"
|
||||
|
||||
- name: docs/SCRIPTS.md is up to date
|
||||
run: |
|
||||
# Regenerate to a temp file and compare. If different, the
|
||||
# contributor forgot to run the generator (or skipped the
|
||||
# pre-commit hook). Fail loudly and tell them the fix.
|
||||
./bin/utils/nomarchy-docs-scripts --out /tmp/SCRIPTS.regen.md
|
||||
if ! diff -q docs/SCRIPTS.md /tmp/SCRIPTS.regen.md >/dev/null; then
|
||||
echo "::error::docs/SCRIPTS.md is stale."
|
||||
echo "Run: ./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md"
|
||||
echo "Then commit the regenerated file."
|
||||
echo "--- diff ---"
|
||||
diff -u docs/SCRIPTS.md /tmp/SCRIPTS.regen.md || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: installer/hardware-db.sh references real nixos-hardware modules
|
||||
run: |
|
||||
# Every 4th-pipe-field in HARDWARE_DB is a nixos-hardware module
|
||||
# name. Half the DB used to point at modules that don't exist
|
||||
# (e.g. microsoft-surface-pro-8 — there's only -pro-intel and
|
||||
# -pro-9), which made the install fail at eval time with
|
||||
# cryptic "attribute not found" errors on real laptops. This
|
||||
# step catches that regression class.
|
||||
awk -F'|' '/^ "/ { gsub(/"/,"",$4); gsub(/^[[:space:]]+|[[:space:]]+$/,"",$4); if ($4) print $4 }' \
|
||||
installer/hardware-db.sh | sort -u > /tmp/db-refs.txt
|
||||
nix eval --impure --json --expr '
|
||||
let
|
||||
nh = (builtins.getFlake (toString ./.)).inputs.nixos-hardware.nixosModules;
|
||||
in builtins.attrNames nh' \
|
||||
| nix shell nixpkgs#jq --command jq -r '.[]' | sort -u > /tmp/db-real.txt
|
||||
missing=$(comm -23 /tmp/db-refs.txt /tmp/db-real.txt)
|
||||
if [[ -n "$missing" ]]; then
|
||||
echo "::error::hardware-db.sh references nixos-hardware modules that don't exist:"
|
||||
printf ' - %s\n' $missing
|
||||
echo "Either fix the name (check the actual attr in nixos-hardware) or drop the row."
|
||||
exit 1
|
||||
fi
|
||||
54
.githooks/pre-commit
Executable file
54
.githooks/pre-commit
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# Nomarchy pre-commit hook.
|
||||
#
|
||||
# Enable per-clone with:
|
||||
# git config core.hooksPath .githooks
|
||||
#
|
||||
# Two responsibilities:
|
||||
# 1. Lint changed nomarchy-* scripts (bash -n + shellcheck if available)
|
||||
# so syntax errors and unquoted-var bugs don't ship.
|
||||
# 2. Regenerate docs/SCRIPTS.md when any nomarchy-* script under the three
|
||||
# script directories is added, modified, or deleted in this commit, and
|
||||
# stage the refreshed file so it lands with the change.
|
||||
|
||||
set -e
|
||||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
cd "$repo_root"
|
||||
|
||||
script_dirs_re='^(features/scripts/utils|core/system/scripts|themes/engine/scripts)/nomarchy-'
|
||||
|
||||
# 1. Lint changed scripts. bash -n catches syntax errors (always fatal).
|
||||
# shellcheck catches unquoted-var, use-before-define, missing-shebang, etc.
|
||||
# We only fail on severity=error so the long tail of pre-existing warnings
|
||||
# (info / style / warning) doesn't block commits — those can be cleaned up
|
||||
# incrementally without a flag day.
|
||||
changed_scripts=$(git diff --cached --name-only --diff-filter=ACMR \
|
||||
| grep -E "$script_dirs_re" || true)
|
||||
if [[ -n "$changed_scripts" ]]; then
|
||||
while IFS= read -r script; do
|
||||
[[ -f "$script" ]] || continue
|
||||
# Only lint scripts with a bash shebang. nomarchy-* is a name
|
||||
# convention, not a language guarantee — at least one Python helper
|
||||
# ships under the same prefix (nomarchy-haptic-touchpad).
|
||||
head -1 "$script" | grep -qE '^#!.*\bbash\b' || continue
|
||||
if ! bash -n "$script"; then
|
||||
echo "pre-commit: bash syntax error in $script — aborting commit." >&2
|
||||
exit 1
|
||||
fi
|
||||
if command -v shellcheck >/dev/null 2>&1; then
|
||||
if ! shellcheck --severity=error --shell=bash "$script"; then
|
||||
echo "pre-commit: shellcheck found error-level issues in $script — aborting commit." >&2
|
||||
echo "pre-commit: fix the reported issues, or rerun with --no-verify after a deliberate decision to ship." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done <<< "$changed_scripts"
|
||||
fi
|
||||
|
||||
# 2. Regenerate the script audit doc.
|
||||
if git diff --cached --name-only --diff-filter=ACMRD | grep -qE "$script_dirs_re"; then
|
||||
echo "pre-commit: regenerating docs/SCRIPTS.md (script change detected)…"
|
||||
./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
git add docs/SCRIPTS.md
|
||||
fi
|
||||
16
README.md
16
README.md
@@ -1,6 +1,6 @@
|
||||
# 👑 Nomarchy
|
||||
|
||||
**Nomarchy** is a professional-grade NixOS distribution that replicates the Omarchy Wayland workflow with a strictly declarative, flake-based architecture. It provides a highly polished, "it just works" experience for power users who want a beautiful Hyprland environment without sacrificing the reliability of NixOS.
|
||||
**Nomarchy** is a professional-grade NixOS distribution that ships a highly curated Hyprland desktop on a strictly declarative, flake-based foundation. It provides a highly polished, "it just works" experience for power users who want a beautiful Wayland environment without sacrificing the reliability of NixOS.
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
@@ -40,7 +40,8 @@ This builds a full graphical VM of the installer environment. Once inside, click
|
||||
### 2. Build the Installer ISO
|
||||
To install on physical hardware, generate your own bootable image:
|
||||
```bash
|
||||
nix build .#nixosConfigurations.installerIso.config.system.build.isoImage
|
||||
./features/scripts/utils/nomarchy-build-iso # Minimal TTY installer
|
||||
./features/scripts/utils/nomarchy-build-live-iso # Graphical try-before-install
|
||||
```
|
||||
The ISO will be located at `./result/iso/nixos-*.iso`. Flash it to a USB drive and boot.
|
||||
|
||||
@@ -55,6 +56,9 @@ The wizard will guide you through:
|
||||
- **Storage:** Choice between Standard Ext4 or Encrypted BTRFS with optional **Impermanence**.
|
||||
- **Localization:** Searchable timezones and keyboard layout selection.
|
||||
|
||||
### Already on NixOS?
|
||||
Layer Nomarchy onto an existing 25.11 install without reformatting — see the [Migration Guide](docs/MIGRATION.md).
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Configuration & Usage
|
||||
@@ -80,6 +84,8 @@ Add user-level packages, aliases, and dotfiles here.
|
||||
nomarchy.home.terminal = "kitty";
|
||||
```
|
||||
|
||||
For the full list of `nomarchy.*` options you can set in `system.nix` and `home.nix`, see the [Options Reference](docs/OPTIONS.md). Hit a rebuild error? Check [Troubleshooting](docs/TROUBLESHOOTING.md). For where the project is heading next, see the [Roadmap](docs/ROADMAP.md).
|
||||
|
||||
### Applying Changes
|
||||
After editing your files, apply them instantly. **IMPORTANT:** Nomarchy requires the `--impure` flag for evaluation. You **MUST** use the following aliases rather than standard NixOS commands:
|
||||
|
||||
@@ -92,12 +98,12 @@ env-update # Reloads your Home Manager environment (Runs: home-manager switch -
|
||||
|
||||
## 🚀 Commands & Keybindings
|
||||
|
||||
The full list lives in [`docs/KEYBINDINGS.md`](docs/KEYBINDINGS.md) (auto-generated from the Hyprland configs). A few highlights:
|
||||
|
||||
| Keybinding | Action |
|
||||
| :--- | :--- |
|
||||
| `Super + Space` | **App Launcher** (Walker) |
|
||||
| `Super + Shift + Space` | **Nomarchy Menu** (Walker) |
|
||||
| `Super + Ctrl + Space` | **Background Selector** (Walker) |
|
||||
| `Super + Shift + Ctrl + Space` | **Theme Selector** (Walker) |
|
||||
| `Super + Alt + Space` | **Toggle Top Bar** (Waybar) |
|
||||
| `Super + Return` | Open Terminal |
|
||||
| `Super + Q` | Close Window |
|
||||
@@ -109,4 +115,4 @@ Nomarchy includes dozens of productivity scripts available in your PATH. Some hi
|
||||
- `nomarchy-menu`: The central hub for all utilities and pickers.
|
||||
|
||||
---
|
||||
*Built with ❤️ using NixOS, Hyprland, Stylix, and the spirit of Omarchy.*
|
||||
*Built with ❤️ using NixOS, Hyprland, Stylix, and the Nomarchy Community.*
|
||||
|
||||
30
TODO.md
30
TODO.md
@@ -1,30 +0,0 @@
|
||||
# Nomarchy Distribution - TODO List
|
||||
|
||||
## 1. Professional Installer [IN PROGRESS]
|
||||
- [x] Refactor with `gum` for stylized UI.
|
||||
- [x] Add clear section headers and environment checks.
|
||||
- [ ] Implement software profile selection.
|
||||
- [x] Add "Pre-flight Check" summary screen showing all selected options (disk, user, profiles) before proceeding.
|
||||
- [x] Implement post-install "Success" dashboard with next steps.
|
||||
- [ ] Improve disk selection to show more metadata (vendor, model, serial).
|
||||
|
||||
## 2. Nomarchy Plymouth Theme [DONE]
|
||||
- [x] Create custom theme assets in `assets/plymouth/`.
|
||||
- [x] Center official logo on splash screen.
|
||||
- [x] Declarative integration in `modules/system/plymouth.nix`.
|
||||
- [x] Implement full LUKS password entry support (password prompt, bullet indicators).
|
||||
- [x] Add smooth fade-in/fade-out animations for the logo.
|
||||
- [x] Add system message display (e.g., "Rebooting...", "Checking Disk...").
|
||||
|
||||
## 3. System Branding (Fastfetch & Terminal) [DONE]
|
||||
- [x] Restore and optimize official ASCII logo (`logo.txt`).
|
||||
- [x] Update `config/fastfetch/config.jsonc` to use new logo and declarative stats.
|
||||
- [x] Update `nomarchy-show-logo` to use centralized branding path.
|
||||
- [x] Declaratively map all branding assets via Home Manager.
|
||||
|
||||
## 4. Repo Hygiene & Consistency [DONE]
|
||||
- [x] Remove legacy Arch Linux imperative scripts.
|
||||
- [x] Move all dynamic state to unified `state.json`.
|
||||
- [x] Implement professional state migration via Home Manager activation.
|
||||
- [x] Declaratively link all `config/` directories with `recursive = true`.
|
||||
- [x] Transition to Remote-First Upstream model.
|
||||
109
bin/utils/nomarchy-docs-keybindings
Executable file
109
bin/utils/nomarchy-docs-keybindings
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# nomarchy-docs-keybindings
|
||||
#
|
||||
# Regenerates docs/KEYBINDINGS.md from the Hyprland binding files. Run from the
|
||||
# repo root or anywhere — paths are resolved relative to this script.
|
||||
#
|
||||
# nomarchy-docs-keybindings # write to stdout
|
||||
# nomarchy-docs-keybindings --out docs/KEYBINDINGS.md
|
||||
#
|
||||
# Source files in render order. Each entry is "<repo-relative path>|<title>".
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
sources=(
|
||||
"core/home/config/nomarchy/default/hypr/bindings/utilities.conf|Utilities"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf|Tiling"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/clipboard.conf|Clipboard"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/media.conf|Media keys"
|
||||
"features/desktop/hyprland/config/bindings.conf|Apps & web shortcuts"
|
||||
)
|
||||
|
||||
prettify_key() {
|
||||
case "$1" in
|
||||
code:10) echo "1" ;; code:11) echo "2" ;; code:12) echo "3" ;;
|
||||
code:13) echo "4" ;; code:14) echo "5" ;; code:15) echo "6" ;;
|
||||
code:16) echo "7" ;; code:17) echo "8" ;; code:18) echo "9" ;;
|
||||
code:19) echo "0" ;;
|
||||
XF86AudioRaiseVolume) echo "Volume Up" ;;
|
||||
XF86AudioLowerVolume) echo "Volume Down" ;;
|
||||
XF86AudioMute) echo "Mute" ;;
|
||||
XF86AudioMicMute) echo "Mic Mute" ;;
|
||||
XF86AudioPlay) echo "Play/Pause" ;;
|
||||
XF86AudioStop) echo "Stop" ;;
|
||||
XF86AudioNext) echo "Next Track" ;;
|
||||
XF86AudioPrev) echo "Previous Track" ;;
|
||||
XF86MonBrightnessUp) echo "Brightness Up" ;;
|
||||
XF86MonBrightnessDown) echo "Brightness Down" ;;
|
||||
XF86KbdBrightnessUp) echo "Kbd Brightness Up" ;;
|
||||
XF86KbdBrightnessDown) echo "Kbd Brightness Down" ;;
|
||||
XF86KbdLightOnOff) echo "Kbd Backlight" ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
trim() { sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//'; }
|
||||
|
||||
render_section() {
|
||||
local file="$1" title="$2"
|
||||
[[ ! -f "$repo_root/$file" ]] && return
|
||||
local rows
|
||||
rows=$(grep -E '^[[:space:]]*bind[a-z]*[[:space:]]*=' "$repo_root/$file" || true)
|
||||
[[ -z "$rows" ]] && return
|
||||
|
||||
local body=""
|
||||
while IFS= read -r line; do
|
||||
# Strip the "bindXXX =" prefix.
|
||||
local rhs="${line#*=}"
|
||||
local mods key desc
|
||||
IFS=',' read -r mods key desc _ <<<"$rhs"
|
||||
mods=$(printf '%s' "${mods:-}" | trim)
|
||||
key=$(printf '%s' "${key:-}" | trim)
|
||||
desc=$(printf '%s' "${desc:-}" | trim)
|
||||
[[ -z "$desc" ]] && continue # skip non-descriptive bindings
|
||||
[[ -z "$mods" ]] && mods="—"
|
||||
key=$(prettify_key "$key")
|
||||
body+=$(printf '| %s | %s | %s |\n' "$mods" "$key" "$desc")
|
||||
body+=$'\n'
|
||||
done <<<"$rows"
|
||||
|
||||
[[ -z "$body" ]] && return
|
||||
|
||||
printf '\n## %s\n\n' "$title"
|
||||
printf '_Source: `%s`_\n\n' "$file"
|
||||
printf '| Modifiers | Key | Action |\n'
|
||||
printf '| --- | --- | --- |\n'
|
||||
printf '%s' "$body"
|
||||
}
|
||||
|
||||
main() {
|
||||
cat <<'HEADER'
|
||||
# Nomarchy Keybindings
|
||||
|
||||
Auto-generated from the Hyprland binding files. **Do not edit by hand.**
|
||||
Re-run the generator after changing any `bindings/*.conf`:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-keybindings --out docs/KEYBINDINGS.md
|
||||
```
|
||||
|
||||
`SUPER` is the Meta / Win key. `code:NN` keys (X11 digit keycodes) are
|
||||
shown as the digit they correspond to. Media keys (`XF86Audio*`,
|
||||
`XF86MonBrightness*`, …) are prettified.
|
||||
HEADER
|
||||
for entry in "${sources[@]}"; do
|
||||
render_section "${entry%|*}" "${entry#*|}"
|
||||
done
|
||||
}
|
||||
|
||||
out=""
|
||||
if [[ "${1:-}" == "--out" ]]; then
|
||||
out="${2:?--out needs a path}"; shift 2
|
||||
fi
|
||||
if [[ -n "$out" ]]; then
|
||||
main >"$out"
|
||||
else
|
||||
main
|
||||
fi
|
||||
276
bin/utils/nomarchy-docs-scripts
Executable file
276
bin/utils/nomarchy-docs-scripts
Executable file
@@ -0,0 +1,276 @@
|
||||
#!/usr/bin/env bash
|
||||
# Generator tolerates "no matches" exit codes from grep | sort.
|
||||
# pipefail and -e off; -u stays.
|
||||
set -u
|
||||
|
||||
# nomarchy-docs-scripts
|
||||
#
|
||||
# Regenerates docs/SCRIPTS.md from the repo state. Produces:
|
||||
# 1. Header + status legend + regen instructions.
|
||||
# 2. Table of every nomarchy-* script (location, callers, status).
|
||||
# 3. Table of every menu entry in features/scripts/utils/nomarchy-menu
|
||||
# (submenu, label, target command, status).
|
||||
# 4. Snapshot list of orphaned references (called somewhere, no script).
|
||||
#
|
||||
# Status heuristic in Phase A:
|
||||
# kept — file exists AND is called from at least one *.nix / *.conf /
|
||||
# shell file outside its own directory.
|
||||
# unused? — file exists but no caller found. Phase B decides delete-dead
|
||||
# vs intentional public API.
|
||||
# missing — referenced but no file. Phase B decides port-from-omarchy
|
||||
# vs delete-dead vs stub-with-notify.
|
||||
#
|
||||
# nomarchy-docs-scripts # write to stdout
|
||||
# nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
cd "$repo_root"
|
||||
|
||||
# --- Inventory -------------------------------------------------------------
|
||||
|
||||
# Where scripts live, in render order.
|
||||
declare -A loc_label=(
|
||||
["features/scripts/utils"]="features/scripts/utils"
|
||||
["core/system/scripts"]="core/system/scripts"
|
||||
["themes/engine/scripts"]="themes/engine/scripts"
|
||||
)
|
||||
script_dirs=(features/scripts/utils core/system/scripts themes/engine/scripts)
|
||||
|
||||
# Build name → location map (associative array of basename → repo-relative dir).
|
||||
declare -A script_loc
|
||||
for dir in "${script_dirs[@]}"; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
while IFS= read -r f; do
|
||||
script_loc["$(basename "$f")"]="$dir"
|
||||
done < <(find "$dir" -maxdepth 1 -type f -name 'nomarchy-*')
|
||||
done
|
||||
|
||||
# Find every nomarchy-* token referenced anywhere outside the script dirs.
|
||||
# (We exclude the script files themselves so they don't list themselves as
|
||||
# their own caller.)
|
||||
# File types we search for references. *.md catches docs and README;
|
||||
# branding/hook/extension files have varied or no extensions.
|
||||
# *.lua catches elephant providers; *.ini catches mako on-button-* hooks;
|
||||
# *.desktop catches MimeType-registered URL handlers.
|
||||
grep_includes=(
|
||||
--include='*.nix' --include='*.conf' --include='*.sh' --include='*.md'
|
||||
--include='nomarchy-*' --include='*.jsonc' --include='*.json'
|
||||
--include='*.toml' --include='*.ini' --include='*.lua'
|
||||
--include='*.desktop' --include='*.txt' --include='*.sample'
|
||||
)
|
||||
search_dirs=(core features themes installer hosts bin lib README.md)
|
||||
|
||||
# Files whose mentions of nomarchy-* are documentation about the scripts,
|
||||
# not real callers. Excluded from caller discovery so they don't promote
|
||||
# every script to `kept`.
|
||||
self_refs=(docs/SCRIPTS.md docs/ROADMAP.md docs/AGENT.md)
|
||||
|
||||
ref_files_per_cmd() {
|
||||
local cmd="$1"
|
||||
local self_pattern
|
||||
self_pattern=$(IFS='|'; echo "${self_refs[*]}")
|
||||
grep -rlE "\\b${cmd}\\b" \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE "^(features/scripts/utils|core/system/scripts|themes/engine/scripts)/${cmd}$" \
|
||||
| grep -vE "^(${self_pattern})$" \
|
||||
| sort -u
|
||||
}
|
||||
|
||||
# All distinct nomarchy-* tokens we see anywhere in the repo.
|
||||
# Final char must be alphanumeric — dropping trailing-dash matches like
|
||||
# `nomarchy-pkg-` that come from glob references (`for c in nomarchy-pkg-*`).
|
||||
# Restrict to grep_includes so binaries / tmpfiles don't pollute the set.
|
||||
# The first `grep -vE` drops lines where `nomarchy-*` is a derivation /
|
||||
# tmp file / sudoers basename / systemd unit / flake output / docker
|
||||
# container identifier rather than a shell invocation.
|
||||
# The second `grep -vE` is a token-level safety net for prefix-only
|
||||
# tokens left over from wildcards/expansions (e.g. `nomarchy-pkg-*`).
|
||||
all_refs=$(grep -rhE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE \
|
||||
-e '(pname|name)[[:space:]]*=[[:space:]]*"nomarchy-' \
|
||||
-e '/tmp/nomarchy-' \
|
||||
-e '/etc/sudoers\.d/[^"[:space:]]*nomarchy-' \
|
||||
-e 'nixosConfigurations\.nomarchy-' \
|
||||
-e 'packages\.[^.]+\.nomarchy-' \
|
||||
-e '\./result/bin/run-nomarchy-' \
|
||||
-e 'mktemp[[:space:]]+[^|]*-t[[:space:]]+nomarchy-' \
|
||||
-e '(TIMER_NAME|NOPASSWD_FILE|UNIT_NAME)=.*nomarchy-' \
|
||||
-e 'docker[[:space:]]+[^|]*nomarchy-' \
|
||||
| grep -oE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
| grep -vE '^(nomarchy-launch|nomarchy-brightness|nomarchy-cmd|nomarchy-pkg|nomarchy-restart|nomarchy-toggle|nomarchy-theme|nomarchy-webapp-handler|nomarchy-font-selector|nomarchy-theme-selector|nomarchy-wallpaper-selector|nomarchy-setup|nomarchy-refresh|nomarchy-scripts|nomarchy-system-scripts|nomarchy-theme-engine-scripts)$' \
|
||||
| grep -vE '^(nomarchy-plymouth|nomarchy-sddm-theme|nomarchy-live|nomarchy-rev|nomarchy-windows)$' \
|
||||
| sort -u)
|
||||
# The second denylist covers identifiers whose ambiguity survives the line
|
||||
# filter: `nomarchy-plymouth` / `nomarchy-sddm-theme` are Nix derivation
|
||||
# names referenced as bare idents in `[...]` lists, `nomarchy-live` is an
|
||||
# ISO label that shows up in comments, `nomarchy-rev` is `/etc/nomarchy-rev`
|
||||
# (written by the ISO), and `nomarchy-windows` is a docker container name
|
||||
# in compose heredocs.
|
||||
|
||||
# --- Render: header --------------------------------------------------------
|
||||
|
||||
main() {
|
||||
cat <<'HEADER'
|
||||
# Nomarchy Script & Menu Audit
|
||||
|
||||
Auto-generated table for [Pillar 3 of the roadmap](ROADMAP.md#3-pillar-script--menu-audit).
|
||||
**Do not edit by hand.** Regenerate after script or menu changes:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
```
|
||||
|
||||
The status column uses a Phase A heuristic — `kept` / `unused?` / `missing`.
|
||||
Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
`delete-dead`, or `stub-with-notify` and updates the rows.
|
||||
|
||||
## Status legend
|
||||
|
||||
- `kept` — script exists and is called from somewhere outside its own directory.
|
||||
- `unused?` — script exists but no caller was found. Could be dead, could be
|
||||
intentional public API. Phase B triage decides.
|
||||
- `missing` — referenced from code but no script file exists. Phase B triage
|
||||
decides whether to port from Omarchy upstream, delete the caller, or stub
|
||||
with `notify-send`.
|
||||
- `port-from-omarchy` — Phase B verdict: lift the upstream Omarchy script,
|
||||
rewrite for NixOS paths.
|
||||
- `delete-dead` — Phase B verdict: remove and update callers.
|
||||
- `stub-with-notify` — Phase B verdict: temporary `notify-send` stub.
|
||||
|
||||
HEADER
|
||||
|
||||
# --- Render: scripts table ----------------------------------------------
|
||||
printf '## Scripts (%d)\n\n' "${#script_loc[@]}"
|
||||
printf '| Script | Location | Callers | Status | Notes |\n'
|
||||
printf '| --- | --- | --- | --- | --- |\n'
|
||||
|
||||
# Sort scripts by name.
|
||||
for name in $(printf '%s\n' "${!script_loc[@]}" | sort); do
|
||||
local dir="${script_loc[$name]}"
|
||||
local callers status callers_str
|
||||
callers=$(ref_files_per_cmd "$name")
|
||||
if [[ -z "$callers" ]]; then
|
||||
status='`unused?`'
|
||||
callers_str='—'
|
||||
else
|
||||
status='`kept`'
|
||||
# Trim caller list to 2 entries + count.
|
||||
local count
|
||||
count=$(printf '%s\n' "$callers" | wc -l)
|
||||
if (( count > 2 )); then
|
||||
callers_str=$(printf '%s\n' "$callers" | head -2 | paste -sd, -)
|
||||
callers_str="$callers_str, +$((count - 2)) more"
|
||||
else
|
||||
callers_str=$(printf '%s\n' "$callers" | paste -sd, -)
|
||||
fi
|
||||
fi
|
||||
printf '| `%s` | `%s` | %s | %s | |\n' \
|
||||
"$name" "$dir" "$callers_str" "$status"
|
||||
done
|
||||
echo
|
||||
|
||||
# --- Render: missing references -----------------------------------------
|
||||
printf '## Missing references\n\n'
|
||||
printf 'Tokens grepped from `core/`, `features/`, `themes/`, `installer/`, `hosts/`, `bin/`, `lib/` that have no matching script file.\n\n'
|
||||
printf '| Token | Referenced in | Status |\n'
|
||||
printf '| --- | --- | --- |\n'
|
||||
while IFS= read -r token; do
|
||||
[[ -z "$token" ]] && continue
|
||||
[[ -n "${script_loc[$token]:-}" ]] && continue
|
||||
local refs
|
||||
self_pattern=$(IFS='|'; echo "${self_refs[*]}")
|
||||
refs=$(grep -rlE "\\b${token}\\b" \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE "^(${self_pattern})$" \
|
||||
| sort -u)
|
||||
[[ -z "$refs" ]] && continue
|
||||
local count refs_str
|
||||
count=$(printf '%s\n' "$refs" | wc -l)
|
||||
if (( count > 2 )); then
|
||||
refs_str=$(printf '%s\n' "$refs" | head -2 | paste -sd, -)
|
||||
refs_str="$refs_str, +$((count - 2)) more"
|
||||
else
|
||||
refs_str=$(printf '%s\n' "$refs" | paste -sd, -)
|
||||
fi
|
||||
printf '| `%s` | %s | `missing` |\n' "$token" "$refs_str"
|
||||
done <<<"$all_refs"
|
||||
echo
|
||||
|
||||
# --- Render: menu items -------------------------------------------------
|
||||
printf '## Menu items\n\n'
|
||||
printf 'Walked from `features/scripts/utils/nomarchy-menu`. Each `case` arm in a `show_*_menu` function becomes one row.\n\n'
|
||||
printf '| Submenu | Entry | Calls | Status |\n'
|
||||
printf '| --- | --- | --- | --- |\n'
|
||||
|
||||
awk '
|
||||
/^show_[a-z_]+_menu\(\) {/ { sub(/\(\) {/, ""); current=$1; in_func=1; next }
|
||||
/^[a-z_]+\(\) {/ && !/^show_/ { current=""; in_func=0; next }
|
||||
/^}$/ { current=""; in_func=0; next }
|
||||
!in_func { next }
|
||||
/^ case \$\(menu / {
|
||||
# extract the menu title between the first pair of double quotes
|
||||
match($0, /menu "[^"]+" "[^"]+"/);
|
||||
if (RSTART == 0) next;
|
||||
title=substr($0, RSTART, RLENGTH);
|
||||
# second quoted string is the option list
|
||||
n=split(title, parts, "\"");
|
||||
title=parts[2];
|
||||
options=parts[4];
|
||||
# split options on \n
|
||||
split(options, opts, "\\\\n");
|
||||
pending_submenu=current;
|
||||
pending_title=title;
|
||||
for (i=1;i<=length(opts);i++) pending_opts[i]=opts[i];
|
||||
pending_count=length(opts);
|
||||
next
|
||||
}
|
||||
/^ \*[A-Za-z]/ {
|
||||
# case arm — extract pattern between the first * and the closing )
|
||||
match($0, /\*[^)]*\)/);
|
||||
if (RSTART == 0) next;
|
||||
arm=substr($0, RSTART, RLENGTH);
|
||||
gsub(/[*)]/, "", arm);
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", arm);
|
||||
# action follows the )
|
||||
rest=substr($0, RSTART+RLENGTH);
|
||||
sub(/^[[:space:]]+/, "", rest);
|
||||
sub(/[[:space:]]*;;[[:space:]]*$/, "", rest);
|
||||
# match the first nomarchy-* token in the action
|
||||
cmd=""
|
||||
if (match(rest, /nomarchy-[a-z0-9-]+/)) {
|
||||
cmd=substr(rest, RSTART, RLENGTH);
|
||||
}
|
||||
printf "%s|%s|%s\n", pending_submenu, arm, cmd;
|
||||
}
|
||||
' features/scripts/utils/nomarchy-menu > /tmp/nomarchy-menu-rows.$$
|
||||
|
||||
while IFS='|' read -r submenu entry cmd; do
|
||||
[[ -z "$entry" ]] && continue
|
||||
[[ "$entry" =~ ^\) ]] && continue
|
||||
status='`kept`'
|
||||
if [[ -n "$cmd" ]]; then
|
||||
if [[ -z "${script_loc[$cmd]:-}" ]]; then
|
||||
status='`missing`'
|
||||
fi
|
||||
else
|
||||
cmd='_(inline)_'
|
||||
fi
|
||||
printf '| `%s` | %s | `%s` | %s |\n' "$submenu" "$entry" "$cmd" "$status"
|
||||
done < /tmp/nomarchy-menu-rows.$$
|
||||
rm -f /tmp/nomarchy-menu-rows.$$
|
||||
echo
|
||||
}
|
||||
|
||||
out=""
|
||||
if [[ "${1:-}" == "--out" ]]; then
|
||||
out="${2:?--out needs a path}"; shift 2
|
||||
fi
|
||||
if [[ -n "$out" ]]; then
|
||||
main >"$out"
|
||||
else
|
||||
main
|
||||
fi
|
||||
16
core/branding/about.txt
Normal file
16
core/branding/about.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
# About Nomarchy
|
||||
|
||||
Nomarchy is a highly curated, NixOS-based distribution designed for power users.
|
||||
It features a customized Hyprland desktop environment with a declarative
|
||||
theming engine and a suite of integrated utility scripts.
|
||||
|
||||
Built on a foundation of:
|
||||
- NixOS (Linux)
|
||||
- Hyprland (Window Manager)
|
||||
- Waybar (Status Bar)
|
||||
- Walker (Application Launcher & Menu)
|
||||
- Stylix (Theming Engine)
|
||||
|
||||
Version: 2026.05.04
|
||||
Docs: https://github.com/nomarchy/nomarchy/docs
|
||||
Manual: nomarchy-manual (Command)
|
||||
11
core/branding/screensaver.txt
Normal file
11
core/branding/screensaver.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# Nomarchy Screensaver Configuration
|
||||
|
||||
Nomarchy uses hyprlock for locking and hypridle for idle management.
|
||||
To configure the screensaver/lock screen visuals, edit:
|
||||
~/.config/hypr/hyprlock.conf
|
||||
|
||||
To configure idle timeouts and actions, edit:
|
||||
~/.config/hypr/hypridle.conf
|
||||
|
||||
You can also toggle the screensaver/idle management via the Nomarchy Menu:
|
||||
Trigger > Toggle > Idle Lock
|
||||
@@ -1,94 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
# Behavior Configuration Module
|
||||
#
|
||||
# This module deploys non-visual configuration files (keybindings, input settings,
|
||||
# window rules, etc.) with lib.mkDefault, allowing downstream users to override.
|
||||
#
|
||||
# Visual/theme configs are handled separately by theme-loader.nix and stylix.nix.
|
||||
#
|
||||
# Behavior configs include:
|
||||
# - Keybindings (bindings, media keys, clipboard)
|
||||
# - Input settings (keyboard, mouse, touchpad)
|
||||
# - Window rules and layouts
|
||||
# - Autostart applications
|
||||
# - Environment variables
|
||||
|
||||
let
|
||||
configDir = ./config;
|
||||
overridesDir = "${config.home.homeDirectory}/.config/nomarchy/overrides";
|
||||
|
||||
# Behavior config categories with their source paths
|
||||
behaviorConfigs = {
|
||||
# Hyprland behavior (non-visual)
|
||||
"nomarchy/default/hypr/bindings.conf" = "hypr/bindings.conf";
|
||||
"nomarchy/default/hypr/bindings/media.conf" = "hypr/bindings/media.conf";
|
||||
"nomarchy/default/hypr/bindings/clipboard.conf" = "hypr/bindings/clipboard.conf";
|
||||
"nomarchy/default/hypr/bindings/tiling-v2.conf" = "hypr/bindings/tiling-v2.conf";
|
||||
"nomarchy/default/hypr/bindings/utilities.conf" = "hypr/bindings/utilities.conf";
|
||||
"nomarchy/default/hypr/input.conf" = "hypr/input.conf";
|
||||
"nomarchy/default/hypr/windows.conf" = "hypr/windows.conf";
|
||||
"nomarchy/default/hypr/autostart.conf" = "hypr/autostart.conf";
|
||||
"nomarchy/default/hypr/envs.conf" = "hypr/envs.conf";
|
||||
"nomarchy/default/hypr/looknfeel.conf" = "hypr/looknfeel.conf";
|
||||
|
||||
# App-specific window rules (behavior, not visual)
|
||||
"nomarchy/default/hypr/apps.conf" = "hypr/apps.conf";
|
||||
"nomarchy/default/hypr/apps/qemu.conf" = "hypr/apps/qemu.conf";
|
||||
"nomarchy/default/hypr/apps/steam.conf" = "hypr/apps/steam.conf";
|
||||
"nomarchy/default/hypr/apps/terminals.conf" = "hypr/apps/terminals.conf";
|
||||
"nomarchy/default/hypr/apps/walker.conf" = "hypr/apps/walker.conf";
|
||||
"nomarchy/default/hypr/apps/browser.conf" = "hypr/apps/browser.conf";
|
||||
"nomarchy/default/hypr/apps/1password.conf" = "hypr/apps/1password.conf";
|
||||
"nomarchy/default/hypr/apps/bitwarden.conf" = "hypr/apps/bitwarden.conf";
|
||||
"nomarchy/default/hypr/apps/pip.conf" = "hypr/apps/pip.conf";
|
||||
"nomarchy/default/hypr/apps/system.conf" = "hypr/apps/system.conf";
|
||||
"nomarchy/default/hypr/apps/localsend.conf" = "hypr/apps/localsend.conf";
|
||||
"nomarchy/default/hypr/apps/telegram.conf" = "hypr/apps/telegram.conf";
|
||||
"nomarchy/default/hypr/apps/geforce.conf" = "hypr/apps/geforce.conf";
|
||||
"nomarchy/default/hypr/apps/moonlight.conf" = "hypr/apps/moonlight.conf";
|
||||
"nomarchy/default/hypr/apps/retroarch.conf" = "hypr/apps/retroarch.conf";
|
||||
"nomarchy/default/hypr/apps/webcam-overlay.conf" = "hypr/apps/webcam-overlay.conf";
|
||||
"nomarchy/default/hypr/apps/davinci-resolve.conf" = "hypr/apps/davinci-resolve.conf";
|
||||
"nomarchy/default/hypr/apps/hyprshot.conf" = "hypr/apps/hyprshot.conf";
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
options.nomarchy.behavior = {
|
||||
hyprland = {
|
||||
bindings = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default Hyprland keybindings.";
|
||||
};
|
||||
input = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default input settings.";
|
||||
};
|
||||
windowRules = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default window rules.";
|
||||
};
|
||||
autostart = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default autostart configuration.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
# Note: The actual config deployment is handled by configs.nix
|
||||
# This module provides the options and documentation for behavior configs
|
||||
# The separation allows users to selectively disable behavior categories
|
||||
|
||||
# Ensure behavior config directories exist in overrides
|
||||
home.activation.createBehaviorOverrideDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
mkdir -p "${overridesDir}/hypr/bindings"
|
||||
mkdir -p "${overridesDir}/hypr/apps"
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,309 +0,0 @@
|
||||
:root {
|
||||
--accent-color: #aeb1b5; /* #'s before H1-3 */
|
||||
--background-color: white;
|
||||
--border-color: #ddd;
|
||||
--code-bg-color: #f8f8f8;
|
||||
--font-color: #42464c;
|
||||
--header-color: #222324;
|
||||
--link-color: #2077b2;
|
||||
--control-text-color: #667176;
|
||||
--side-bar-bg-color: #fafafa;
|
||||
--body-font: "iA Writer Mono S";
|
||||
--border-radius: 2px;
|
||||
--document-horizontal-margin: 80px;
|
||||
--document-padding-x: 10ch;
|
||||
--font-size: 20px;
|
||||
--h1-fontsize: 20px; /* 1,5 rem = 24px */
|
||||
--h2-fontsize: 20px; /* 1,375 rem = 22px */
|
||||
--h3-fontsize: 20px; /* 1,25 rem = 20px */
|
||||
--h4-fontsize: 20px; /* 1,125 rem = 18px */
|
||||
--line-height: 1.8;
|
||||
--main-content-margin: 0 auto;
|
||||
--main-content-max-width: 85ch;
|
||||
--monospace-font-size: 20px;
|
||||
--monospace-font: "iA Writer Mono S";
|
||||
--monospace-line-height: 1.6;
|
||||
--monospace: var(--monospace-font); /* Fixes source code mode */
|
||||
--nav-width: 200px;
|
||||
--vertical-padding: 40px;
|
||||
}
|
||||
|
||||
/* Narrow layout styles */
|
||||
@media (max-width: 640px) {
|
||||
:root {
|
||||
--document-padding-x: 4ch;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: var(--font-size);
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
color: var(--font-color);
|
||||
font-family: var(--body-font);
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
|
||||
#write {
|
||||
/* size of writing area: */
|
||||
padding-left: var(--document-padding-x);
|
||||
padding-right: var(--document-padding-x);
|
||||
max-width: var(--main-content-max-width);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* ---------------------
|
||||
* Block Elements
|
||||
*/
|
||||
|
||||
/* yaml */
|
||||
pre.md-meta-block {
|
||||
background-color: var(--background-color);
|
||||
padding-bottom: .5rem;
|
||||
color: var(--accent-color);
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
font-family: var(--monospace-font);
|
||||
}
|
||||
|
||||
/* headings */
|
||||
h1, h2, h3 {
|
||||
font-weight: bold;
|
||||
color: var(--header-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: var(--h1-fontsize);
|
||||
}
|
||||
|
||||
h1:not(:first-child) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0rem;
|
||||
font-size: var(--h2-fontsize);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0rem;
|
||||
font-size: var(--h3-fontsize);
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
color: var(--header-color);
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--h4-fontsize);
|
||||
}
|
||||
|
||||
h6 {
|
||||
color: var(--control-text-color);
|
||||
}
|
||||
|
||||
h1::before,
|
||||
h2::before,
|
||||
h3::before {
|
||||
font-weight: 400;
|
||||
text-align: right;
|
||||
width: 5ch;
|
||||
padding-right: 1ch;
|
||||
margin-left: -5ch;
|
||||
color: var(--accent-color);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h1::before {
|
||||
content: '#';
|
||||
}
|
||||
|
||||
h2::before {
|
||||
content: '##';
|
||||
}
|
||||
|
||||
h3::before {
|
||||
content: '###';
|
||||
}
|
||||
|
||||
h1 tt,
|
||||
h1 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h2 tt,
|
||||
h2 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h3 tt,
|
||||
h3 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h4 tt,
|
||||
h4 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h5 tt,
|
||||
h5 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h6 tt,
|
||||
h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
/* table */
|
||||
table {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
table tr:nth-child(2n),
|
||||
thead {
|
||||
background-color: var(--side-bar-bg-color);
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border-style: solid;
|
||||
border-color: var(--border-color);
|
||||
border-width: 1px;
|
||||
padding: .35rem .7rem
|
||||
}
|
||||
|
||||
li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.task-list {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.task-list-item {
|
||||
padding-left: 1.5em;
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
#write input[type='checkbox'] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1rem 0;
|
||||
padding-left: 2ch;
|
||||
margin-left: .5ch;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-left: 2px solid var(--border-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
/* horizontal line */
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
margin-top: 1.4rem;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code Fences
|
||||
* see http:/*support.typora.io/Code-Block-Styles
|
||||
*/
|
||||
|
||||
.cm-s-inner .CodeMirror-gutters {
|
||||
background: var(--code-bg-color);
|
||||
}
|
||||
|
||||
.code-tooltip {
|
||||
box-shadow: none;
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--code-bg-color);
|
||||
border-color: var(--border-color);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.code-tooltip input {
|
||||
outline: none;
|
||||
width: 20ch;
|
||||
}
|
||||
|
||||
.md-fences .code-tooltip {
|
||||
bottom: -1.8rem;
|
||||
padding: none;
|
||||
}
|
||||
|
||||
.md-fences.md-focus .cm-s-inner {
|
||||
/* Remove bottom right border radius when tooltip is shown */
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
/* code tooltip autocomplete list */
|
||||
|
||||
.autoComplt-hint {
|
||||
background-color: transparent !important;
|
||||
margin: 0 !important;
|
||||
padding: 0.125rem 0.375rem !important;
|
||||
color: var(--text-color) !important;
|
||||
line-height: var(--line-height) !important;
|
||||
height: 1.4rem !important;
|
||||
}
|
||||
|
||||
.autoComplt-hint-selected {
|
||||
background-color: var(--link-color) !important;
|
||||
color: var(--background-color) !important;
|
||||
}
|
||||
|
||||
/* basic styles */
|
||||
|
||||
.md-fences,
|
||||
code,
|
||||
tt {
|
||||
border: 1px solid var(--border-color);
|
||||
background-color: var(--code-bg-color);
|
||||
font-family: var(--monospace-font);
|
||||
font-size: var(--monospace-font-size);
|
||||
border-radius: .25rem;
|
||||
padding: 0 .125rem;
|
||||
line-height: var(--monospace-line-height);
|
||||
}
|
||||
|
||||
.md-fences {
|
||||
margin-bottom: 18px;
|
||||
margin-top: 15px;
|
||||
padding: 0.2em 1em;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Control UI (optional)
|
||||
*/
|
||||
|
||||
.outline-item:hover {
|
||||
color: var(--header-color);
|
||||
}
|
||||
|
||||
#write div.md-toc-tooltip {
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
@import 'night/codeblock.dark.css';
|
||||
@import 'night/mermaid.dark.css';
|
||||
@import 'night/sourcemode.dark.css';
|
||||
@import 'ia_typora.css';
|
||||
|
||||
:root {
|
||||
--accented-background-color: #1e1e1e;
|
||||
--light-header-color: #dbdbdb; /* H1-H3 */
|
||||
--select-text-bg-color: #186a9a;
|
||||
--accent-color: #4f525a;
|
||||
--background-color: #101010;
|
||||
--font-color: #bbbcbc;
|
||||
--header-color: #bebebe; /* H4-H6 */
|
||||
--border-color: #232629;
|
||||
--link-color: #5584aa;
|
||||
--code-bg-color: #1c1a1a;
|
||||
--hover-bg-color: #050505;
|
||||
--control-text-color: var(--font-color);
|
||||
--side-bar-bg-color: var(--accented-background-color);
|
||||
--control-text-hover-color: var(--header-color);
|
||||
--item-hover-text-color: var(--header-color);
|
||||
--item-hover-bg-color: var(--hover-bg-color);
|
||||
--bg-color: var(--background-color);
|
||||
--text-color: var(--font-color);
|
||||
--meta-content-color: var(--accent-color);
|
||||
--md-char-color: var(--accent-color);
|
||||
--window-border: 1px solid rgba(0,0,0,.07);
|
||||
--active-file-bg-color: var(--hover-bg-color);
|
||||
}
|
||||
|
||||
.outline-item:hover {
|
||||
background-color: var(--hover-bg-color);
|
||||
}
|
||||
|
||||
#write {
|
||||
cursor: -webkit-image-set(url("night/cursor.png") 1x, url("night/cursor@2x.png") 2x) 8 8, auto;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
color: var(--light-header-color);
|
||||
}
|
||||
|
||||
mark {
|
||||
background: #b8b80a
|
||||
}
|
||||
|
||||
table tr:nth-child(2n),
|
||||
thead {
|
||||
background-color: #141313;
|
||||
}
|
||||
|
||||
sup.md-footnote {
|
||||
background-color: var(--code-bg-color);
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
/* right click menu */
|
||||
.context-menu {
|
||||
background-color: #141313;
|
||||
}
|
||||
|
||||
.context-menu.dropdown-menu .divider {
|
||||
background-color: #232629;
|
||||
}
|
||||
|
||||
/* focus mode */
|
||||
.on-focus-mode .md-end-block:not(.md-focus):not(.md-focus-container) * {
|
||||
color: #4f525a !important;
|
||||
}
|
||||
|
||||
.on-focus-mode .md-end-block:not(.md-focus) img,
|
||||
.on-focus-mode .md-task-list-item:not(.md-focus-container)>input {
|
||||
opacity: #4f525a !important;
|
||||
}
|
||||
|
||||
.on-focus-mode li[cid]:not(.md-focus-container){
|
||||
color: #4f525a;
|
||||
}
|
||||
|
||||
.on-focus-mode .md-fences.md-focus .CodeMirror-code>*:not(.CodeMirror-activeline) *,
|
||||
.on-focus-mode .CodeMirror.cm-s-inner:not(.CodeMirror-focused) * {
|
||||
color: #4f525a !important;
|
||||
}
|
||||
|
||||
.on-focus-mode .md-focus,
|
||||
.on-focus-mode .md-focus-container {
|
||||
color: var(--light-header-color);
|
||||
}
|
||||
|
||||
.on-focus-mode #typora-source .CodeMirror-code>*:not(.CodeMirror-activeline) * {
|
||||
color: #4f525a !important;
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
INPUT_METHOD=fcitx
|
||||
QT_IM_MODULE=fcitx
|
||||
XMODIFIERS=@im=fcitx
|
||||
SDL_IM_MODULE=fcitx
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
monitors, gaps, borders, blur, opacity, waybar, walker, terminal config, themes,
|
||||
wallpaper, night light, idle, lock screen, screenshots, layer rules, workspace
|
||||
settings, display config, and user-facing nomarchy commands. Excludes Nomarchy
|
||||
source development in ~/.local/share/nomarchy/ and nomarchy-dev-* workflows.
|
||||
source development in ~/.local/share/nomarchy/ and repo-internal workflows.
|
||||
---
|
||||
|
||||
# Nomarchy Skill
|
||||
@@ -34,7 +34,7 @@ It is not for contributing to Nomarchy source code.
|
||||
|
||||
**If you're about to edit a config file in ~/.config/ on this system, STOP and use this skill first.**
|
||||
|
||||
**Do NOT use this skill for Nomarchy development tasks** (editing files in `~/.local/share/nomarchy/`, creating migrations, or running `nomarchy-dev-*` workflows).
|
||||
**Do NOT use this skill for Nomarchy development tasks** — editing files in `~/.local/share/nomarchy/` or modifying repo internals.
|
||||
|
||||
## Critical Safety Rules
|
||||
|
||||
@@ -244,6 +244,9 @@ nomarchy-theme-set <name> # Apply theme (use "Tokyo Night" not "tokyo-nig
|
||||
nomarchy-theme-next # Cycle to next theme
|
||||
nomarchy-theme-bg-next # Cycle wallpaper
|
||||
nomarchy-theme-install <url> # Install from git repo
|
||||
nomarchy-theme-remove <name> # Remove an installed extra theme
|
||||
nomarchy-theme-refresh # Re-apply current theme from templates
|
||||
nomarchy-theme-bg-install # Open backgrounds dir to drop in custom images
|
||||
```
|
||||
|
||||
### Keybindings
|
||||
@@ -311,10 +314,48 @@ nomarchy-debug --no-sudo --print # Debug info (ALWAYS use these flags)
|
||||
nomarchy-lock-screen # Lock screen
|
||||
nomarchy-system-shutdown # Shutdown
|
||||
nomarchy-system-reboot # Reboot
|
||||
nomarchy-sudo-passwordless-toggle # Toggle 15-min passwordless sudo
|
||||
nomarchy-sudo-reset # Clear sudo lockout / faillock
|
||||
nomarchy-restart-trackpad # Reload intel_quicki2c (fixes dead THC trackpad)
|
||||
```
|
||||
|
||||
**IMPORTANT:** Always run `nomarchy-debug` with `--no-sudo --print` flags to avoid interactive sudo prompts that will hang the terminal.
|
||||
|
||||
### Custom App Launchers
|
||||
|
||||
```bash
|
||||
nomarchy-webapp-install # Add a web app launcher (interactive)
|
||||
nomarchy-webapp-remove [name...] # Remove web apps (interactive if no name)
|
||||
nomarchy-webapp-remove-all # Bulk-remove every web app
|
||||
nomarchy-tui-install # Add a TUI launcher for a terminal program
|
||||
nomarchy-tui-remove [name...] # Remove TUI launchers
|
||||
nomarchy-tui-remove-all # Bulk-remove every TUI launcher
|
||||
```
|
||||
|
||||
Both families write `.desktop` files into `~/.local/share/applications/` so they appear in the app launcher (walker / rofi).
|
||||
|
||||
### Voice dictation (Voxtype)
|
||||
|
||||
```bash
|
||||
nomarchy-voxtype-install # Install Voxtype + AI model (~150MB)
|
||||
nomarchy-voxtype-remove # Uninstall Voxtype
|
||||
nomarchy-voxtype-status # Running state (also shown in waybar)
|
||||
```
|
||||
|
||||
Toggle dictation with `SUPER+CTRL+X` after install.
|
||||
|
||||
### Virtualization
|
||||
|
||||
```bash
|
||||
nomarchy-windows-vm install # Provision a Windows VM via docker-compose
|
||||
nomarchy-windows-vm launch # Connect to the VM (auto-stop on disconnect)
|
||||
nomarchy-windows-vm launch -k # Connect, keep VM running after disconnect
|
||||
nomarchy-windows-vm stop # Shut the VM down
|
||||
nomarchy-windows-vm status # Show current state
|
||||
```
|
||||
|
||||
Requires KVM (`/dev/kvm`) and Docker (enable via `nomarchy.system.virtualization.docker`).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
@@ -325,6 +366,7 @@ nomarchy-debug --no-sudo --print
|
||||
nomarchy-upload-log
|
||||
|
||||
# Reset specific config to defaults
|
||||
# Examples: nomarchy-refresh-fastfetch, nomarchy-refresh-hyprland, nomarchy-refresh-waybar
|
||||
nomarchy-refresh-<app>
|
||||
|
||||
# Refresh specific config file
|
||||
@@ -352,7 +394,7 @@ When user requests system changes:
|
||||
This skill intentionally does not cover Nomarchy source development. Do not use this skill for:
|
||||
- Editing files in `~/.local/share/nomarchy/` (`bin/`, `config/`, `default/`, `themes/`, `migrations/`, etc.)
|
||||
- Creating or editing migrations
|
||||
- Running `nomarchy-dev-*` commands
|
||||
- Modifying Nomarchy's own source tree
|
||||
|
||||
## Example Requests
|
||||
|
||||
|
||||
@@ -3,5 +3,4 @@ export SUDO_EDITOR="$EDITOR"
|
||||
export BAT_THEME=ansi
|
||||
|
||||
# Duplicated from .config/uwsm/env so SSH works too
|
||||
export NOMARCHY_PATH=$HOME/.local/share/nomarchy
|
||||
export PATH=$NOMARCHY_PATH/bin:$PATH:$HOME/.local/bin
|
||||
export PATH=$PATH:$HOME/.local/bin
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# If not running interactively, don't do anything (leave this at the top of this file)
|
||||
[[ $- != *i* ]] && return
|
||||
|
||||
# All the default Nomarchy aliases and functions
|
||||
# (don't mess with these directly, just overwrite them here!)
|
||||
source ~/.config/nomarchy/default/bash/rc
|
||||
|
||||
# Add your own exports, aliases, and functions here.
|
||||
#
|
||||
# Make an alias for invoking commands you use constantly
|
||||
# alias p='python'
|
||||
@@ -32,8 +32,7 @@ end
|
||||
function GetEntries()
|
||||
local entries = {}
|
||||
local user_theme_dir = os.getenv("HOME") .. "/.config/nomarchy/themes"
|
||||
local nomarchy_path = os.getenv("NOMARCHY_PATH") or ""
|
||||
local default_theme_dir = nomarchy_path .. "/themes"
|
||||
local default_theme_dir = os.getenv("HOME") .. "/.local/share/nomarchy/themes"
|
||||
|
||||
local seen_themes = {}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
exec-once = uwsm-app -- hypridle
|
||||
exec-once = uwsm-app -- mako
|
||||
exec-once = nomarchy-welcome
|
||||
# exec-once = uwsm-app -- waybar
|
||||
exec-once = uwsm-app -- fcitx5 --disable notificationitem
|
||||
# fcitx5 is autostarted by NixOS's i18n.inputMethod when
|
||||
# nomarchy.system.inputMethod.enable = true; no manual exec-once needed.
|
||||
# swaybg is started as a systemd user service (nomarchy-wallpaper.service)
|
||||
# so failures surface in logs and the wallpaper survives Hyprland restarts.
|
||||
exec-once = uwsm-app -- swayosd-server
|
||||
@@ -10,3 +12,6 @@ exec-once = nomarchy-on-boot
|
||||
# Slow app launch fix -- set systemd vars
|
||||
exec-once = systemctl --user import-environment $(env | cut -d'=' -f 1)
|
||||
exec-once = dbus-update-activation-environment --systemd --all
|
||||
|
||||
# Network Manager
|
||||
exec-once = uwsm-app 'nm-applet --indicator'
|
||||
|
||||
@@ -12,5 +12,5 @@ bindd = SUPER, O, Obsidian, exec, obsidian -disable-gpu
|
||||
bindd = SUPER, SLASH, Password manager, exec, $passwordManager
|
||||
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/media.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/tiling.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/tiling-v2.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/utilities.conf
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
# This is now a deprecated file meant for those who did not wish to learn the latest Nomarchy hotkeys.
|
||||
# Do not make changes here, but bring them to tiling-v2.conf instead.
|
||||
|
||||
# Close windows
|
||||
bindd = SUPER, W, Close window, killactive,
|
||||
bindd = CTRL ALT, DELETE, Close all windows, exec, nomarchy-hyprland-window-close-all
|
||||
|
||||
# Control tiling
|
||||
bindd = SUPER, J, Toggle window split, togglesplit, # dwindle
|
||||
bindd = SUPER, P, Pseudo window, pseudo, # dwindle
|
||||
bindd = SUPER SHIFT, V, Toggle window floating/tiling, togglefloating,
|
||||
bindd = SHIFT, F11, Force full screen, fullscreen, 0
|
||||
bindd = ALT, F11, Full width, fullscreen, 1
|
||||
|
||||
# Move focus with SUPER + arrow keys
|
||||
bindd = SUPER, LEFT, Move focus left, movefocus, l
|
||||
bindd = SUPER, RIGHT, Move focus right, movefocus, r
|
||||
bindd = SUPER, UP, Move focus up, movefocus, u
|
||||
bindd = SUPER, DOWN, Move focus down, movefocus, d
|
||||
|
||||
# Switch workspaces with SUPER + [0-9]
|
||||
bindd = SUPER, code:10, Switch to workspace 1, workspace, 1
|
||||
bindd = SUPER, code:11, Switch to workspace 2, workspace, 2
|
||||
bindd = SUPER, code:12, Switch to workspace 3, workspace, 3
|
||||
bindd = SUPER, code:13, Switch to workspace 4, workspace, 4
|
||||
bindd = SUPER, code:14, Switch to workspace 5, workspace, 5
|
||||
bindd = SUPER, code:15, Switch to workspace 6, workspace, 6
|
||||
bindd = SUPER, code:16, Switch to workspace 7, workspace, 7
|
||||
bindd = SUPER, code:17, Switch to workspace 8, workspace, 8
|
||||
bindd = SUPER, code:18, Switch to workspace 9, workspace, 9
|
||||
bindd = SUPER, code:19, Switch to workspace 10, workspace, 10
|
||||
|
||||
# Move active window to a workspace with SUPER + SHIFT + [0-9]
|
||||
bindd = SUPER SHIFT, code:10, Move window to workspace 1, movetoworkspace, 1
|
||||
bindd = SUPER SHIFT, code:11, Move window to workspace 2, movetoworkspace, 2
|
||||
bindd = SUPER SHIFT, code:12, Move window to workspace 3, movetoworkspace, 3
|
||||
bindd = SUPER SHIFT, code:13, Move window to workspace 4, movetoworkspace, 4
|
||||
bindd = SUPER SHIFT, code:14, Move window to workspace 5, movetoworkspace, 5
|
||||
bindd = SUPER SHIFT, code:15, Move window to workspace 6, movetoworkspace, 6
|
||||
bindd = SUPER SHIFT, code:16, Move window to workspace 7, movetoworkspace, 7
|
||||
bindd = SUPER SHIFT, code:17, Move window to workspace 8, movetoworkspace, 8
|
||||
bindd = SUPER SHIFT, code:18, Move window to workspace 9, movetoworkspace, 9
|
||||
bindd = SUPER SHIFT, code:19, Move window to workspace 10, movetoworkspace, 10
|
||||
|
||||
# TAB between workspaces
|
||||
bindd = SUPER, TAB, Next workspace, workspace, e+1
|
||||
bindd = SUPER SHIFT, TAB, Previous workspace, workspace, e-1
|
||||
bindd = SUPER CTRL, TAB, Former workspace, workspace, previous
|
||||
|
||||
# Swap active window with the one next to it with SUPER + SHIFT + arrow keys
|
||||
bindd = SUPER SHIFT, LEFT, Swap window to the left, swapwindow, l
|
||||
bindd = SUPER SHIFT, RIGHT, Swap window to the right, swapwindow, r
|
||||
bindd = SUPER SHIFT, UP, Swap window up, swapwindow, u
|
||||
bindd = SUPER SHIFT, DOWN, Swap window down, swapwindow, d
|
||||
|
||||
# Cycle through applications on active workspace
|
||||
bindd = ALT, TAB, Cycle to next window, cyclenext
|
||||
bindd = ALT SHIFT, TAB, Cycle to prev window, cyclenext, prev
|
||||
bindd = ALT, TAB, Reveal active window on top, bringactivetotop
|
||||
bindd = ALT SHIFT, TAB, Reveal active window on top, bringactivetotop
|
||||
|
||||
# Resize active window
|
||||
bindd = SUPER, code:20, Expand window left, resizeactive, -100 0 # - key
|
||||
bindd = SUPER, code:21, Shrink window left, resizeactive, 100 0 # = key
|
||||
bindd = SUPER SHIFT, code:20, Shrink window up, resizeactive, 0 -100
|
||||
bindd = SUPER SHIFT, code:21, Expand window down, resizeactive, 0 100
|
||||
|
||||
# Scroll through existing workspaces with SUPER + scroll
|
||||
bindd = SUPER, MOUSE_DOWN, Scroll active workspace forward, workspace, e+1
|
||||
bindd = SUPER, MOUSE_UP, Scroll active workspace backward, workspace, e-1
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindmd = SUPER, mouse:272, Move window, movewindow
|
||||
bindmd = SUPER, mouse:273, Resize window, resizewindow
|
||||
@@ -1,268 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--The Xournal++ settings file. Do not edit this file! Most settings are available in the Settings dialog, the others are commented in this file, but handle with care!-->
|
||||
<settings>
|
||||
<property name="pressureSensitivity" value="true"/>
|
||||
<property name="minimumPressure" value="0.05"/>
|
||||
<property name="pressureMultiplier" value="1"/>
|
||||
<property name="zoomGesturesEnabled" value="true"/>
|
||||
<property name="selectedToolbar" value="Portrait"/>
|
||||
<property name="lastSavePath" value="/home/dhh/Downloads"/>
|
||||
<property name="lastOpenPath" value=""/>
|
||||
<property name="lastImagePath" value="/home/dhh/Dropbox/Images"/>
|
||||
<property name="edgePanSpeed" value="20"/>
|
||||
<property name="edgePanMaxMult" value="5"/>
|
||||
<property name="zoomStep" value="10"/>
|
||||
<property name="zoomStepScroll" value="2"/>
|
||||
<property name="displayDpi" value="72"/>
|
||||
<property name="mainWndWidth" value="800"/>
|
||||
<property name="mainWndHeight" value="600"/>
|
||||
<property name="maximized" value="true"/>
|
||||
<property name="showToolbar" value="true"/>
|
||||
<property name="showSidebar" value="true"/>
|
||||
<property name="sidebarWidth" value="150"/>
|
||||
<property name="sidebarNumberingStyle" value="1"/>
|
||||
<property name="sidebarOnRight" value="false"/>
|
||||
<property name="scrollbarOnLeft" value="false"/>
|
||||
<property name="menubarVisible" value="true"/>
|
||||
<property name="filepathShownInTitlebar" value="false"/>
|
||||
<property name="numColumns" value="1"/>
|
||||
<property name="numRows" value="1"/>
|
||||
<property name="viewFixedRows" value="false"/>
|
||||
<property name="showPairedPages" value="false"/>
|
||||
<property name="layoutVertical" value="false"/>
|
||||
<property name="layoutRightToLeft" value="false"/>
|
||||
<property name="layoutBottomToTop" value="false"/>
|
||||
<property name="numPairsOffset" value="1"/>
|
||||
<!--The icon theme, allowed values are "disabled", "onDrawOfLastPage", and "onScrollOfLastPage"-->
|
||||
<property name="emptyLastPageAppend" value="disabled"/>
|
||||
<property name="presentationMode" value="false"/>
|
||||
<!--Which GUI elements are shown in default view mode, separated by a colon (,)-->
|
||||
<property name="defaultViewModeAttributes" value="showMenubar,showToolbar,showSidebar"/>
|
||||
<!--Which GUI elements are shown in fullscreen view mode, separated by a colon (,)-->
|
||||
<property name="fullscreenViewModeAttributes" value="goFullscren,showToolbar,showSidebar"/>
|
||||
<!--Which GUI elements are shown in presentation view mode, separated by a colon (,)-->
|
||||
<property name="presentationViewModeAttributes" value="goFullscren,showToolbar"/>
|
||||
<!--The cursor icon used with a stylus, allowed values are "none", "dot", "big", "arrow"-->
|
||||
<property name="stylusCursorType" value="dot"/>
|
||||
<!--The eraser cursor visibility used with a stylus, allowed values are "never", "always", "hover", "touch"-->
|
||||
<property name="eraserVisibility" value="always"/>
|
||||
<!--The icon theme, allowed values are "iconsColor", "iconsLucide"-->
|
||||
<property name="iconTheme" value="iconsColor"/>
|
||||
<!--Dark/light mode, allowed values are "useSystem", "forceLight", "forceDark"-->
|
||||
<property name="themeVariant" value="forceDark"/>
|
||||
<property name="highlightPosition" value="false"/>
|
||||
<property name="cursorHighlightColor" value="2164260608"/>
|
||||
<property name="cursorHighlightBorderColor" value="2147483903"/>
|
||||
<property name="cursorHighlightRadius" value="30"/>
|
||||
<property name="cursorHighlightBorderWidth" value="0"/>
|
||||
<property name="useStockIcons" value="false"/>
|
||||
<property name="disableScrollbarFadeout" value="false"/>
|
||||
<property name="disableAudio" value="false"/>
|
||||
<!--Hides scroolbars in the main window, allowed values: "none", "horizontal", "vertical", "both"-->
|
||||
<property name="scrollbarHideType" value="none"/>
|
||||
<property name="autoloadMostRecent" value="false"/>
|
||||
<property name="autoloadPdfXoj" value="true"/>
|
||||
<property name="defaultSaveName" value="%F-Note-%H-%M"/>
|
||||
<property name="defaultPdfExportName" value="%{name}_annotated"/>
|
||||
<property name="autosaveEnabled" value="true"/>
|
||||
<property name="autosaveTimeout" value="3"/>
|
||||
<property name="addHorizontalSpace" value="false"/>
|
||||
<property name="addHorizontalSpaceAmount" value="150"/>
|
||||
<property name="addVerticalSpace" value="false"/>
|
||||
<property name="addVerticalSpaceAmount" value="150"/>
|
||||
<property name="drawDirModsEnabled" value="false"/>
|
||||
<property name="drawDirModsRadius" value="50"/>
|
||||
<property name="snapRotation" value="true"/>
|
||||
<property name="snapRotationTolerance" value="0.3"/>
|
||||
<property name="snapGrid" value="true"/>
|
||||
<property name="snapGridTolerance" value="0.5"/>
|
||||
<property name="snapGridSize" value="14.17"/>
|
||||
<property name="strokeRecognizerMinSize" value="40"/>
|
||||
<property name="touchDrawing" value="false"/>
|
||||
<property name="gtkTouchInertialScrolling" value="true"/>
|
||||
<property name="pressureGuessing" value="false"/>
|
||||
<property name="selectionBorderColor" value="4294901760"/>
|
||||
<property name="backgroundColor" value="4292664021"/>
|
||||
<property name="selectionMarkerColor" value="4285702095"/>
|
||||
<property name="touchZoomStartThreshold" value="0"/>
|
||||
<property name="pageRerenderThreshold" value="5"/>
|
||||
<!--The count of rendered PDF pages which will be cached.-->
|
||||
<property name="pdfPageCacheSize" value="10"/>
|
||||
<property name="preloadPagesBefore" value="3"/>
|
||||
<property name="preloadPagesAfter" value="5"/>
|
||||
<property name="eagerPageCleanup" value="true"/>
|
||||
<!--Config for new pages-->
|
||||
<property name="pageTemplate" value="xoj/template copyLastPageSettings=true size=595.275591x841.889764 backgroundType=lined backgroundColor=#ffffff "/>
|
||||
<property name="sizeUnit" value=""/>
|
||||
<property name="audioFolder" value=""/>
|
||||
<property name="audioInputDevice" value="-1"/>
|
||||
<property name="audioOutputDevice" value="-1"/>
|
||||
<property name="audioSampleRate" value="44100"/>
|
||||
<property name="audioGain" value="1"/>
|
||||
<property name="defaultSeekTime" value="5"/>
|
||||
<property name="pluginEnabled" value=""/>
|
||||
<property name="pluginDisabled" value=""/>
|
||||
<property name="strokeFilterIgnoreTime" value="150"/>
|
||||
<property name="strokeFilterIgnoreLength" value="1"/>
|
||||
<property name="strokeFilterSuccessiveTime" value="500"/>
|
||||
<property name="strokeFilterEnabled" value="false"/>
|
||||
<property name="doActionOnStrokeFiltered" value="false"/>
|
||||
<property name="trySelectOnStrokeFiltered" value="false"/>
|
||||
<property name="snapRecognizedShapesEnabled" value="false"/>
|
||||
<property name="restoreLineWidthEnabled" value="false"/>
|
||||
<property name="numIgnoredStylusEvents" value="0"/>
|
||||
<property name="inputSystemTPCButton" value="false"/>
|
||||
<property name="inputSystemDrawOutsideWindow" value="true"/>
|
||||
<property name="preferredLocale" value=""/>
|
||||
<property name="stabilizerAveragingMethod" value="0"/>
|
||||
<property name="stabilizerPreprocessor" value="0"/>
|
||||
<property name="stabilizerBuffersize" value="20"/>
|
||||
<property name="stabilizerSigma" value="0.5"/>
|
||||
<property name="stabilizerDeadzoneRadius" value="1.3"/>
|
||||
<property name="stabilizerDrag" value="0.4"/>
|
||||
<property name="stabilizerMass" value="5"/>
|
||||
<property name="stabilizerCuspDetection" value="true"/>
|
||||
<property name="stabilizerFinalizeStroke" value="true"/>
|
||||
<property name="latexSettings.autoCheckDependencies" value="true"/>
|
||||
<property name="latexSettings.defaultText" value="x^2"/>
|
||||
<property name="latexSettings.globalTemplatePath" value="/usr/share/xournalpp/resources/default_template.tex"/>
|
||||
<property name="latexSettings.genCmd" value="pdflatex -halt-on-error -interaction=nonstopmode '{}'"/>
|
||||
<property name="latexSettings.sourceViewThemeId" value=""/>
|
||||
<property name="latexSettings.editorFont" value="Monospace 12"/>
|
||||
<property name="latexSettings.useCustomEditorFont" value="false"/>
|
||||
<property name="latexSettings.editorWordWrap" value="true"/>
|
||||
<property name="latexSettings.sourceViewAutoIndent" value="true"/>
|
||||
<property name="latexSettings.sourceViewSyntaxHighlight" value="true"/>
|
||||
<property name="latexSettings.sourceViewShowLineNumbers" value="false"/>
|
||||
<property name="font" font="Sans" size="12"/>
|
||||
<data name="buttonConfig">
|
||||
<data name="default">
|
||||
<attribute name="color" type="hex" value="ff000000"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
<attribute name="size" type="string" value="thin"/>
|
||||
<attribute name="tool" type="string" value="pen"/>
|
||||
</data>
|
||||
<data name="eraser">
|
||||
<attribute name="eraserMode" type="string" value="none"/>
|
||||
<attribute name="size" type="string" value="none"/>
|
||||
<attribute name="tool" type="string" value="eraser"/>
|
||||
</data>
|
||||
<data name="middle">
|
||||
<attribute name="tool" type="string" value="hand"/>
|
||||
</data>
|
||||
<data name="right">
|
||||
<attribute name="tool" type="string" value="none"/>
|
||||
</data>
|
||||
<data name="stylus">
|
||||
<attribute name="tool" type="string" value="none"/>
|
||||
</data>
|
||||
<data name="stylus2">
|
||||
<attribute name="tool" type="string" value="none"/>
|
||||
</data>
|
||||
<data name="touch">
|
||||
<attribute name="device" type="string" value=""/>
|
||||
<attribute name="disableDrawing" type="boolean" value="false"/>
|
||||
<attribute name="tool" type="string" value="none"/>
|
||||
</data>
|
||||
</data>
|
||||
<data name="deviceClasses">
|
||||
<data name="Wayland Finger Scrolling">
|
||||
<attribute name="deviceClass" type="int" value="1"/>
|
||||
<attribute name="deviceSource" type="int" value="6"/>
|
||||
</data>
|
||||
<data name="Wayland Pointer">
|
||||
<attribute name="deviceClass" type="int" value="1"/>
|
||||
<attribute name="deviceSource" type="int" value="0"/>
|
||||
</data>
|
||||
</data>
|
||||
<data name="tools">
|
||||
<attribute name="current" type="string" value="text"/>
|
||||
<data name="drawArrow">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="drawCoordinateSystem">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="drawDoubleArrow">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="drawEllipse">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="drawRect">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="drawSpline">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="eraser">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
<attribute name="size" type="string" value="MEDIUM"/>
|
||||
<attribute name="type" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="hand">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="highlighter">
|
||||
<attribute name="color" type="hex" value="ffffff00"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
<attribute name="fill" type="int" value="0"/>
|
||||
<attribute name="fillAlpha" type="int" value="128"/>
|
||||
<attribute name="size" type="string" value="MEDIUM"/>
|
||||
</data>
|
||||
<data name="image">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="pen">
|
||||
<attribute name="color" type="hex" value="ff3333cc"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
<attribute name="fill" type="int" value="0"/>
|
||||
<attribute name="fillAlpha" type="int" value="128"/>
|
||||
<attribute name="size" type="string" value="MEDIUM"/>
|
||||
<attribute name="style" type="string" value="plain"/>
|
||||
</data>
|
||||
<data name="playObject">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectMultiLayerRect">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectMultiLayerRegion">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectObject">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectPdfTextLinear">
|
||||
<attribute name="color" type="hex" value="ff000000"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectPdfTextRect">
|
||||
<attribute name="color" type="hex" value="ff000000"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectRect">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="selectRegion">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="showFloatingToolbox">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="text">
|
||||
<attribute name="color" type="hex" value="ff000000"/>
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
<data name="verticalSpace">
|
||||
<attribute name="drawingType" type="string" value="default"/>
|
||||
</data>
|
||||
</data>
|
||||
<data name="touch">
|
||||
<attribute name="cmdDisable" type="string" value=""/>
|
||||
<attribute name="cmdEnable" type="string" value=""/>
|
||||
<attribute name="disableTouch" type="boolean" value="false"/>
|
||||
<attribute name="method" type="string" value="auto"/>
|
||||
<attribute name="timeout" type="int" value="1000"/>
|
||||
</data>
|
||||
</settings>
|
||||
@@ -7,7 +7,6 @@ let
|
||||
# This replaces dynamic builtins.readDir for clarity and faster evaluation
|
||||
configItems = {
|
||||
# Directories
|
||||
"environment.d" = "directory";
|
||||
fastfetch = "directory";
|
||||
fcitx5 = "directory";
|
||||
fontconfig = "directory";
|
||||
@@ -16,10 +15,8 @@ let
|
||||
"nautilus-python" = "directory";
|
||||
nomarchy = "directory";
|
||||
"nomarchy-skill" = "directory";
|
||||
Typora = "directory";
|
||||
uwsm = "directory";
|
||||
wiremix = "directory";
|
||||
xournalpp = "directory";
|
||||
|
||||
# Files
|
||||
"brave-flags.conf" = "regular";
|
||||
@@ -54,5 +51,17 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
xdg.configFile = configMappings;
|
||||
xdg.configFile = configMappings // {
|
||||
# mako reads ~/.config/mako/config by default. The themed Nomarchy
|
||||
# config (urgency rules, app filters, button handlers) lives under
|
||||
# nomarchy/default/mako/core.ini for organizational reasons, so wire
|
||||
# it explicitly here. Without this, mako silently falls back to its
|
||||
# built-in defaults and every Nomarchy notification customization is
|
||||
# inert.
|
||||
"mako/config".source = lib.mkDefault ./config/nomarchy/default/mako/core.ini;
|
||||
};
|
||||
|
||||
home.file.".XCompose" = lib.mkDefault {
|
||||
source = ./config/nomarchy/default/xcompose;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
./options.nix
|
||||
./state.nix
|
||||
./overrides.nix
|
||||
./behavior.nix
|
||||
./fonts.nix
|
||||
./configs.nix
|
||||
./security.nix
|
||||
./bash.nix
|
||||
./gaming.nix
|
||||
];
|
||||
}
|
||||
|
||||
12
core/home/gaming.nix
Normal file
12
core/home/gaming.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.gaming;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
wayland.windowManager.hyprland.extraConfig = ''
|
||||
windowrulev2 = fullscreen, class:^(steam_app_).*$
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,75 +1,92 @@
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# Defaults live in lib/state-schema.nix so they can't drift between this
|
||||
# file, core/system/options.nix, and core/home/state.nix's `or` fallbacks.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
options.nomarchy = {
|
||||
toggles = {
|
||||
suspend = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.suspend;
|
||||
description = "Whether to show suspend in system menu.";
|
||||
};
|
||||
screensaver = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.screensaver;
|
||||
description = "Whether the screensaver is enabled.";
|
||||
};
|
||||
idle = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.idle;
|
||||
description = "Whether the idle lock is enabled.";
|
||||
};
|
||||
nightlight = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.home.nightlight;
|
||||
description = "Whether the nightlight is enabled.";
|
||||
};
|
||||
waybar = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.waybar;
|
||||
description = "Whether the top bar is enabled.";
|
||||
};
|
||||
skipVsCodeTheme = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to skip theme changes in VSCode.";
|
||||
};
|
||||
};
|
||||
nightlightTemperature = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 4000;
|
||||
default = schema.home.nightlightTemperature;
|
||||
description = "Temperature for the nightlight.";
|
||||
};
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "summer-night";
|
||||
default = schema.home.theme;
|
||||
description = "System theme name.";
|
||||
};
|
||||
formFactor = lib.mkOption {
|
||||
type = lib.types.enum [ "laptop" "desktop" ];
|
||||
default = "laptop";
|
||||
description = ''
|
||||
Physical form factor. Drives UI affordances (battery widget,
|
||||
future lid handling). Default "laptop" — battery widget is
|
||||
harmless on a desktop (renders empty when no BAT* is present),
|
||||
so the safe default is "show, don't hide". The installer
|
||||
auto-detects via /sys/class/power_supply/BAT* and writes the
|
||||
explicit value into the generated home.nix.
|
||||
'';
|
||||
};
|
||||
wallpaper = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
default = schema.home.wallpaper;
|
||||
description = "System wallpaper path.";
|
||||
};
|
||||
panelPosition = lib.mkOption {
|
||||
type = lib.types.enum [ "top" "bottom" ];
|
||||
default = schema.home.panelPosition;
|
||||
description = "Waybar panel position.";
|
||||
};
|
||||
hyprland = {
|
||||
gaps_in = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5;
|
||||
default = schema.home.hyprland.gaps_in;
|
||||
description = "Inner gaps for Hyprland.";
|
||||
};
|
||||
gaps_out = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
default = schema.home.hyprland.gaps_out;
|
||||
description = "Outer gaps for Hyprland.";
|
||||
};
|
||||
border_size = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2;
|
||||
default = schema.home.hyprland.border_size;
|
||||
description = "Border size for Hyprland.";
|
||||
};
|
||||
};
|
||||
fonts = {
|
||||
monospace = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "JetBrainsMono Nerd Font";
|
||||
default = schema.home.font;
|
||||
description = "System monospace font.";
|
||||
};
|
||||
};
|
||||
@@ -100,5 +117,27 @@
|
||||
default = null;
|
||||
description = "Path to a directory containing configuration overrides.";
|
||||
};
|
||||
|
||||
apps = {
|
||||
opencode = {
|
||||
enable = lib.mkEnableOption ''
|
||||
opencode AI coding CLI integration. When on, deploys
|
||||
~/.config/opencode/opencode.json. The `opencode` package itself
|
||||
is not installed by Nomarchy — add it to your home.nix if you
|
||||
want it on PATH.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
gaming = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Gaming preset (home-side companion to nomarchy.system.gaming.enable).
|
||||
Adds a Hyprland window rule that fullscreens windows whose class
|
||||
matches steam_app_* — i.e. games launched through Steam — so they
|
||||
grab the whole screen instead of opening windowed. Set this to the
|
||||
same value as nomarchy.system.gaming.enable; the installer flips
|
||||
both when the Gaming profile is selected.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,97 +1,34 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
# File-based override system for Nomarchy
|
||||
# File-based override system for Nomarchy.
|
||||
#
|
||||
# Users can place config files in ~/.config/nomarchy/overrides/ to completely
|
||||
# replace upstream defaults. Override priority (highest to lowest):
|
||||
# 1. User Nix options
|
||||
# 2. User file overrides (~/.config/nomarchy/overrides/)
|
||||
# 3. Upstream defaults
|
||||
# STATUS: option surface only — the actual override mechanism is NOT yet
|
||||
# implemented. The options are kept so configs that already set
|
||||
# `nomarchy.overrides.enable = …;` continue to evaluate; setting them has
|
||||
# no effect today. Tracked in docs/ROADMAP.md.
|
||||
#
|
||||
# Supported override paths:
|
||||
# - hypr/ - Hyprland configs (bindings.conf, input.conf, etc.)
|
||||
# - waybar/ - Waybar config and style
|
||||
# - alacritty/ - Alacritty terminal config
|
||||
# - walker/ - Walker launcher config
|
||||
# - kitty/ - Kitty terminal config
|
||||
# - btop/ - Btop resource monitor config
|
||||
# - apps/ - Other application configs
|
||||
# When implemented, this module should substitute sources in
|
||||
# `xdg.configFile.<path>.source` based on the presence of matching files
|
||||
# under ~/.config/nomarchy/overrides/.
|
||||
|
||||
let
|
||||
overridesDir = "${config.home.homeDirectory}/.config/nomarchy/overrides";
|
||||
|
||||
# Helper to get override from options
|
||||
getOverrideOrDefault = { path, default }:
|
||||
config.nomarchy.overrides.paths.${path} or default;
|
||||
|
||||
in
|
||||
{
|
||||
options.nomarchy.overrides = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable file-based override loading from ~/.config/nomarchy/overrides/";
|
||||
description = ''
|
||||
Reserved for the future file-based override loader. Currently a
|
||||
no-op — setting this has no effect. See docs/ROADMAP.md.
|
||||
'';
|
||||
};
|
||||
|
||||
paths = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.path;
|
||||
default = {};
|
||||
description = "Override paths discovered at build time. Populated by the override system.";
|
||||
description = ''
|
||||
Reserved for the future file-based override loader. Currently
|
||||
unused.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.nomarchy.overrides.enable {
|
||||
# Create the overrides directory structure if it doesn't exist
|
||||
home.activation.createOverridesDir = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
mkdir -p "${overridesDir}"
|
||||
mkdir -p "${overridesDir}/hypr"
|
||||
mkdir -p "${overridesDir}/waybar"
|
||||
mkdir -p "${overridesDir}/apps"
|
||||
'';
|
||||
|
||||
# Document the override system
|
||||
xdg.configFile."nomarchy/overrides/README.md".text = lib.mkDefault ''
|
||||
# Nomarchy Configuration Overrides
|
||||
|
||||
Place files in this directory to override upstream Nomarchy defaults.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
overrides/
|
||||
├── hypr/
|
||||
│ ├── bindings.conf # Keybindings
|
||||
│ ├── input.conf # Input settings
|
||||
│ ├── monitors.conf # Monitor layout
|
||||
│ ├── rules.conf # Window rules
|
||||
│ └── autostart.conf # Startup apps
|
||||
├── waybar/
|
||||
│ ├── config.jsonc # Waybar layout
|
||||
│ └── style.css # Waybar styling
|
||||
├── apps/
|
||||
│ ├── alacritty.toml # Terminal behavior
|
||||
│ └── ...
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Override Priority
|
||||
|
||||
1. **Nix Options** (highest) - Set in your flake/config
|
||||
2. **File Overrides** - Files in this directory
|
||||
3. **Upstream Defaults** (lowest) - Nomarchy defaults
|
||||
|
||||
## Usage
|
||||
|
||||
1. Copy the file you want to customize from the upstream config
|
||||
2. Place it in the appropriate directory here
|
||||
3. Edit to your preferences
|
||||
4. Run `nixos-rebuild switch` or `home-manager switch`
|
||||
|
||||
## Tips
|
||||
|
||||
- For keybindings, copy `~/.config/hypr/bindings.conf` to `overrides/hypr/`
|
||||
- For Waybar styling, copy `~/.config/waybar/style.css` to `overrides/waybar/`
|
||||
- Changes here persist across Nomarchy updates
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,41 +2,51 @@
|
||||
|
||||
let
|
||||
nomarchyLib = import ../../lib { inherit lib; };
|
||||
# Single source of truth for default values when state.json is missing
|
||||
# a key. Both core/system/options.nix and core/home/options.nix read
|
||||
# from this same file — changing a default in one place updates
|
||||
# everywhere. (Was: each consumer hardcoded its own `or X` literal,
|
||||
# which is how the summer-night/nord split lived for so long.)
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
assetsPath = ../../themes/palettes;
|
||||
|
||||
# Read unified state from ~/.config/nomarchy/state.json
|
||||
togglesState = nomarchyLib.readHomeState config.home.homeDirectory;
|
||||
in
|
||||
{
|
||||
# Every assignment uses lib.mkDefault so a downstream /etc/nixos/home.nix
|
||||
# can override the state.json-derived value. Without mkDefault, every
|
||||
# option here would resolve at default priority and conflict on
|
||||
# assignment from the user's config.
|
||||
config = {
|
||||
nomarchy = {
|
||||
toggles = {
|
||||
suspend = togglesState.suspend or true;
|
||||
screensaver = togglesState.screensaver or true;
|
||||
idle = togglesState.idle or true;
|
||||
nightlight = togglesState.nightlight or false;
|
||||
waybar = togglesState.waybar or true;
|
||||
skipVsCodeTheme = togglesState.skipVsCodeTheme or false;
|
||||
suspend = lib.mkDefault (togglesState.suspend or schema.home.suspend);
|
||||
screensaver = lib.mkDefault (togglesState.screensaver or schema.home.screensaver);
|
||||
idle = lib.mkDefault (togglesState.idle or schema.home.idle);
|
||||
nightlight = lib.mkDefault (togglesState.nightlight or schema.home.nightlight);
|
||||
waybar = lib.mkDefault (togglesState.waybar or schema.home.waybar);
|
||||
};
|
||||
nightlightTemperature = togglesState.nightlightTemperature or 4000;
|
||||
theme = togglesState.theme or "summer-night";
|
||||
wallpaper = togglesState.wallpaper or "";
|
||||
nightlightTemperature = lib.mkDefault (togglesState.nightlightTemperature or schema.home.nightlightTemperature);
|
||||
theme = lib.mkDefault (togglesState.theme or schema.home.theme);
|
||||
wallpaper = lib.mkDefault (togglesState.wallpaper or schema.home.wallpaper);
|
||||
panelPosition = lib.mkDefault (togglesState.panelPosition or schema.home.panelPosition);
|
||||
hyprland = {
|
||||
gaps_in = togglesState.hyprland.gaps_in or 5;
|
||||
gaps_out = togglesState.hyprland.gaps_out or 10;
|
||||
border_size = togglesState.hyprland.border_size or 2;
|
||||
gaps_in = lib.mkDefault (togglesState.hyprland.gaps_in or schema.home.hyprland.gaps_in);
|
||||
gaps_out = lib.mkDefault (togglesState.hyprland.gaps_out or schema.home.hyprland.gaps_out);
|
||||
border_size = lib.mkDefault (togglesState.hyprland.border_size or schema.home.hyprland.border_size);
|
||||
};
|
||||
fonts.monospace = togglesState.font or "JetBrainsMono Nerd Font";
|
||||
fonts.monospace = lib.mkDefault (togglesState.font or schema.home.font);
|
||||
|
||||
# Derived properties from the theme directory
|
||||
isLightMode = nomarchyLib.isThemeLightMode {
|
||||
themeName = togglesState.theme or "summer-night";
|
||||
isLightMode = lib.mkDefault (nomarchyLib.isThemeLightMode {
|
||||
themeName = togglesState.theme or schema.home.theme;
|
||||
inherit assetsPath;
|
||||
};
|
||||
iconsTheme = nomarchyLib.getIconsTheme {
|
||||
themeName = togglesState.theme or "summer-night";
|
||||
});
|
||||
iconsTheme = lib.mkDefault (nomarchyLib.getIconsTheme {
|
||||
themeName = togglesState.theme or schema.home.theme;
|
||||
inherit assetsPath;
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
14
core/system/accessibility.nix
Normal file
14
core/system/accessibility.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.accessibility;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.gnome.at-spi2-core.enable = lib.mkDefault true;
|
||||
|
||||
environment.systemPackages = [ pkgs.orca ];
|
||||
|
||||
environment.variables.XCURSOR_SIZE = toString cfg.cursorSize;
|
||||
};
|
||||
}
|
||||
17
core/system/branding.nix
Normal file
17
core/system/branding.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
# Identify the distribution as Nomarchy in /etc/os-release.
|
||||
# Anything that reads os-release picks this up: fastfetch, login banners,
|
||||
# GUI "About" dialogs, neofetch, etc.
|
||||
system.nixos = {
|
||||
distroId = "nomarchy";
|
||||
distroName = "Nomarchy";
|
||||
};
|
||||
|
||||
# Ensure the bootloader entries use Nomarchy instead of NixOS
|
||||
boot.loader.grub.configurationName = lib.mkDefault "Nomarchy";
|
||||
# For systemd-boot, NixOS 24.11+ uses distroName if available,
|
||||
# but some older versions or specific setups might need explicit labels.
|
||||
# We use mkDefault so users can still override if they want.
|
||||
}
|
||||
23
core/system/containers.nix
Normal file
23
core/system/containers.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.containers;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
# `docker` and `docker-compose` invocations transparently route to
|
||||
# podman. Pairs cleanly with rootless mode.
|
||||
dockerCompat = true;
|
||||
defaultNetwork.settings.dns_enabled = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
podman
|
||||
podman-compose
|
||||
podman-tui
|
||||
dive
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
imports = [
|
||||
./options.nix
|
||||
./state.nix
|
||||
./branding.nix
|
||||
./graphics.nix
|
||||
./nix.nix
|
||||
./scripts.nix
|
||||
@@ -16,12 +17,23 @@
|
||||
./network.nix
|
||||
./impermanence.nix
|
||||
./browser.nix
|
||||
./makima.nix
|
||||
# Tier 1 system features (all opt-in via nomarchy.system.*).
|
||||
./snapper.nix
|
||||
./laptop.nix
|
||||
./desktop.nix
|
||||
./accessibility.nix
|
||||
./gaming.nix
|
||||
./hibernate.nix
|
||||
./containers.nix
|
||||
./pam.nix
|
||||
./input-method.nix
|
||||
../../themes/engine/plymouth.nix
|
||||
../../themes/engine/sddm.nix
|
||||
];
|
||||
|
||||
time.timeZone = lib.mkDefault config.nomarchy.system.timezone;
|
||||
|
||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
}
|
||||
|
||||
15
core/system/desktop.nix
Normal file
15
core/system/desktop.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.desktop;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
|
||||
|
||||
# No-op until the user adds ZFS to boot.supportedFilesystems and a pool;
|
||||
# then maintenance kicks in without further config.
|
||||
services.zfs.autoScrub.enable = lib.mkDefault true;
|
||||
services.zfs.trim.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -5,7 +5,7 @@ let
|
||||
pname = "nomarchy-font";
|
||||
version = "1.0";
|
||||
# Point directly to the font file
|
||||
src = ./../home/config/Nomarchy.ttf;
|
||||
src = ./../branding/Nomarchy.ttf;
|
||||
# No archive to unpack
|
||||
unpackPhase = "true";
|
||||
installPhase = ''
|
||||
|
||||
20
core/system/gaming.nix
Normal file
20
core/system/gaming.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.gaming;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.steam = {
|
||||
enable = true;
|
||||
remotePlay.openFirewall = lib.mkDefault true;
|
||||
localNetworkGameTransfers.openFirewall = lib.mkDefault true;
|
||||
};
|
||||
|
||||
# gamemode adjusts CPU governor and reschedules processes when a
|
||||
# game requests it. The launching user must be in the `gamemode` group.
|
||||
programs.gamemode.enable = true;
|
||||
|
||||
services.flatpak.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -10,9 +10,18 @@ in
|
||||
isT2Mac = mkEnableOption "Apple T2 MacBook specific hardware fixes";
|
||||
isFramework = mkEnableOption "Framework laptop specific hardware fixes";
|
||||
hasIPU7Camera = mkEnableOption "Intel IPU7 camera support";
|
||||
fwupd = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable fwupd firmware update service.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.fwupd {
|
||||
services.fwupd.enable = true;
|
||||
})
|
||||
|
||||
(mkIf cfg.isXPS {
|
||||
services.udev.extraRules = ''
|
||||
ACTION=="add", SUBSYSTEM=="pci", KERNEL=="0000:00:19.0", ATTR{power/control}="on"
|
||||
@@ -61,8 +70,47 @@ in
|
||||
})
|
||||
|
||||
(mkIf config.nomarchy.system.features.hybridGPU {
|
||||
# supergfxd manages mode switching (Integrated / Hybrid / Vfio /
|
||||
# AsusEgpu). It blacklists/unblacklists the nvidia kernel module via
|
||||
# /etc/modprobe.d/ depending on the active mode. ExecStartPre sleep
|
||||
# gives udev time to settle so the daemon doesn't see a half-attached
|
||||
# GPU on cold boot.
|
||||
services.supergfxd.enable = true;
|
||||
systemd.services.supergfxd.serviceConfig.ExecStartPre = "-${pkgs.coreutils}/bin/sleep 5";
|
||||
|
||||
# Load the NVIDIA driver so the dGPU has something to drive. Without
|
||||
# these, supergfxd switches modes successfully but the X/Wayland
|
||||
# stack has no NVIDIA driver loaded — render-offload silently no-ops
|
||||
# and Hyprland renders everything on the iGPU regardless of mode.
|
||||
# mkDefault throughout so downstream system.nix can override
|
||||
# (pin to a beta driver, flip to the open kernel module, etc.).
|
||||
services.xserver.videoDrivers = lib.mkDefault [ "nvidia" ];
|
||||
hardware.graphics.enable = lib.mkDefault true;
|
||||
hardware.graphics.enable32Bit = lib.mkDefault true;
|
||||
hardware.nvidia = {
|
||||
modesetting.enable = lib.mkDefault true;
|
||||
powerManagement.enable = lib.mkDefault true;
|
||||
open = lib.mkDefault false;
|
||||
package = lib.mkDefault config.boot.kernelPackages.nvidiaPackages.stable;
|
||||
};
|
||||
# Required for Wayland compositors (Hyprland) to render via NVIDIA.
|
||||
boot.kernelParams = [ "nvidia-drm.modeset=1" ];
|
||||
|
||||
# PRIME render-offload (the part that lets `nvidia-offload <cmd>`
|
||||
# actually use the dGPU) needs bus IDs, which are per-machine.
|
||||
# We deliberately don't enable `hardware.nvidia.prime.offload.enable`
|
||||
# here — without the correct intelBusId / nvidiaBusId the nvidia
|
||||
# kernel module panics on load. The user adds this to their own
|
||||
# /etc/nixos/system.nix after running `lspci -D`:
|
||||
#
|
||||
# hardware.nvidia.prime = {
|
||||
# offload.enable = true;
|
||||
# offload.enableOffloadCmd = true;
|
||||
# intelBusId = "PCI:0:2:0"; # or amdgpuBusId for AMD iGPU
|
||||
# nvidiaBusId = "PCI:1:0:0";
|
||||
# };
|
||||
#
|
||||
# See docs/OPTIONS.md for the full recipe.
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
24
core/system/hibernate.nix
Normal file
24
core/system/hibernate.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.hibernation;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Wait this long after suspend before hibernating, and use the same
|
||||
# delay as the idle-action timeout so the two paths agree.
|
||||
systemd.sleep.extraConfig = ''
|
||||
HibernateDelaySec=${toString (cfg.idleMinutes * 60)}
|
||||
'';
|
||||
|
||||
services.logind = {
|
||||
settings.Login = {
|
||||
HandleLidSwitch = lib.mkDefault "suspend-then-hibernate";
|
||||
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
||||
HandlePowerKey = lib.mkDefault "hibernate";
|
||||
IdleAction = lib.mkDefault "suspend-then-hibernate";
|
||||
IdleActionSec = lib.mkDefault (toString (cfg.idleMinutes * 60));
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -10,13 +10,39 @@ in
|
||||
|
||||
options.nomarchy.system.impermanence = {
|
||||
enable = lib.mkEnableOption "Erase Your Darlings (Impermanence) root wipe on boot";
|
||||
|
||||
# The disko layout names the main LUKS mapping `crypted` on single-disk
|
||||
# installs and `crypted_main` on multi-disk installs (see
|
||||
# installer/disko-config.nix: `mainLuksName`). The rollback hook must
|
||||
# mount the right device, otherwise initrd fails on every boot and the
|
||||
# @ → root-blank snapshot is never restored.
|
||||
mainLuksName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "crypted";
|
||||
description = ''
|
||||
Name of the /dev/mapper entry holding the BTRFS root. Set to
|
||||
"crypted_main" on multi-disk installs to match the disko layout.
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nomarchy";
|
||||
description = ''
|
||||
Primary user whose home subset (.ssh, .gnupg, keyrings, common
|
||||
directories) survives the rootfs wipe. Must match the user
|
||||
created via `users.users.<name>` — otherwise the persistence
|
||||
block is silently inert and the user's home directory is wiped
|
||||
on every boot. The installer writes this for you.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
mount -o subvol=/ /dev/mapper/${cfg.mainLuksName} /btrfs_tmp
|
||||
|
||||
if [[ -e /btrfs_tmp/@ ]]; then
|
||||
mkdir -p /btrfs_tmp/old_roots
|
||||
@@ -58,7 +84,7 @@ in
|
||||
"/etc/machine-id"
|
||||
"/etc/supergfxd.conf"
|
||||
];
|
||||
users.nomarchy = {
|
||||
users.${cfg.user} = {
|
||||
directories = [
|
||||
".ssh"
|
||||
".gnupg"
|
||||
|
||||
22
core/system/input-method.nix
Normal file
22
core/system/input-method.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.inputMethod;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# NixOS's i18n.inputMethod handles env vars (GTK_IM_MODULE, QT_IM_MODULE,
|
||||
# XMODIFIERS, SDL_IM_MODULE) and the fcitx5-daemon autostart for us, so
|
||||
# we don't ship a manual environment.d file or Hyprland exec-once.
|
||||
i18n.inputMethod = {
|
||||
enable = true;
|
||||
type = "fcitx5";
|
||||
fcitx5.addons = with pkgs; [
|
||||
fcitx5-mozc # Japanese
|
||||
fcitx5-chinese-addons # Chinese (pinyin/shuangpin)
|
||||
fcitx5-table-extra # Hanyu/Cangjie/etc.
|
||||
fcitx5-gtk # GTK4/3 client
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
42
core/system/laptop.nix
Normal file
42
core/system/laptop.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.laptop;
|
||||
hib = config.nomarchy.system.hibernation;
|
||||
lidAction = if hib.enable then "suspend-then-hibernate" else "suspend";
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.tlp = {
|
||||
enable = lib.mkDefault true;
|
||||
settings = {
|
||||
CPU_SCALING_GOVERNOR_ON_AC = lib.mkDefault "performance";
|
||||
CPU_SCALING_GOVERNOR_ON_BAT = lib.mkDefault "powersave";
|
||||
CPU_BOOST_ON_BAT = lib.mkDefault 0;
|
||||
PLATFORM_PROFILE_ON_AC = lib.mkDefault "balanced";
|
||||
PLATFORM_PROFILE_ON_BAT = lib.mkDefault "low-power";
|
||||
# Charge thresholds only honored on supported hardware (ThinkPad,
|
||||
# some ASUS); a harmless warning is logged elsewhere.
|
||||
START_CHARGE_THRESH_BAT0 = lib.mkDefault 75;
|
||||
STOP_CHARGE_THRESH_BAT0 = lib.mkDefault 80;
|
||||
};
|
||||
};
|
||||
|
||||
# TLP and power-profiles-daemon both arbitrate CPU/EPP — NixOS asserts
|
||||
# mutual exclusion. Opt out of the preset entirely to use PPD instead.
|
||||
services.power-profiles-daemon.enable = lib.mkForce false;
|
||||
|
||||
services.upower.enable = lib.mkDefault true;
|
||||
services.thermald.enable = lib.mkDefault cfg.thermald;
|
||||
|
||||
# Backlight write access for the `video` group, so the existing
|
||||
# nomarchy-brightness-{display,keyboard} scripts run without root.
|
||||
services.udev.packages = [ pkgs.brightnessctl ];
|
||||
|
||||
services.logind.settings.Login = {
|
||||
HandleLidSwitch = lib.mkDefault lidAction;
|
||||
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
||||
HandleLidSwitchDocked = lib.mkDefault "ignore";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.features.makima;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg {
|
||||
# If the user has makima-bin available in their overlays (as they originally used a custom package),
|
||||
# this will install it. Otherwise, it will fail evaluation if not available in nixpkgs.
|
||||
environment.systemPackages = [ pkgs.makima-bin ];
|
||||
|
||||
environment.etc."makima/AT Translated Set 2 keyboard.toml".source = ../../features/apps/makima + "/AT Translated Set 2 keyboard.toml";
|
||||
|
||||
systemd.services.makima = {
|
||||
description = "Makima key remapping service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
User = config.services.displayManager.autoLogin.user;
|
||||
Environment = "MAKIMA_CONFIG=/etc/makima";
|
||||
ExecStart = "${pkgs.makima-bin}/bin/makima";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -25,4 +25,8 @@ in
|
||||
DNSOverTLS=opportunistic
|
||||
'';
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.networkmanagerapplet
|
||||
];
|
||||
}
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
|
||||
# Optimize storage by hard-linking identical files
|
||||
auto-optimise-store = lib.mkDefault true;
|
||||
|
||||
# Bump the substituter download buffer from the 64 MiB default to
|
||||
# 512 MiB. Large NARs (kernels, electron apps, the full NixOS
|
||||
# closure on first install) overrun 64 MiB and Nix prints
|
||||
# "download buffer is full" until the consumer catches up — the
|
||||
# warning is harmless but slows substitution and looks like an
|
||||
# error. 512 MiB comfortably covers everything in our closure.
|
||||
download-buffer-size = 524288000;
|
||||
};
|
||||
|
||||
# Populates NIX_PATH with the nixpkgs input from the flake.
|
||||
|
||||
@@ -1,55 +1,216 @@
|
||||
{ lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# Defaults live in lib/state-schema.nix so they can't drift between this
|
||||
# file, core/home/options.nix, and core/home/state.nix's `or` fallbacks.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
options.nomarchy.system = {
|
||||
dns = lib.mkOption {
|
||||
type = lib.types.enum [ "Cloudflare" "Google" "DHCP" "Custom" ];
|
||||
default = "DHCP";
|
||||
default = schema.system.dns;
|
||||
description = "Selected DNS provider.";
|
||||
};
|
||||
customDns = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
default = schema.system.customDns;
|
||||
description = "List of custom DNS servers.";
|
||||
};
|
||||
wifi = {
|
||||
powersave = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.system.wifi.powersave;
|
||||
description = "Whether to enable wifi power saving.";
|
||||
};
|
||||
};
|
||||
timezone = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "UTC";
|
||||
default = schema.system.timezone;
|
||||
description = "System timezone.";
|
||||
};
|
||||
formFactor = lib.mkOption {
|
||||
type = lib.types.enum [ "laptop" "desktop" ];
|
||||
default = "laptop";
|
||||
description = ''
|
||||
Physical form factor. Drives UI affordances (battery widget,
|
||||
future lid handling / TLP). Default "laptop" — battery widget
|
||||
is harmless on a desktop (renders empty when no BAT* is
|
||||
present), so the safe default is "show, don't hide". The
|
||||
installer auto-detects via /sys/class/power_supply/BAT* and
|
||||
writes the explicit value into the generated system.nix.
|
||||
'';
|
||||
};
|
||||
features = {
|
||||
fingerprint = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.fingerprint;
|
||||
description = "Whether to enable fingerprint support.";
|
||||
};
|
||||
fido2 = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.fido2;
|
||||
description = "Whether to enable FIDO2 support.";
|
||||
};
|
||||
hybridGPU = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.hybridGPU;
|
||||
description = "Whether to enable hybrid GPU support (supergfxd).";
|
||||
};
|
||||
makima = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable makima key remapper.";
|
||||
};
|
||||
};
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "summer-night";
|
||||
default = schema.system.theme;
|
||||
description = "Selected system theme.";
|
||||
};
|
||||
|
||||
# ----- Tier 1 system features (all opt-in, no behavioural change off) ---
|
||||
|
||||
snapper = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Snapper-driven BTRFS timeline snapshots of `/`. Auto-disables when
|
||||
`/` isn't BTRFS. Includes a `nixos-rebuild-snap` wrapper that takes
|
||||
a "Pre-rebuild" snapshot before each switch.
|
||||
'';
|
||||
};
|
||||
|
||||
hibernation = {
|
||||
enable = lib.mkEnableOption ''
|
||||
suspend-then-hibernate (lid close, idle, power button). NOTE: this
|
||||
requires a disk swap device or swapfile sized to at least RAM —
|
||||
zRAM alone is not enough.
|
||||
'';
|
||||
idleMinutes = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 30;
|
||||
description = "Idle minutes before suspend-then-hibernate fires.";
|
||||
};
|
||||
};
|
||||
|
||||
laptop = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.nomarchy.system.formFactor == "laptop";
|
||||
defaultText = lib.literalExpression ''config.nomarchy.system.formFactor == "laptop"'';
|
||||
description = ''
|
||||
Laptop power preset: TLP (with sane AC/battery governors),
|
||||
`services.upower`, `services.thermald` (x86_64), a brightnessctl
|
||||
udev rule, and a logind lid-switch policy. Force-disables
|
||||
`services.power-profiles-daemon` (mutually exclusive with TLP).
|
||||
Lid-close defers to `nomarchy.system.hibernation.enable`:
|
||||
suspend-then-hibernate when on, suspend otherwise. Defaults on
|
||||
when `formFactor = "laptop"`.
|
||||
'';
|
||||
};
|
||||
thermald = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = pkgs.stdenv.hostPlatform.isx86_64;
|
||||
defaultText = lib.literalExpression "pkgs.stdenv.hostPlatform.isx86_64";
|
||||
description = ''
|
||||
Enable `services.thermald` (Intel thermal daemon). Default true on
|
||||
x86_64. Harmless no-op on AMD; gated off on aarch64.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
desktop = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.nomarchy.system.formFactor == "desktop";
|
||||
defaultText = lib.literalExpression ''config.nomarchy.system.formFactor == "desktop"'';
|
||||
description = ''
|
||||
Desktop preset: pins `powerManagement.cpuFreqGovernor` to
|
||||
`"performance"` and enables `services.zfs.autoScrub` and
|
||||
`services.zfs.trim` so a future ZFS pool gets sensible
|
||||
maintenance without further config. The ZFS knobs are no-ops
|
||||
until the user adds `boot.supportedFilesystems = [ "zfs" ]`
|
||||
and a pool. Defaults on when `formFactor = "desktop"`. Battery
|
||||
widget filtering is already handled by `formFactor` itself in
|
||||
`features/desktop/waybar/default.nix`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
accessibility = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Accessibility preset: AT-SPI2 framework, the Orca screen reader
|
||||
on PATH, and a larger default cursor size. Off by default —
|
||||
accessibility is a personal preference, not a hardware-derived
|
||||
signal. The Hyprland-side keybinding to launch Orca is a
|
||||
separate roadmap item.
|
||||
'';
|
||||
cursorSize = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 32;
|
||||
description = ''
|
||||
XCURSOR_SIZE when accessibility is on. NixOS default is 24;
|
||||
32 is a safer floor for low-vision users. Bump to 48 if the
|
||||
user explicitly asks.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
gaming = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Gaming preset: Steam (with remote-play firewall holes),
|
||||
gamemode (CPU governor + nice on Steam launch via the user's
|
||||
gamemode group), and flatpak. NOTE: flatpak's flathub remote
|
||||
is not added declaratively — after first boot, run
|
||||
`flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo`.
|
||||
The Hyprland fullscreen-on-Steam-launch window rule is a
|
||||
separate roadmap item.
|
||||
'';
|
||||
};
|
||||
|
||||
containers = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Rootless Podman with Docker compatibility (`docker` → `podman`),
|
||||
plus podman-compose, podman-tui and dive.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualization = {
|
||||
libvirt = {
|
||||
enable = lib.mkEnableOption ''
|
||||
libvirt daemon + virt-manager + OVMF. The user must be in the
|
||||
`libvirtd` group.
|
||||
'';
|
||||
};
|
||||
docker = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Docker daemon + docker-compose. The user must be in the `docker`
|
||||
group.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
keyring = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Auto-unlock GNOME Keyring at SDDM/Hyprland login and route SSH
|
||||
keys through `gcr-ssh-agent`. Default on — near-universal QoL
|
||||
improvement.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
inputMethod = {
|
||||
enable = lib.mkEnableOption ''
|
||||
fcitx5 input method (CJK / IME). Wires NixOS's i18n.inputMethod and
|
||||
autostarts fcitx5-daemon. Adds a small footprint when enabled, so
|
||||
most users want this off.
|
||||
'';
|
||||
};
|
||||
|
||||
voxtype = {
|
||||
enable = lib.mkEnableOption ''
|
||||
voxtype voice-typing integration. NOTE: voxtype is not packaged in
|
||||
nixpkgs — when enabled, install voxtype yourself (e.g. via
|
||||
`home.packages = [ (pkgs.callPackage … {}) ]`). With this off the
|
||||
SUPER+CTRL+X keybinding and waybar widget are no-ops.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
28
core/system/pam.nix
Normal file
28
core/system/pam.nix
Normal file
@@ -0,0 +1,28 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.keyring;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Auto-unlock GNOME Keyring at SDDM autologin and at login. hyprlock
|
||||
# gets the same treatment so the session keyring stays unlocked when
|
||||
# the screen lock disengages.
|
||||
security.pam.services = {
|
||||
login.enableGnomeKeyring = true;
|
||||
sddm.enableGnomeKeyring = true;
|
||||
hyprlock.enableGnomeKeyring = true;
|
||||
};
|
||||
|
||||
# Run the keyring + the gcr SSH agent. Disabling `programs.ssh.startAgent`
|
||||
# ensures keys flow through the keyring's agent (so unlock-on-login
|
||||
# carries over to ssh) instead of a separate ssh-agent process.
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
services.gnome.gcr-ssh-agent.enable = true;
|
||||
programs.ssh.startAgent = lib.mkForce false;
|
||||
|
||||
# Point downstream tooling at the gcr socket so `ssh` / `git` / etc.
|
||||
# find the keyring's keys without per-user shell config.
|
||||
environment.sessionVariables.SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/gcr/ssh";
|
||||
};
|
||||
}
|
||||
@@ -30,6 +30,9 @@ let
|
||||
bc
|
||||
supergfxctl
|
||||
systemd
|
||||
fwupd
|
||||
hyprland
|
||||
swayosd
|
||||
];
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
@@ -52,8 +55,7 @@ pkgs.stdenv.mkDerivation {
|
||||
for file in $out/bin/*; do
|
||||
if [ -f "$file" ]; then
|
||||
wrapProgram "$file" \
|
||||
--prefix PATH : "$deps" \
|
||||
--set NOMARCHY_PATH "/etc/nixos/nomarchy"
|
||||
--prefix PATH : "$deps"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
@@ -2,4 +2,13 @@
|
||||
|
||||
{
|
||||
environment.systemPackages = [ pkgs.nomarchy-system-scripts ];
|
||||
|
||||
# /etc/nixos is owned by root, but `nomarchy-env-update` (and `nix
|
||||
# flake` invocations) run as the user and shell out to git. Without
|
||||
# this, git refuses with "dubious ownership in repository" and HM
|
||||
# evaluation fails. Mark both the standard and impermanence-relocated
|
||||
# paths as safe at the system level so every user is covered.
|
||||
programs.git.config = {
|
||||
safe.directory = [ "/etc/nixos" "/persist/etc/nixos" ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns the battery full capacity in Wh (rounded to whole number).
|
||||
# Used by nomarchy-battery-status for displaying battery capacity.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Designed to be run by systemd timer every 30 seconds and alerts if battery is low
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if a battery is present on the system.
|
||||
# Used by the battery monitor and other battery-related checks.
|
||||
|
||||
for bat in /sys/class/power_supply/BAT*; do
|
||||
[[ -r $bat/present ]] &&
|
||||
[[ $(cat $bat/present) == "1" ]] &&
|
||||
[[ $(cat $bat/type) == "Battery" ]] &&
|
||||
exit 0
|
||||
done
|
||||
|
||||
exit 1
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns the battery percentage remaining as an integer.
|
||||
# Used by the battery monitor and the Ctrl + Shift + Super + B hotkey.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns the battery time remaining (to empty or full) in a compact format.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns a formatted battery status string with percentage and power draw/charge.
|
||||
# Used by the battery notification hotkey (Ctrl + Shift + Super + B).
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Adjust brightness on the most likely display device.
|
||||
# Usage: nomarchy-brightness-display <step>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Adjust the brightness on Apple Studio Displays and Apple XDR Displays using asdcontrol.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Adjust keyboard backlight brightness using available steps.
|
||||
# Usage: nomarchy-brightness-keyboard <up|down|cycle>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Check if hibernation is supported
|
||||
if [[ ! -f /sys/power/image_size ]]; then
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Removes hibernation setup: disables swap, removes swapfile, removes fstab entry,
|
||||
# removes resume hook, and removes suspend-then-hibernate configuration.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Creates a swap file in the btrfs subvolume, adds the swap file to /etc/fstab,
|
||||
# adds a resume hook to mkinitcpio, and configures suspend-then-hibernate.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Detect whether the computer is an Asus ROG machine.
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer is a Framework Laptop 16.
|
||||
|
||||
[[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Framework" ]] &&
|
||||
nomarchy-hw-match "Laptop 16"
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer has an Intel CPU.
|
||||
|
||||
[[ $(grep -m1 "vendor_id" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | tr -d ' ') == "GenuineIntel" ]]
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer has an Intel Panther Lake GPU.
|
||||
|
||||
lspci | grep -iE 'vga|3d|display' | grep -qi 'panther lake'
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Match against the computer's DMI product name (case-insensitive).
|
||||
# Usage: nomarchy-hw-match "XPS"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer is a Microsoft Surface device.
|
||||
|
||||
[[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Microsoft Corporation" ]] &&
|
||||
nomarchy-hw-match "Surface"
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Detect whether Vulkan is available.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns a list of all the available power profiles on the system.
|
||||
# Used by the Nomarchy Menu under Setup > Power Profile.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Unblock and restart the bluetooth service.
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Restart makima - key remapping service for remapping Copilot key to Nomarchy Menu
|
||||
|
||||
sudo systemctl restart makima
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Restart the PipeWire audio service to fix audio issues or apply new configuration.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Reload the intel_quicki2c driver to fix a dead trackpad.
|
||||
# The THC (Touch Host Controller) can fail to initialize interrupts
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Unblock and restart the Wi-Fi service.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Restart the XCompose input method service (fcitx5) to apply new compose key settings.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Configure DNS declaratively for Nomarchy NixOS.
|
||||
# Hybrid: updates /etc/nixos/state.json and runs sys-update.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Configure FIDO2 support declaratively for Nomarchy NixOS.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Configure fingerprint support declaratively for Nomarchy NixOS.
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Prompt for sudo once and keep the credential alive in the background.
|
||||
# Source this script so the trap applies to the calling shell:
|
||||
# source nomarchy-sudo-keepalive
|
||||
|
||||
sudo -v
|
||||
while true; do sudo -n true; sleep 60; done 2>/dev/null &
|
||||
SUDO_KEEPALIVE_PID=$!
|
||||
trap "kill $SUDO_KEEPALIVE_PID 2>/dev/null" EXIT
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Toggle passwordless sudo for the current user.
|
||||
# First run: enables passwordless sudo for 15 minutes (after confirmation).
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Reset the sudo lockout/faillock for the current user.
|
||||
# This clears any failed authentication attempts that may have locked the user out.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Display brightness level using SwayOSD on the current monitor.
|
||||
# Usage: nomarchy-swayosd-brightness <percent>
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Display keyboard brightness level using SwayOSD on the current monitor.
|
||||
# Usage: nomarchy-swayosd-kbd-brightness <percent>
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Logout command that first closes all application windows (thus giving them a chance to save state),
|
||||
# then stops the session, returning to the SDDM login screen.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Reboot command that first closes all application windows (thus giving them a chance to save state).
|
||||
# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Shutdown command that first closes all application windows (thus giving them a chance to save state).
|
||||
# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14).
|
||||
# Declarative enablement + Runtime mode switching for Nomarchy NixOS.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Toggles the idle daemon (hypridle) between enabled and disabled.
|
||||
# Hybrid: updates state.json and provides instant feedback.
|
||||
|
||||
@@ -1,29 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Toggles the suspend menu option availability.
|
||||
# Hybrid: updates state.json and runs env-update for persistence.
|
||||
|
||||
STATE_DIR="$HOME/.config/nomarchy"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
# Initialize if doesn't exist
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# Get current state from env or state file
|
||||
if [[ $NOMARCHY_TOGGLE_SUSPEND == "false" ]]; then
|
||||
NEW_VALUE="true"
|
||||
notify-send -u low " Suspend now available in system menu"
|
||||
else
|
||||
NEW_VALUE="false"
|
||||
notify-send -u low " Suspend removed from system menu"
|
||||
fi
|
||||
|
||||
# Update JSON using jq with --argjson for proper boolean handling
|
||||
TMP_JSON=$(mktemp)
|
||||
jq --argjson val "$NEW_VALUE" '.suspend = $val' "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
|
||||
echo "Suspend availability set to $NEW_VALUE. Updating environment..."
|
||||
|
||||
# Run nomarchy-env-update to apply changes to the menu
|
||||
nomarchy-env-update
|
||||
# Execute system suspend
|
||||
systemctl suspend
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Select system timezone declaratively for Nomarchy NixOS.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Updating time..."
|
||||
sudo systemctl restart systemd-timesyncd
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Toggles wifi power saving declaratively.
|
||||
# Usage: nomarchy-wifi-powersave <on|off>
|
||||
|
||||
42
core/system/snapper.nix
Normal file
42
core/system/snapper.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.snapper;
|
||||
rootIsBtrfs = (config.fileSystems."/".fsType or "") == "btrfs";
|
||||
active = cfg.enable && rootIsBtrfs;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf active {
|
||||
# `nixos-rebuild-snap`: take a Snapper pre-rebuild snapshot, then run
|
||||
# `nixos-rebuild switch` against the current host. The hostname is read
|
||||
# from the running config so this script works on every machine without
|
||||
# editing.
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "nixos-rebuild-snap" ''
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root (use sudo)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Creating pre-rebuild snapshot..."
|
||||
${pkgs.snapper}/bin/snapper -c root create \
|
||||
-d "Pre-rebuild $(date +'%Y-%m-%d %H:%M:%S')" \
|
||||
--cleanup-algorithm number
|
||||
echo "Rebuilding..."
|
||||
nixos-rebuild switch --flake .#${config.networking.hostName} "$@"
|
||||
'')
|
||||
];
|
||||
|
||||
services.snapper.configs = {
|
||||
root = {
|
||||
SUBVOLUME = "/";
|
||||
TIMELINE_CREATE = true;
|
||||
TIMELINE_CLEANUP = true;
|
||||
TIMELINE_LIMIT_HOURLY = "5";
|
||||
TIMELINE_LIMIT_DAILY = "7";
|
||||
TIMELINE_LIMIT_WEEKLY = "0";
|
||||
TIMELINE_LIMIT_MONTHLY = "0";
|
||||
TIMELINE_LIMIT_YEARLY = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -2,20 +2,28 @@
|
||||
|
||||
let
|
||||
nomarchyLib = import ../../lib { inherit lib; };
|
||||
# Same canonical schema as core/home/state.nix and the options.nix
|
||||
# files — keeps every state default in one place.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
systemState = nomarchyLib.readSystemState;
|
||||
in
|
||||
{
|
||||
# Every assignment is lib.mkDefault so a downstream /etc/nixos/system.nix
|
||||
# can still set e.g. `nomarchy.system.features.hybridGPU = true;`
|
||||
# without colliding with the state.json-derived value. Without
|
||||
# mkDefault, every state.json-driven option was unoverridable from
|
||||
# Nix — flipping hybridGPU required jq'ing the state file rather
|
||||
# than declaring it in your config.
|
||||
config.nomarchy.system = {
|
||||
dns = systemState.dns or "DHCP";
|
||||
customDns = systemState.customDns or [];
|
||||
wifi.powersave = systemState.wifi.powersave or true;
|
||||
timezone = systemState.timezone or "UTC";
|
||||
dns = lib.mkDefault (systemState.dns or schema.system.dns);
|
||||
customDns = lib.mkDefault (systemState.customDns or schema.system.customDns);
|
||||
wifi.powersave = lib.mkDefault (systemState.wifi.powersave or schema.system.wifi.powersave);
|
||||
timezone = lib.mkDefault (systemState.timezone or schema.system.timezone);
|
||||
features = {
|
||||
fingerprint = systemState.features.fingerprint or false;
|
||||
fido2 = systemState.features.fido2 or false;
|
||||
hybridGPU = systemState.features.hybridGPU or false;
|
||||
makima = systemState.features.makima or false;
|
||||
fingerprint = lib.mkDefault (systemState.features.fingerprint or schema.system.features.fingerprint);
|
||||
fido2 = lib.mkDefault (systemState.features.fido2 or schema.system.features.fido2);
|
||||
hybridGPU = lib.mkDefault (systemState.features.hybridGPU or schema.system.features.hybridGPU);
|
||||
};
|
||||
theme = systemState.theme or "nord";
|
||||
theme = lib.mkDefault (systemState.theme or schema.system.theme);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
{ lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
libvirt = config.nomarchy.system.virtualization.libvirt.enable;
|
||||
docker = config.nomarchy.system.virtualization.docker.enable;
|
||||
in
|
||||
{
|
||||
# uwsm + Hyprland session — present on every Nomarchy install regardless
|
||||
# of the optional libvirt branch below.
|
||||
programs.uwsm = {
|
||||
enable = lib.mkDefault true;
|
||||
waylandCompositors.hyprland = {
|
||||
@@ -8,4 +14,23 @@
|
||||
prettyName = "Hyprland";
|
||||
};
|
||||
};
|
||||
|
||||
# Optional: libvirt + virt-manager + OVMF. Toggle with
|
||||
# `nomarchy.system.virtualization.libvirt.enable = true;`. The user must
|
||||
# be in the `libvirtd` group to drive virsh / virt-manager.
|
||||
virtualisation.libvirtd.enable = lib.mkIf libvirt true;
|
||||
|
||||
# Optional: Docker + docker-compose.
|
||||
virtualisation.docker.enable = lib.mkIf docker true;
|
||||
|
||||
environment.systemPackages = lib.mkMerge [
|
||||
(lib.mkIf libvirt (with pkgs; [
|
||||
virt-manager
|
||||
qemu
|
||||
OVMF
|
||||
]))
|
||||
(lib.mkIf docker (with pkgs; [
|
||||
docker-compose
|
||||
]))
|
||||
];
|
||||
}
|
||||
|
||||
247
docs/AGENT.md
Normal file
247
docs/AGENT.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# Agent Instructions for Nomarchy
|
||||
|
||||
You're an AI coding agent picking up the Nomarchy project. This document gives you everything you need to be useful from the first turn: what Nomarchy is, how it's organized, what the rules are, and how to actually pick up the next piece of work.
|
||||
|
||||
If anything below conflicts with what the user just said, the user wins. If anything below conflicts with the existing code, read the code — these notes can rot.
|
||||
|
||||
---
|
||||
|
||||
## 1. What Nomarchy is
|
||||
|
||||
Nomarchy is a NixOS-based distribution that ships a highly curated Hyprland desktop on a strictly declarative, flake-based foundation. It targets power users who want a polished, reproducible desktop environment.
|
||||
|
||||
Concretely:
|
||||
|
||||
- A flake at the repo root exposes `nixosModules.system` (foundational OS modules) and `nixosModules.home` (apps + desktop), plus three `nixosConfigurations` (`nomarchy-installer`, `nomarchy-live`, `default`) and standalone `homeConfigurations`.
|
||||
- Downstream users get the distro by importing `nomarchy.nixosModules.system` and `nomarchy.nixosModules.home` from their own `/etc/nixos/flake.nix`. The Nomarchy installer generates that flake for them; an existing-NixOS user can hand-write it (see `docs/MIGRATION.md`).
|
||||
- A bash/`gum` TUI installer lives in `installer/install.sh` (~1100 lines). It auto-detects hardware via `installer/hardware-db.sh` (DMI + `lspci` + `BAT*` sysfs), prompts for the rest, and generates `flake.nix`, `system.nix`, `home.nix`, and `hardware-selection.nix` into `/mnt/etc/nixos/`.
|
||||
- The desktop is Hyprland + waybar + walker + a curated theming engine (`themes/`) with 22 palettes wired through Stylix.
|
||||
|
||||
Read in this order to come up to speed:
|
||||
|
||||
1. `README.md` — public face.
|
||||
2. `docs/STRUCTURE.md` — directory layout and module logic.
|
||||
3. `docs/OPTIONS.md` — every `nomarchy.*` option a downstream flake can set.
|
||||
4. `docs/ROADMAP.md` — what's planned. **This is your work queue.**
|
||||
5. `docs/SCRIPTS.md` — the script & menu audit table (Pillar 3 of the roadmap).
|
||||
6. `docs/MIGRATION.md` — how an existing NixOS install becomes Nomarchy.
|
||||
7. `docs/creating-themes.md` — when palette work comes up.
|
||||
|
||||
---
|
||||
|
||||
## 2. How the repo is organized
|
||||
|
||||
```
|
||||
core/ Foundational OS + user defaults. Don't put apps here.
|
||||
system/ NixOS modules, all imported via core/default.nix.
|
||||
options.nix nomarchy.system.* options live here.
|
||||
hardware.nix nomarchy.hardware.* options + module wiring.
|
||||
network.nix NetworkManager, DNS, networkmanagerapplet.
|
||||
impermanence.nix Erase-Your-Darlings root wipe.
|
||||
scripts/ Low-level system scripts (battery, brightness, hardware).
|
||||
home/ Home Manager modules.
|
||||
options.nix Most home-side nomarchy.* options.
|
||||
overrides.nix nomarchy.overrides.* (reserved; currently no-op — see ROADMAP).
|
||||
config/ Plain dotfiles symlinked into ~/.config.
|
||||
|
||||
features/ Apps and desktop components. Add new apps here.
|
||||
apps/ One subdir per app (alacritty, btop, kitty, vscode.nix, …).
|
||||
desktop/ hyprland, waybar, idle.nix, nightlight.nix, …
|
||||
scripts/ User-PATH scripts, battery-monitor user service.
|
||||
utils/ ~68 nomarchy-* user scripts.
|
||||
default.nix Packages them as nomarchy-system-scripts derivation.
|
||||
|
||||
themes/ Theme engine + 22 palettes.
|
||||
engine/ Loader, Stylix glue, switcher, scripts (font, theme, wallpaper).
|
||||
palettes/ One subdir per palette (summer-night, tokyo-night, …).
|
||||
|
||||
hosts/ ISO host configs (nomarchy-installer, nomarchy-live/live-iso).
|
||||
installer/ The bash/gum TUI + disko configs + hardware-db.sh.
|
||||
lib/ Shared Nix helpers (state schema, color resolution, paths).
|
||||
docs/ All long-form documentation. README.md stays at repo root.
|
||||
bin/ Convenience wrappers for testing (nomarchy-test-installer, …).
|
||||
```
|
||||
|
||||
When you add a new feature:
|
||||
|
||||
- A new app → `features/apps/<name>/default.nix` (+ optional `config/`), import it from `features/default.nix`.
|
||||
- A new system service → `core/system/<name>.nix`, import from `core/default.nix`.
|
||||
- A new toggle → add to `core/system/options.nix` or `core/home/options.nix`, wire it into the relevant module, document it in `docs/OPTIONS.md`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Guardrails (non-negotiable unless the user overrides)
|
||||
|
||||
These are inherited from the established Nomarchy conventions. Violating them is a bug.
|
||||
|
||||
1. **Declarative-first.** No imperative state in `core/`. Mutable state goes in `~/.config/nomarchy/state.json` or in NixOS / home-manager options.
|
||||
2. **Downstream-flake friendly.** Every behavior toggle is a `nomarchy.*` option documented in `docs/OPTIONS.md`. Adding a feature without a corresponding option is a bug.
|
||||
3. **Opt-in by default.** New features default off (or default to existing behavior). The installer can flip defaults *for the user being installed*, but the option must read sensibly when set by hand.
|
||||
4. **`lib.mkDefault` everywhere user might override.** If a downstream `system.nix` would reasonably want to change something Nomarchy sets, set it with `lib.mkDefault`. If it must not be overridden, use `lib.mkForce` and explain why in a comment.
|
||||
5. **Reuse before invent.** ~155 `nomarchy-*` scripts already exist across `core/system/scripts/`, `features/scripts/utils/`, `themes/engine/scripts/`. Grep before writing a new one.
|
||||
6. **No comments that narrate.** Don't write comments explaining *what* the code does. Only write a comment when the *why* is non-obvious — a hidden constraint, a subtle invariant, a workaround.
|
||||
7. **No backwards-compat shims.** If you remove a thing, remove it everywhere. No re-exports, no `// removed` markers.
|
||||
8. **Docs ride with the change.** Every change ships in the same commit as its doc updates — no follow-up "docs catch-up" PRs. The mapping is in §5.4 below; if a change touches something in that table and the matching doc didn't move with it, the change is incomplete.
|
||||
|
||||
---
|
||||
|
||||
## 4. How to find work to do
|
||||
|
||||
The roadmap (`docs/ROADMAP.md`) is the source of truth. It has three columns and seven pillars.
|
||||
|
||||
**Default rule:** prefer items in the **Now** column. Pick whichever matches the user's current ask, or the smallest one if no ask is in flight.
|
||||
|
||||
If the user asked for something not in the roadmap:
|
||||
|
||||
- Do the work.
|
||||
- After it ships, propose a one-line addition to `docs/ROADMAP.md` so future you doesn't re-discover it.
|
||||
|
||||
If the user asks "what's next?", reply with the Now column items in 2–3 sentences and let them pick.
|
||||
|
||||
### The script & menu audit (Pillar 3)
|
||||
|
||||
This is the **largest single open work item**. Phase A (inventory) hasn't run yet; `docs/SCRIPTS.md` is just scaffolding. The user explicitly flagged this pillar as important.
|
||||
|
||||
Phase A shipped. The inventory lives at [`docs/SCRIPTS.md`](SCRIPTS.md) and is regenerated by:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
```
|
||||
|
||||
It tags every row with one of `kept` / `unused?` / `missing`. Phase B is the per-batch porting/removal: pick ~10 rows tagged `missing` or `unused?`, decide one of `port-from-omarchy` / `delete-dead` / `stub-with-notify`, and ship as one PR per batch on a `wave/audit-<batch>` branch. Each PR description should reference the rows it closes; reviewers spot-check that every caller of a removed/renamed script is updated.
|
||||
|
||||
---
|
||||
|
||||
## 5. Workflow per change
|
||||
|
||||
Steps you should follow for any non-trivial change:
|
||||
|
||||
1. **Understand the current state first.**
|
||||
- `git status` and `git log -5` so you know what's just landed and what's in flight.
|
||||
- Read the relevant files. Don't infer.
|
||||
2. **Plan if it's non-trivial.** Tasks with three or more steps benefit from a TaskCreate list. Tasks that touch the architecture benefit from plan mode.
|
||||
3. **Reuse existing options and scripts.** Grep `core/system/options.nix`, `core/home/options.nix`, and the three script directories before adding anything.
|
||||
4. **Touch the docs in the same change.** Use this table — if your change matches a row, the doc edit ships in the same commit. No exceptions, no follow-ups.
|
||||
|
||||
| If you change… | Update in the same commit |
|
||||
| --- | --- |
|
||||
| A `nomarchy.*` option (added, removed, renamed, default flipped, type changed, description changed) | `docs/OPTIONS.md` (matching row) **and** any other row that mentions it (e.g. `formFactor` is referenced from `laptop.enable`'s row) |
|
||||
| A `nomarchy-*` script (added, removed, renamed) | `docs/SCRIPTS.md` — the pre-commit hook regenerates it; verify it's staged. If `core.hooksPath` isn't set, run `./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md` manually. |
|
||||
| A keybinding (`bindd =` / `bindeld =`) under `core/home/config/.../hypr/` | `docs/KEYBINDINGS.md` — regenerate via `./bin/utils/nomarchy-docs-keybindings --out docs/KEYBINDINGS.md`; spot-check the README highlights still hold |
|
||||
| A directory was added/removed/renamed under `core/`, `features/`, `themes/`, `hosts/`, `installer/`, `lib/`, `bin/`, or `docs/` | `docs/STRUCTURE.md` (tree + module logic prose) **and** §2 of this file (`docs/AGENT.md`) if the change is structural enough to affect new-agent onboarding |
|
||||
| A feature module's behavior changed in a way an existing user would notice (a default flipped, a service started/stopped, a key remapped) | `README.md` if it's user-visible at the marketing level; otherwise just `docs/OPTIONS.md` |
|
||||
| An installer prompt added/removed/reordered, or generated-file shape changed | `docs/MIGRATION.md` if it affects hand-written `flake.nix` setups; `installer/install.sh` heredoc comments if a generated file's shape changed |
|
||||
| A theme palette added/removed, or the theming engine's contract changed | `docs/creating-themes.md` and the palette count in `README.md` |
|
||||
| A roadmap item shipped | Move the entry to the **Shipped** section at the bottom of `docs/ROADMAP.md`. Don't delete — that's our changelog. |
|
||||
| A roadmap item discovered (new scope) | Add a one-line row to **Now**, **Next**, or **Later** in `docs/ROADMAP.md`. Don't tell the user verbally and forget. |
|
||||
| A workflow / convention / guardrail you'd want a future agent to follow | `docs/AGENT.md` (this file). |
|
||||
| A new flake input, output, or major architectural decision | `docs/STRUCTURE.md` and `docs/AGENT.md` §1. |
|
||||
|
||||
Before declaring done, do one explicit pass: did the change cross any row above? If yes, is the matching doc edit staged? If you can't answer "yes" to both, you're not done.
|
||||
5. **Verify the change evaluates** (cheap, do this before declaring done):
|
||||
```bash
|
||||
nix --extra-experimental-features 'nix-command flakes' flake check --no-build
|
||||
bash -n installer/install.sh # if you touched it
|
||||
```
|
||||
First clone? Enable the repo's pre-commit hook so `docs/SCRIPTS.md` regenerates whenever you add/modify/remove a `nomarchy-*` script:
|
||||
```bash
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
For installer changes, also do a dry-run end-to-end:
|
||||
```bash
|
||||
sudo /etc/install.sh --dry-run # in the live ISO or VM
|
||||
```
|
||||
For waybar / Hyprland visual changes, the only reliable check is booting the live ISO with `nomarchy-test-live-iso`. If you can't boot it, **say so** rather than claiming success.
|
||||
6. **Commit narrowly.** One concept per commit. The commit subject is `<type>: <imperative summary>` (`feat:`, `fix:`, `docs:`, `chore:`). The body explains the why.
|
||||
7. **Push only when the user asks.** Local commits are free; pushing publishes.
|
||||
|
||||
---
|
||||
|
||||
## 6. Patterns worth knowing
|
||||
|
||||
### Adding a new option
|
||||
|
||||
```nix
|
||||
# core/system/options.nix (or core/home/options.nix for home-side)
|
||||
mything.enable = lib.mkEnableOption ''
|
||||
Concise description that reads well in `nix eval`. Mention any
|
||||
pre-conditions (groups, kernel modules, hardware needed).
|
||||
'';
|
||||
```
|
||||
|
||||
Then wire it inside a `config = lib.mkIf cfg.mything.enable { ... }` block and document it in `docs/OPTIONS.md`.
|
||||
|
||||
### Filtering modules conditionally
|
||||
|
||||
We do this for waybar (drop `battery` on desktop) in `features/desktop/waybar/default.nix:25-39`. Pattern:
|
||||
|
||||
```nix
|
||||
let
|
||||
rawSettings = builtins.fromJSON (builtins.readFile configFile);
|
||||
laptopOnly = [ "battery" "custom/battery" ];
|
||||
filterModules = mods:
|
||||
if config.nomarchy.formFactor == "laptop" then mods
|
||||
else builtins.filter (m: !(builtins.elem m laptopOnly)) mods;
|
||||
settings = rawSettings // {
|
||||
modules-right = filterModules (rawSettings.modules-right or []);
|
||||
modules-center = filterModules (rawSettings.modules-center or []);
|
||||
modules-left = filterModules (rawSettings.modules-left or []);
|
||||
};
|
||||
in { ... }
|
||||
```
|
||||
|
||||
### Form-factor (laptop vs desktop)
|
||||
|
||||
`nomarchy.system.formFactor` and `nomarchy.formFactor` are the two halves of the same flag (system + home). Default `"laptop"`. The installer auto-detects via `compgen -G "/sys/class/power_supply/BAT*"` and writes the explicit value into both generated files. Use this option to gate any laptop-only UI / service.
|
||||
|
||||
### State (`state.json`)
|
||||
|
||||
Theme, font, wallpaper, and a few feature toggles live in `~/.config/nomarchy/state.json` so they can change without a rebuild. Schema is in `lib/state-schema.nix`. The Home Manager evaluator reads it via `lib/default.nix`. **Don't add new state without justifying it** — most "state" should be a NixOS option instead.
|
||||
|
||||
### Scripts derivation
|
||||
|
||||
User-PATH scripts ship via `nomarchy-system-scripts` (`core/system/scripts-derivation.nix`) plus the per-category dependencies declared in `features/scripts/default.nix:categoryDeps`. When you add a script:
|
||||
|
||||
1. Drop the file in `features/scripts/utils/` or `core/system/scripts/`.
|
||||
2. `chmod +x` it (it'll be wrapped with the right deps automatically).
|
||||
3. Reference the right `categoryDeps` group in `features/scripts/default.nix` if it needs new tools.
|
||||
4. Test that `which <script>` resolves after a rebuild.
|
||||
|
||||
### Heredocs in `installer/install.sh`
|
||||
|
||||
The system-config generator uses unquoted heredocs (`<< EOF`) so `$VAR` expands. The home-config generator now also uses unquoted heredocs — any literal `$` or backtick in the body must be escaped (see `installer/install.sh:1043-1131`). If you forget and the install fails with a "unbound variable" or unexpected command output, that's why.
|
||||
|
||||
---
|
||||
|
||||
## 7. Things to never do without explicit user OK
|
||||
|
||||
- `git push --force`, `git reset --hard`, `git clean -f`, `rm -rf` outside obvious sandbox dirs.
|
||||
- Touch `flake.lock` unless the user asked to update inputs.
|
||||
- Bump `nixpkgs` major version (e.g. `25.11` → `26.05`) — that's a release decision.
|
||||
- Add a new flake input. They're load-bearing across all three host configurations.
|
||||
- Skip pre-commit hooks (`--no-verify`).
|
||||
- Ship a feature without a `nomarchy.*` option to gate it.
|
||||
- Ship a removal without updating callers (grep first).
|
||||
- Mock the database / external services in tests — use the real thing.
|
||||
|
||||
---
|
||||
|
||||
## 8. Where to put your own notes
|
||||
|
||||
- **Long-lived docs** → `docs/`.
|
||||
- **Working notes / per-session plans** → `~/.claude/plans/`. Don't commit them.
|
||||
- **Memory** about the user, this project, or process preferences → your harness's memory directory at `/home/bernardo/.claude/projects/-home-bernardo-Projects-nomarchy/memory/`. Each entry gets a frontmatter file plus a one-line index entry in `MEMORY.md`.
|
||||
|
||||
---
|
||||
|
||||
## 9. The shape of a good handoff
|
||||
|
||||
Before you stop, leave the next agent (or future you) something to land on:
|
||||
|
||||
- The roadmap is up to date — items you shipped are in **Shipped**.
|
||||
- `git status` is clean (or has one obvious WIP commit on a `wave/...` branch).
|
||||
- If you discovered new scope, you logged it as a roadmap row, not a verbal heads-up.
|
||||
- Any plan file you wrote in `~/.claude/plans/` is named after the task, not the date.
|
||||
- The user's last message has been answered concisely.
|
||||
|
||||
That's it. The roadmap tells you what; this file tells you how. Go pick a Now item.
|
||||
218
docs/KEYBINDINGS.md
Normal file
218
docs/KEYBINDINGS.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# Nomarchy Keybindings
|
||||
|
||||
Auto-generated from the Hyprland binding files. **Do not edit by hand.**
|
||||
Re-run the generator after changing any `bindings/*.conf`:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-keybindings --out docs/KEYBINDINGS.md
|
||||
```
|
||||
|
||||
`SUPER` is the Meta / Win key. `code:NN` keys (X11 digit keycodes) are
|
||||
shown as the digit they correspond to. Media keys (`XF86Audio*`,
|
||||
`XF86MonBrightness*`, …) are prettified.
|
||||
|
||||
## Utilities
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/utilities.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| SUPER | SPACE | Launch apps |
|
||||
| SUPER CTRL | E | Emoji picker |
|
||||
| SUPER CTRL | C | Capture menu |
|
||||
| SUPER CTRL | O | Toggle menu |
|
||||
| SUPER ALT | SPACE | Toggle top bar |
|
||||
| SUPER | ESCAPE | System menu |
|
||||
| — | XF86PowerOff | Power menu |
|
||||
| SUPER | K | Show key bindings |
|
||||
| — | XF86Calculator | Calculator |
|
||||
| SUPER SHIFT | SPACE | Nomarchy menu |
|
||||
| SUPER CTRL | SPACE | Theme background menu |
|
||||
| SUPER SHIFT CTRL | SPACE | Theme menu |
|
||||
| SUPER | BACKSPACE | Toggle window transparency |
|
||||
| SUPER SHIFT | BACKSPACE | Toggle window gaps |
|
||||
| SUPER CTRL | BACKSPACE | Toggle single-window square aspect |
|
||||
| SUPER | COMMA | Dismiss last notification |
|
||||
| SUPER SHIFT | COMMA | Dismiss all notifications |
|
||||
| SUPER CTRL | COMMA | Toggle silencing notifications |
|
||||
| SUPER ALT | COMMA | Invoke last notification |
|
||||
| SUPER SHIFT ALT | COMMA | Restore last notification |
|
||||
| SUPER CTRL | I | Toggle locking on idle |
|
||||
| SUPER CTRL | N | Toggle nightlight |
|
||||
| CTRL | F1 | Apple Display brightness down |
|
||||
| CTRL | F2 | Apple Display brightness up |
|
||||
| SHIFT CTRL | F2 | Apple Display full brightness |
|
||||
| — | PRINT | Screenshot |
|
||||
| ALT | PRINT | Screenrecording |
|
||||
| SUPER | PRINT | Color picker |
|
||||
| SUPER CTRL | S | Share |
|
||||
| SUPER CTRL ALT | T | Show time |
|
||||
| SUPER CTRL ALT | B | Show battery remaining |
|
||||
| SUPER CTRL | A | Audio controls |
|
||||
| SUPER CTRL | B | Bluetooth controls |
|
||||
| SUPER CTRL | W | Wifi controls |
|
||||
| SUPER CTRL | T | Activity |
|
||||
| SUPER CTRL | X | Toggle dictation |
|
||||
| SUPER CTRL | Z | Zoom in |
|
||||
| SUPER CTRL ALT | Z | Reset zoom |
|
||||
| SUPER CTRL | L | Lock system |
|
||||
|
||||
## Tiling
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| SUPER | W | Close window |
|
||||
| CTRL ALT | DELETE | Close all windows |
|
||||
| SUPER | J | Toggle window split |
|
||||
| SUPER | P | Pseudo window |
|
||||
| SUPER | T | Toggle window floating/tiling |
|
||||
| SUPER | F | Full screen |
|
||||
| SUPER CTRL | F | Tiled full screen |
|
||||
| SUPER ALT | F | Full width |
|
||||
| SUPER | O | Pop window out (float & pin) |
|
||||
| SUPER | L | Toggle workspace layout |
|
||||
| SUPER | LEFT | Move window focus left |
|
||||
| SUPER | RIGHT | Move window focus right |
|
||||
| SUPER | UP | Move window focus up |
|
||||
| SUPER | DOWN | Move window focus down |
|
||||
| SUPER | 1 | Switch to workspace 1 |
|
||||
| SUPER | 2 | Switch to workspace 2 |
|
||||
| SUPER | 3 | Switch to workspace 3 |
|
||||
| SUPER | 4 | Switch to workspace 4 |
|
||||
| SUPER | 5 | Switch to workspace 5 |
|
||||
| SUPER | 6 | Switch to workspace 6 |
|
||||
| SUPER | 7 | Switch to workspace 7 |
|
||||
| SUPER | 8 | Switch to workspace 8 |
|
||||
| SUPER | 9 | Switch to workspace 9 |
|
||||
| SUPER | 0 | Switch to workspace 10 |
|
||||
| SUPER SHIFT | 1 | Move window to workspace 1 |
|
||||
| SUPER SHIFT | 2 | Move window to workspace 2 |
|
||||
| SUPER SHIFT | 3 | Move window to workspace 3 |
|
||||
| SUPER SHIFT | 4 | Move window to workspace 4 |
|
||||
| SUPER SHIFT | 5 | Move window to workspace 5 |
|
||||
| SUPER SHIFT | 6 | Move window to workspace 6 |
|
||||
| SUPER SHIFT | 7 | Move window to workspace 7 |
|
||||
| SUPER SHIFT | 8 | Move window to workspace 8 |
|
||||
| SUPER SHIFT | 9 | Move window to workspace 9 |
|
||||
| SUPER SHIFT | 0 | Move window to workspace 10 |
|
||||
| SUPER SHIFT ALT | 1 | Move window silently to workspace 1 |
|
||||
| SUPER SHIFT ALT | 2 | Move window silently to workspace 2 |
|
||||
| SUPER SHIFT ALT | 3 | Move window silently to workspace 3 |
|
||||
| SUPER SHIFT ALT | 4 | Move window silently to workspace 4 |
|
||||
| SUPER SHIFT ALT | 5 | Move window silently to workspace 5 |
|
||||
| SUPER SHIFT ALT | 6 | Move window silently to workspace 6 |
|
||||
| SUPER SHIFT ALT | 7 | Move window silently to workspace 7 |
|
||||
| SUPER SHIFT ALT | 8 | Move window silently to workspace 8 |
|
||||
| SUPER SHIFT ALT | 9 | Move window silently to workspace 9 |
|
||||
| SUPER SHIFT ALT | 0 | Move window silently to workspace 10 |
|
||||
| SUPER | S | Toggle scratchpad |
|
||||
| SUPER ALT | S | Move window to scratchpad |
|
||||
| SUPER | TAB | Next workspace |
|
||||
| SUPER SHIFT | TAB | Previous workspace |
|
||||
| SUPER CTRL | TAB | Former workspace |
|
||||
| SUPER SHIFT ALT | LEFT | Move workspace to left monitor |
|
||||
| SUPER SHIFT ALT | RIGHT | Move workspace to right monitor |
|
||||
| SUPER SHIFT ALT | UP | Move workspace to up monitor |
|
||||
| SUPER SHIFT ALT | DOWN | Move workspace to down monitor |
|
||||
| SUPER SHIFT | LEFT | Swap window to the left |
|
||||
| SUPER SHIFT | RIGHT | Swap window to the right |
|
||||
| SUPER SHIFT | UP | Swap window up |
|
||||
| SUPER SHIFT | DOWN | Swap window down |
|
||||
| ALT | TAB | Cycle to next window |
|
||||
| ALT SHIFT | TAB | Cycle to prev window |
|
||||
| ALT | TAB | Reveal active window on top |
|
||||
| ALT SHIFT | TAB | Reveal active window on top |
|
||||
| SUPER | code:20 | Expand window left |
|
||||
| SUPER | code:21 | Shrink window left |
|
||||
| SUPER SHIFT | code:20 | Shrink window up |
|
||||
| SUPER SHIFT | code:21 | Expand window down |
|
||||
| SUPER | mouse_down | Scroll active workspace forward |
|
||||
| SUPER | mouse_up | Scroll active workspace backward |
|
||||
| SUPER | mouse:272 | Move window |
|
||||
| SUPER | mouse:273 | Resize window |
|
||||
| SUPER | G | Toggle window grouping |
|
||||
| SUPER ALT | G | Move active window out of group |
|
||||
| SUPER ALT | LEFT | Move window to group on left |
|
||||
| SUPER ALT | RIGHT | Move window to group on right |
|
||||
| SUPER ALT | UP | Move window to group on top |
|
||||
| SUPER ALT | DOWN | Move window to group on bottom |
|
||||
| SUPER ALT | TAB | Next window in group |
|
||||
| SUPER ALT SHIFT | TAB | Previous window in group |
|
||||
| SUPER CTRL | LEFT | Move grouped window focus left |
|
||||
| SUPER CTRL | RIGHT | Move grouped window focus right |
|
||||
| SUPER ALT | mouse_down | Next window in group |
|
||||
| SUPER ALT | mouse_up | Previous window in group |
|
||||
| SUPER ALT | 1 | Switch to group window 1 |
|
||||
| SUPER ALT | 2 | Switch to group window 2 |
|
||||
| SUPER ALT | 3 | Switch to group window 3 |
|
||||
| SUPER ALT | 4 | Switch to group window 4 |
|
||||
| SUPER ALT | 5 | Switch to group window 5 |
|
||||
| SUPER | Slash | Cycle monitor scaling |
|
||||
|
||||
## Clipboard
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/clipboard.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| SUPER | C | Universal copy |
|
||||
| SUPER | V | Universal paste |
|
||||
| SUPER | X | Universal cut |
|
||||
| SUPER CTRL | V | Clipboard manager |
|
||||
|
||||
## Media keys
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/media.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| — | Volume Up | Volume up |
|
||||
| — | Volume Down | Volume down |
|
||||
| — | Mute | Mute |
|
||||
| — | Mic Mute | Mute microphone |
|
||||
| — | Brightness Up | Brightness up |
|
||||
| — | Brightness Down | Brightness down |
|
||||
| — | Kbd Brightness Up | Keyboard brightness up |
|
||||
| — | Kbd Brightness Down | Keyboard brightness down |
|
||||
| — | Kbd Backlight | Keyboard backlight cycle |
|
||||
| ALT | Volume Up | Volume up precise |
|
||||
| ALT | Volume Down | Volume down precise |
|
||||
| ALT | Brightness Up | Brightness up precise |
|
||||
| ALT | Brightness Down | Brightness down precise |
|
||||
| — | Next Track | Next track |
|
||||
| — | XF86AudioPause | Pause |
|
||||
| — | Play/Pause | Play |
|
||||
| — | Previous Track | Previous track |
|
||||
| SUPER | Mute | Switch audio output |
|
||||
|
||||
## Apps & web shortcuts
|
||||
|
||||
_Source: `features/desktop/hyprland/config/bindings.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| SUPER | RETURN | Terminal |
|
||||
| SUPER ALT | RETURN | Tmux |
|
||||
| SUPER SHIFT | RETURN | Browser |
|
||||
| SUPER SHIFT | F | File manager |
|
||||
| SUPER ALT SHIFT | F | File manager (cwd) |
|
||||
| SUPER SHIFT | B | Browser |
|
||||
| SUPER SHIFT ALT | B | Browser (private) |
|
||||
| SUPER SHIFT | M | Music |
|
||||
| SUPER SHIFT | N | Editor |
|
||||
| SUPER SHIFT | D | Docker |
|
||||
| SUPER SHIFT | G | Signal |
|
||||
| SUPER SHIFT | O | Obsidian |
|
||||
| SUPER SHIFT | SLASH | Passwords |
|
||||
| SUPER SHIFT | A | ChatGPT |
|
||||
| SUPER SHIFT ALT | A | Grok |
|
||||
| SUPER SHIFT | C | Calendar |
|
||||
| SUPER SHIFT | E | Email |
|
||||
| SUPER SHIFT | Y | YouTube |
|
||||
| SUPER SHIFT ALT | G | WhatsApp |
|
||||
| SUPER SHIFT CTRL | G | Google Messages |
|
||||
| SUPER SHIFT | P | Google Photos |
|
||||
| SUPER SHIFT | X | X |
|
||||
| SUPER SHIFT ALT | X | X Post |
|
||||
259
docs/MIGRATION.md
Normal file
259
docs/MIGRATION.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# Migrating an existing NixOS install to Nomarchy
|
||||
|
||||
You already have NixOS running and you want the Nomarchy desktop without
|
||||
reformatting. This is the in-place path. Your `/`, `/home`, hostname, and
|
||||
user account are preserved; Nomarchy is layered on as a flake input.
|
||||
|
||||
> Prefer a clean disk? Skip to the [fallback](#fallback-clean-install-via-the-live-iso).
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- NixOS 25.11. Older releases are not supported by the current Nomarchy
|
||||
modules.
|
||||
- Flakes enabled. If you don't have them yet:
|
||||
```nix
|
||||
# somewhere in your existing config
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
```
|
||||
Apply with `sudo nixos-rebuild switch` once before proceeding.
|
||||
|
||||
---
|
||||
|
||||
## 1. Move to a flake-based config
|
||||
|
||||
If you already have `/etc/nixos/flake.nix`, skip to step 2.
|
||||
|
||||
Back your existing config up:
|
||||
|
||||
```bash
|
||||
sudo cp /etc/nixos/configuration.nix /etc/nixos/configuration.nix.bak
|
||||
```
|
||||
|
||||
Then create `/etc/nixos/flake.nix` with the structure below. (This is the
|
||||
same shape the Nomarchy installer produces — see
|
||||
`installer/install.sh:generate_flake_config` in the upstream repo.)
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "My Nomarchy Configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
||||
nomarchy.url = "git+https://git.bemagri.xyz/bernardo/Nomarchy.git";
|
||||
# …or pin: "git+https://git.bemagri.xyz/bernardo/Nomarchy.git?rev=<sha>"
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-25.11";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nomarchy, home-manager, nixos-hardware, ... }@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ nomarchy.overlays.default ];
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
nixosConfigurations.<hostname> = nixpkgs.lib.nixosSystem {
|
||||
inherit pkgs;
|
||||
specialArgs = { inputs = nomarchy.inputs // inputs; };
|
||||
modules = [
|
||||
./hardware-configuration.nix
|
||||
nomarchy.nixosModules.system
|
||||
./system.nix
|
||||
];
|
||||
};
|
||||
|
||||
homeConfigurations.<user> = home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
extraSpecialArgs = { inputs = nomarchy.inputs // inputs; };
|
||||
modules = [
|
||||
nomarchy.nixosModules.home
|
||||
./home.nix
|
||||
{
|
||||
home.username = "<user>";
|
||||
home.homeDirectory = "/home/<user>";
|
||||
home.stateVersion = "25.11";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Replace `<hostname>` and `<user>` with your real values. Two-track Nomarchy:
|
||||
the system block uses `nomarchy.nixosModules.system`; the standalone
|
||||
home-manager block uses `nomarchy.nixosModules.home`. Both consume the same
|
||||
`pkgs` so overlays stay in sync.
|
||||
|
||||
## 2. Move your existing settings into `system.nix` and `home.nix`
|
||||
|
||||
The Nomarchy installer also generates these files — copy that template, or
|
||||
create minimal versions to start:
|
||||
|
||||
`/etc/nixos/system.nix`:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
networking.hostName = "<hostname>";
|
||||
time.timeZone = "<your-timezone>";
|
||||
|
||||
users.users."<user>" = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "video" "render" "audio" "networkmanager" ];
|
||||
};
|
||||
|
||||
# Compressed RAM swap — near-free memory headroom.
|
||||
zramSwap.enable = true;
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
```
|
||||
|
||||
`/etc/nixos/home.nix`:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
btop
|
||||
fastfetch
|
||||
chromium
|
||||
# …add anything you want; firefox/thunar/mpv/mako/etc. ship with Nomarchy.
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
Move any user/services/packages you had in `configuration.nix` over to
|
||||
`system.nix`. Do **not** redefine things Nomarchy already provides (display
|
||||
manager, Hyprland, PipeWire, NetworkManager) unless you want to override
|
||||
them — see the [conflicts](#conflicts-to-resolve-before-rebuild) section.
|
||||
|
||||
## 3. (Optional) Pick up hardware-specific tuning
|
||||
|
||||
Nomarchy ships a `nixos-hardware` matcher. From any shell on your existing
|
||||
system:
|
||||
|
||||
```bash
|
||||
nix shell nixpkgs#git -c \
|
||||
bash -c 'tmp=$(mktemp -d); git clone --depth=1 https://git.bemagri.xyz/bernardo/Nomarchy.git "$tmp" >/dev/null 2>&1; \
|
||||
source "$tmp/installer/hardware-db.sh"; nomarchy_detect_hw'
|
||||
```
|
||||
|
||||
Output is a list like:
|
||||
|
||||
```
|
||||
MODULE common-cpu-amd
|
||||
MODULE common-gpu-amd
|
||||
MODULE common-pc-laptop
|
||||
MODULE framework-13-amd-ai-300-series
|
||||
OPT isFramework=true
|
||||
```
|
||||
|
||||
Drop a `hardware-selection.nix` next to your flake:
|
||||
|
||||
```nix
|
||||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.nixos-hardware.nixosModules.common-cpu-amd
|
||||
inputs.nixos-hardware.nixosModules.common-gpu-amd
|
||||
inputs.nixos-hardware.nixosModules.framework-13-amd-ai-300-series
|
||||
];
|
||||
nomarchy.hardware.isFramework = true;
|
||||
}
|
||||
```
|
||||
|
||||
…and add `./hardware-selection.nix` to the system module list in `flake.nix`.
|
||||
Skip this entirely if you don't have a matching device.
|
||||
|
||||
## 4. Rebuild
|
||||
|
||||
```bash
|
||||
sudo nixos-rebuild switch --flake /etc/nixos#<hostname>
|
||||
home-manager switch --flake /etc/nixos#<user> --impure
|
||||
```
|
||||
|
||||
Reboot or `systemctl restart display-manager`. SDDM comes up with the
|
||||
Nomarchy theme; logging in as `<user>` lands you in Hyprland with the full
|
||||
Nomarchy desktop.
|
||||
|
||||
After this, the daily workflow is two commands:
|
||||
|
||||
- **System changes** (services, kernel, hardware) →
|
||||
`sudo nixos-rebuild switch --flake /etc/nixos#<hostname>`
|
||||
- **Dotfiles, themes, user packages** → `nomarchy-env-update` (runs the
|
||||
standalone `home-manager switch` for you, no system rebuild)
|
||||
|
||||
---
|
||||
|
||||
## Conflicts to resolve before rebuild
|
||||
|
||||
`nomarchy.nixosModules.system` enables a desktop stack. If your existing
|
||||
`configuration.nix` already configures any of these, only one setting wins
|
||||
and it's whichever has higher Nix priority. Fix these explicitly:
|
||||
|
||||
| Area | Nomarchy default | What to do if you already have it |
|
||||
| --- | --- | --- |
|
||||
| Display manager | SDDM (Wayland) | Disable yours: `services.xserver.displayManager.gdm.enable = lib.mkForce false;` (or whatever you had) |
|
||||
| Default session | `hyprland-uwsm` | Drop your `services.displayManager.defaultSession` |
|
||||
| Hyprland | `programs.hyprland.enable = true; withUWSM = true;` | Drop your `programs.hyprland` setting |
|
||||
| Audio | PipeWire (alsa+pulse+jack) | Remove `services.pulseaudio.enable = true;` — NixOS errors if both are on |
|
||||
| Networking | NetworkManager | Drop `networking.wireless.enable = true;` (if set) |
|
||||
| Graphics | `hardware.graphics.enable = true` (was `hardware.opengl`) | Probably already enabled — fine |
|
||||
| User groups | needs `video render networkmanager` | Add to your `users.users.<user>.extraGroups` |
|
||||
| `/etc/os-release` | `ID=nomarchy`, `NAME=Nomarchy` | A few third-party scripts grep `ID=nixos` — adjust them or rely on `ID_LIKE` (TBD) |
|
||||
| autoLogin | `enable = false; user = "nomarchy";` (mkDefault) | Off by default — opt in with `services.displayManager.autoLogin = { enable = true; user = "<your user>"; };` if you want it |
|
||||
|
||||
Impermanence is **off** unless you set `nomarchy.system.impermanence.enable = true`,
|
||||
and it requires a BTRFS layout with a `root-blank` snapshot. Don't enable it
|
||||
on an existing install — the live ISO is the right path for that.
|
||||
|
||||
If your first rebuild errors out, the five most common failures and their fixes
|
||||
live in [Troubleshooting](TROUBLESHOOTING.md).
|
||||
|
||||
---
|
||||
|
||||
## Fallback: clean install via the live ISO
|
||||
|
||||
```bash
|
||||
# In a checkout of the Nomarchy repo:
|
||||
nomarchy-test-live-iso # boots the ISO in QEMU to evaluate
|
||||
# Or burn the produced .iso to a USB and boot it on real hardware.
|
||||
```
|
||||
|
||||
The ISO autologins to a Hyprland live session that points you at:
|
||||
|
||||
- `sudo /etc/install.sh` — install (BTRFS + LUKS + subvolumes per
|
||||
`installer/disko-config.nix`, auto-detects hardware via `hardware-db.sh`,
|
||||
runs `home-manager switch` inside `nixos-enter` so the first login is
|
||||
fully themed).
|
||||
- `sudo /etc/install.sh --dry-run` — generate the flake into a tmpdir and
|
||||
parse-check it without touching the disk.
|
||||
- `sudo /etc/install.sh --resume` — pick up an interrupted run.
|
||||
|
||||
After install, the system at `/etc/nixos/` is the same shape this guide
|
||||
produces by hand.
|
||||
|
||||
---
|
||||
|
||||
## Verification (in-place migration)
|
||||
|
||||
1. `cat /etc/os-release` → `NAME=Nomarchy`, `ID=nomarchy`.
|
||||
2. SDDM theme is the Nomarchy purple/blue panel.
|
||||
3. After login: waybar shows the Nomarchy logo on the left, theme switcher
|
||||
under Style → Theme works.
|
||||
4. `which btop fastfetch waybar walker nomarchy-env-update` → all on PATH.
|
||||
5. `nomarchy-env-update` returns clean (proves standalone HM is wired and
|
||||
`nomarchy.nixosModules.home` is in scope).
|
||||
|
||||
If anything is wrong, your old config is intact at
|
||||
`/etc/nixos/configuration.nix.bak` — `sudo nixos-rebuild switch -I nixos-config=/etc/nixos/configuration.nix.bak`
|
||||
will roll back.
|
||||
328
docs/OPTIONS.md
Normal file
328
docs/OPTIONS.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# Nomarchy Options Reference
|
||||
|
||||
Every option Nomarchy exposes for downstream flakes. Paths under `nomarchy.system.*` are NixOS options (set in `system.nix`); paths under `nomarchy.*` (no `system` segment) are Home Manager options (set in `home.nix`). `nomarchy.hardware.*` is NixOS.
|
||||
|
||||
The installer-generated configuration writes a few of these for you (timezone, formFactor, hardware vendor flags, keymap, locale). Anything not listed there is opt-in — set it yourself.
|
||||
|
||||
To see the live default for any option:
|
||||
|
||||
```bash
|
||||
nix eval .#nixosConfigurations.<host>.config.nomarchy.system.<path>
|
||||
nix eval .#homeConfigurations.<user>.config.nomarchy.<path>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NixOS options (`system.nix`)
|
||||
|
||||
### `nomarchy.system.dns`
|
||||
|
||||
DNS provider. One of `"DHCP"` (default), `"Cloudflare"`, `"Google"`, `"Custom"`. With `"Custom"`, set `nomarchy.system.customDns` to a list of nameservers. Anything other than `"DHCP"` also enables `services.resolved` with DNSSEC and DNS-over-TLS.
|
||||
|
||||
Defined in `core/system/options.nix`; wired in `core/system/network.nix`.
|
||||
|
||||
### `nomarchy.system.customDns`
|
||||
|
||||
`listOf str`, default `[]`. Nameservers used when `dns = "Custom"`.
|
||||
|
||||
### `nomarchy.system.wifi.powersave`
|
||||
|
||||
`bool`, default `true`. Sets `networking.networkmanager.wifi.powersave`. Turn off if you see drops on idle Wi-Fi.
|
||||
|
||||
### `nomarchy.system.timezone`
|
||||
|
||||
`str`, default `"UTC"`. The installer writes `time.timeZone` directly, so this option is informational unless you wire it into your own modules.
|
||||
|
||||
### `nomarchy.system.formFactor`
|
||||
|
||||
`enum [ "laptop" "desktop" ]`, default `"laptop"`. Drives UI affordances and the laptop power preset. The installer auto-detects via `/sys/class/power_supply/BAT*`. The default is `"laptop"` because the battery widget renders empty when no battery is present — safe on a desktop, useful on a laptop.
|
||||
|
||||
Wired in `features/desktop/waybar/default.nix` (filters the battery widget out on desktop), `features/scripts/battery-monitor.nix` (skips the timer on desktop), and `nomarchy.system.laptop.enable` (defaults true when this is `"laptop"`).
|
||||
|
||||
### `nomarchy.system.theme`
|
||||
|
||||
`str`, default `"summer-night"`. Theme name. Mirror of the home-side `nomarchy.theme`. Set both if you also want NixOS-side modules (e.g. SDDM theming) to follow.
|
||||
|
||||
### `nomarchy.system.features.fingerprint`
|
||||
|
||||
`bool`, default `false`. Enables `services.fprintd.enable`.
|
||||
|
||||
### `nomarchy.system.features.fido2`
|
||||
|
||||
`bool`, default `false`. Enables `security.pam.u2f` (sufficient, with cue).
|
||||
|
||||
### `nomarchy.system.features.hybridGPU`
|
||||
|
||||
`bool`, default `false`. NVIDIA-hybrid laptop support. Wires:
|
||||
|
||||
- `services.supergfxd.enable` for runtime mode switching (`Integrated` / `Hybrid` / `Vfio` / `AsusEgpu`), driven by `nomarchy-toggle-hybrid-gpu`.
|
||||
- The NVIDIA driver stack (`services.xserver.videoDrivers = ["nvidia"]`, `hardware.graphics.{enable,enable32Bit}`, `hardware.nvidia.{modesetting,powerManagement}.enable`, `boot.kernelParams = ["nvidia-drm.modeset=1"]`).
|
||||
|
||||
All driver knobs use `lib.mkDefault`, so a downstream `system.nix` can pin a beta driver or flip to the open kernel module without forking the module.
|
||||
|
||||
**You still have to add bus IDs** — they're per-machine and can't be derived from any flag. Find them with `lspci -D | grep -E 'VGA|3D'`, then in your `/etc/nixos/system.nix`:
|
||||
|
||||
```nix
|
||||
hardware.nvidia.prime = {
|
||||
offload.enable = true;
|
||||
offload.enableOffloadCmd = true;
|
||||
intelBusId = "PCI:0:2:0"; # or `amdgpuBusId` for AMD iGPU
|
||||
nvidiaBusId = "PCI:1:0:0";
|
||||
};
|
||||
```
|
||||
|
||||
Without prime config, supergfxd still switches modes but render-offload via `nvidia-offload <cmd>` is unavailable.
|
||||
|
||||
### `nomarchy.system.snapper.enable`
|
||||
|
||||
`bool`, default `false`. BTRFS timeline snapshots of `/`. Auto-disables when `/` isn't BTRFS. Includes a `nixos-rebuild-snap` wrapper that takes a "Pre-rebuild" snapshot before each switch.
|
||||
|
||||
### `nomarchy.system.hibernation.enable`
|
||||
|
||||
`bool`, default `false`. Suspend-then-hibernate on lid close, idle, and power button. Requires a disk swap device or swapfile sized to at least RAM — zRAM alone is not enough.
|
||||
|
||||
### `nomarchy.system.hibernation.idleMinutes`
|
||||
|
||||
`int`, default `30`. Idle minutes before suspend-then-hibernate fires.
|
||||
|
||||
### `nomarchy.system.laptop.enable`
|
||||
|
||||
`bool`, default `nomarchy.system.formFactor == "laptop"`. Laptop power preset: TLP (with sane AC/battery governors and ThinkPad-style 75/80 charge thresholds), `services.upower`, `services.thermald` (gated by `laptop.thermald`), and a brightnessctl udev rule so the existing `nomarchy-brightness-{display,keyboard}` scripts run without root. Force-disables `services.power-profiles-daemon` (mutually exclusive with TLP) — to use PPD instead, set `laptop.enable = false` and wire it yourself. Lid-close action defers to `nomarchy.system.hibernation.enable`: `suspend-then-hibernate` when on, `suspend` otherwise. Charge thresholds are only honored on supported hardware (ThinkPad, some ASUS); harmless warning elsewhere.
|
||||
|
||||
### `nomarchy.system.laptop.thermald`
|
||||
|
||||
`bool`, default `true` on x86_64. Enables `services.thermald` (Intel thermal daemon). Harmless no-op on AMD; gated off on aarch64.
|
||||
|
||||
### `nomarchy.system.desktop.enable`
|
||||
|
||||
`bool`, default `nomarchy.system.formFactor == "desktop"`. Desktop preset: pins `powerManagement.cpuFreqGovernor` to `"performance"` (via `mkDefault`) and enables `services.zfs.autoScrub` + `services.zfs.trim` so a future ZFS pool gets sensible maintenance without further config. The ZFS knobs are no-ops until you add `boot.supportedFilesystems = [ "zfs" ]` (plus `networking.hostId`) and a pool. Battery-widget filtering is handled by `formFactor` itself, so this preset doesn't repeat it.
|
||||
|
||||
### `nomarchy.system.accessibility.enable`
|
||||
|
||||
`bool`, default `false`. Accessibility preset: enables `services.gnome.at-spi2-core` (AT-SPI2 framework), installs `pkgs.orca` (screen reader) into `environment.systemPackages`, and sets `XCURSOR_SIZE` to `accessibility.cursorSize`. Off by default — accessibility is a personal preference, not hardware-derived. The Hyprland-side bits (slower key-repeat, Orca launch keybinding, high-contrast palette) are a separate roadmap item.
|
||||
|
||||
### `nomarchy.system.accessibility.cursorSize`
|
||||
|
||||
`int`, default `32`. `XCURSOR_SIZE` when `accessibility.enable = true`. NixOS default is 24; 32 is a safer floor for low-vision users.
|
||||
|
||||
### `nomarchy.system.gaming.enable`
|
||||
|
||||
`bool`, default `false`. Gaming preset: enables `programs.steam` (with `remotePlay` and `localNetworkGameTransfers` firewall holes opened by `mkDefault`), `programs.gamemode` (the launching user must be in the `gamemode` group), and `services.flatpak`. The flathub remote isn't added declaratively — after first boot, run `flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo`. Pair with the home-side companion `nomarchy.gaming.enable` for the Hyprland fullscreen-on-Steam-launch window rule.
|
||||
|
||||
### `nomarchy.system.containers.enable`
|
||||
|
||||
`bool`, default `false`. Rootless Podman with Docker compatibility (`docker` → `podman`), plus `podman-compose`, `podman-tui`, and `dive`.
|
||||
|
||||
### `nomarchy.system.virtualization.libvirt.enable`
|
||||
|
||||
`bool`, default `false`. libvirt daemon, virt-manager, and OVMF. Add your user to the `libvirtd` group.
|
||||
|
||||
### `nomarchy.system.virtualization.docker.enable`
|
||||
|
||||
`bool`, default `false`. Docker daemon and docker-compose. Add your user to the `docker` group.
|
||||
|
||||
### `nomarchy.system.keyring.enable`
|
||||
|
||||
`bool`, default `true`. Auto-unlock GNOME Keyring at login and route SSH keys through `gcr-ssh-agent`. On by default — near-universal QoL improvement.
|
||||
|
||||
### `nomarchy.system.inputMethod.enable`
|
||||
|
||||
`bool`, default `false`. fcitx5 input method for CJK / IME. Wires NixOS's `i18n.inputMethod` and autostarts `fcitx5-daemon`.
|
||||
|
||||
### `nomarchy.system.voxtype.enable`
|
||||
|
||||
`bool`, default `false`. voxtype voice-typing integration. voxtype isn't packaged in nixpkgs — when you enable this, install voxtype yourself (e.g. `home.packages = [ (pkgs.callPackage … {}) ]`). With this off the `SUPER+CTRL+X` keybinding and waybar widget are no-ops.
|
||||
|
||||
### `nomarchy.hardware.isXPS`
|
||||
|
||||
`bool`, default `false`. Dell XPS fixes — haptic touchpad service and PCI/I²C power-control udev rules.
|
||||
|
||||
### `nomarchy.hardware.isT2Mac`
|
||||
|
||||
`bool`, default `false`. Apple T2 MacBook fixes — IOMMU kernel params, `apple-bce` module, brcmfmac feature mask.
|
||||
|
||||
### `nomarchy.hardware.isFramework`
|
||||
|
||||
`bool`, default `false`. Framework laptop QMK HID udev rule.
|
||||
|
||||
### `nomarchy.hardware.fwupd`
|
||||
|
||||
`bool`, default `false`. Enables `services.fwupd` firmware update service.
|
||||
|
||||
### `nomarchy.hardware.hasIPU7Camera`
|
||||
|
||||
`bool`, default `false`. Intel IPU7 camera support (kernel modules + firmware).
|
||||
|
||||
### `nomarchy.system.impermanence.enable`
|
||||
|
||||
`bool`, default `false`. Erase Your Darlings root wipe on boot. Defined in `core/system/impermanence.nix`. The installer writes the flag based on the impermanence prompt.
|
||||
|
||||
### `nomarchy.system.impermanence.mainLuksName`
|
||||
|
||||
`str`, default `"crypted"`. Name of the `/dev/mapper` entry holding the BTRFS root. The disko layout uses `"crypted"` on single-disk installs and `"crypted_main"` once multiple drives are selected — the installer writes the matching value automatically.
|
||||
|
||||
### `nomarchy.system.impermanence.user`
|
||||
|
||||
`str`, default `"nomarchy"`. Primary user whose home subset (`.ssh`, `.gnupg`, `.local/share/keyrings`, `Documents`, `Downloads`, `Pictures`, `Videos`, `Projects`) survives the rootfs wipe. Must match the user created via `users.users.<name>` — otherwise the persistence block is silently inert and the user's home directory is wiped on every boot. The installer writes this for you.
|
||||
|
||||
---
|
||||
|
||||
## Home Manager options (`home.nix`)
|
||||
|
||||
### `nomarchy.theme`
|
||||
|
||||
`str`, default `"summer-night"`. Active theme name. Available themes are the directories under `themes/palettes/`.
|
||||
|
||||
### `nomarchy.panelPosition`
|
||||
|
||||
`enum ["top", "bottom"]`, default `"top"`. Waybar panel position.
|
||||
|
||||
### `nomarchy.formFactor`
|
||||
|
||||
`enum [ "laptop" "desktop" ]`, default `"laptop"`. Mirror of `nomarchy.system.formFactor`. Filters laptop-only widgets out of waybar (battery) when set to `"desktop"`. The installer writes both system and home values together.
|
||||
|
||||
### `nomarchy.wallpaper`
|
||||
|
||||
`str`, default `""`. Absolute path to a wallpaper override. Empty string means "use the active theme's default wallpaper".
|
||||
|
||||
### `nomarchy.toggles.suspend`
|
||||
|
||||
`bool`, default `true`. Whether suspend appears in the system menu.
|
||||
|
||||
### `nomarchy.toggles.screensaver`
|
||||
|
||||
`bool`, default `true`. Whether the screensaver is enabled.
|
||||
|
||||
### `nomarchy.toggles.idle`
|
||||
|
||||
`bool`, default `true`. Whether the idle lock is enabled (hypridle).
|
||||
|
||||
### `nomarchy.toggles.nightlight`
|
||||
|
||||
`bool`, default `false`. Enables hyprsunset.
|
||||
|
||||
### `nomarchy.toggles.waybar`
|
||||
|
||||
`bool`, default `true`. Whether the top bar is deployed at all.
|
||||
|
||||
### `nomarchy.nightlightTemperature`
|
||||
|
||||
`int`, default `4000`. Nightlight color temperature (Kelvin).
|
||||
|
||||
### `nomarchy.hyprland.gaps_in`
|
||||
|
||||
`int`, default `5`. Inner gaps.
|
||||
|
||||
### `nomarchy.hyprland.gaps_out`
|
||||
|
||||
`int`, default `10`. Outer gaps.
|
||||
|
||||
### `nomarchy.hyprland.border_size`
|
||||
|
||||
`int`, default `2`. Window border width.
|
||||
|
||||
### `nomarchy.fonts.monospace`
|
||||
|
||||
`str`, default `"JetBrainsMono Nerd Font"`. Used by terminals, VSCode, etc.
|
||||
|
||||
### `nomarchy.iconsTheme`
|
||||
|
||||
`str`, default derived from the active theme (falls back to `"Yaru-blue"`). GTK/Qt icon theme name. `core/home/state.nix` computes this from the theme's palette metadata; override to pin a specific icon theme regardless of palette.
|
||||
|
||||
### `nomarchy.isLightMode`
|
||||
|
||||
`bool`, default derived from the active theme. Whether the active theme is a light theme. `core/home/state.nix` computes this from the theme directory; affects nightlight defaults and a few app theme decisions. Override only if you need to force a specific value.
|
||||
|
||||
### `nomarchy.cursor.name`
|
||||
|
||||
`str`, default `"Bibata-Modern-Ice"`. Cursor theme name.
|
||||
|
||||
### `nomarchy.cursor.package`
|
||||
|
||||
`package`, default `pkgs.bibata-cursors`. Package providing the cursor theme. Override both `name` and `package` together if you switch themes.
|
||||
|
||||
### `nomarchy.configOverrides`
|
||||
|
||||
`nullOr path`, default `null`. Path to a replacement config directory. When set, the items listed in `core/home/configs.nix` (`fastfetch`, `fcitx5`, `fontconfig`, `git`, `imv`, `nautilus-python`, `nomarchy`, `nomarchy-skill`, `uwsm`, `wiremix`, plus the loose files) are read from `<this-path>/<name>` instead of the bundled defaults. Distinct from `nomarchy.overrides.*` below — `configOverrides` is a working bulk redirect; `overrides.*` is a reserved option surface (currently a no-op).
|
||||
|
||||
### `nomarchy.apps.opencode.enable`
|
||||
|
||||
`bool`, default `false`. opencode AI coding CLI integration. Deploys `~/.config/opencode/opencode.json`. The `opencode` package itself is **not** installed by Nomarchy — add it to your `home.packages`.
|
||||
|
||||
### `nomarchy.gaming.enable`
|
||||
|
||||
`bool`, default `false`. Home-side companion to `nomarchy.system.gaming.enable`. Adds a Hyprland `windowrulev2 = fullscreen, class:^(steam_app_).*$` so games launched through Steam grab the whole screen instead of opening windowed. Set to the same value as the system option; the installer flips both when the Gaming profile is selected.
|
||||
|
||||
### `nomarchy.vscode.devExtensions`
|
||||
|
||||
`bool`, default `false`. Install Nomarchy's curated VSCode extension pack (Nix, language servers, theme variants).
|
||||
|
||||
### `nomarchy.themeLoader.enable`
|
||||
|
||||
`bool`, default `true`. Auto-load theme-specific app configs from the active theme's `apps/` directory. Disable if you want to provide your own.
|
||||
|
||||
### `nomarchy.themeLoader.apps.btop`
|
||||
|
||||
`bool`, default `true`. Deploy the active theme's `apps/btop.theme` to `~/.config/btop/themes/nomarchy.theme`. The only per-app toggle in this group — waybar themes inline from `colorScheme` in `features/desktop/waybar`; kitty and alacritty are themed by stylix targets (`themes/engine/stylix.nix`); mako has no theme integration yet.
|
||||
|
||||
### `nomarchy.overrides.enable`
|
||||
|
||||
`bool`, default `true`. **Reserved — currently a no-op.** Intended to gate a future file-based override loader (drop a file under `~/.config/nomarchy/overrides/`, have it substitute the bundled default for that path). The option exists so configs that set it don't fail to evaluate; setting it has no effect today. Use `nomarchy.configOverrides` for bulk redirection, or set `xdg.configFile.<path>.source` directly in your `home.nix` for per-file overrides — Nomarchy's defaults use `lib.mkDefault` and yield to higher-priority assignments. Tracked in `docs/ROADMAP.md`.
|
||||
|
||||
### `nomarchy.overrides.paths`
|
||||
|
||||
`attrsOf path`, default `{}`. **Reserved — currently unused.** Will be populated by the future override loader.
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Minimal `system.nix` for a desktop with Cloudflare DNS, Snapper, and rootless Podman
|
||||
|
||||
```nix
|
||||
{
|
||||
nomarchy.system = {
|
||||
dns = "Cloudflare";
|
||||
formFactor = "desktop";
|
||||
snapper.enable = true;
|
||||
containers.enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Minimal `home.nix` for a Tokyo-night user with custom gaps and opencode
|
||||
|
||||
```nix
|
||||
{
|
||||
nomarchy = {
|
||||
theme = "tokyo-night";
|
||||
hyprland.gaps_in = 8;
|
||||
hyprland.gaps_out = 16;
|
||||
apps.opencode.enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Ship your own Hyprland keybindings instead of Nomarchy's defaults
|
||||
|
||||
Nomarchy deploys its `bindings.conf` with `lib.mkDefault`, so a higher-priority assignment from your own `home.nix` wins:
|
||||
|
||||
```nix
|
||||
{
|
||||
xdg.configFile."hypr/bindings.conf".source = ./my-bindings.conf;
|
||||
}
|
||||
```
|
||||
|
||||
The same pattern works for any file Nomarchy deploys via `xdg.configFile.<path>.source = lib.mkDefault …` — point at your own file and skip the default.
|
||||
|
||||
---
|
||||
|
||||
## Where these are defined
|
||||
|
||||
- `core/system/options.nix` — most `nomarchy.system.*` options
|
||||
- `core/system/hardware.nix` — `nomarchy.hardware.*`
|
||||
- `core/system/impermanence.nix` — `impermanence.enable`
|
||||
- `core/home/options.nix` — most home-side `nomarchy.*` options
|
||||
- `core/home/overrides.nix` — `nomarchy.overrides.*` (reserved; currently no-op)
|
||||
- `themes/engine/loader.nix` — `nomarchy.themeLoader.*`
|
||||
- `features/apps/vscode.nix` — `nomarchy.vscode.*`
|
||||
201
docs/ROADMAP.md
Normal file
201
docs/ROADMAP.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# Nomarchy Roadmap
|
||||
|
||||
This is the mid-term plan for Nomarchy. It exists so future sessions — human or agent — can pick up work without re-deriving context. Items move from **Now** → **Next** → **Later** as priorities shift, and from any column into **Shipped** at the bottom when done. There are no dates: ship-when-ready.
|
||||
|
||||
If you're new here, also read [`docs/STRUCTURE.md`](STRUCTURE.md) and [`docs/OPTIONS.md`](OPTIONS.md). Existing-NixOS users should also read [`docs/MIGRATION.md`](MIGRATION.md).
|
||||
|
||||
## 1. Vision & guardrails
|
||||
|
||||
Nomarchy is a NixOS-based distribution that gives you a polished Hyprland desktop (Hyprland + waybar + walker + a curated theming engine) on a strictly declarative, flake-based foundation. Goal: power-user polish without giving up reproducibility.
|
||||
|
||||
Guardrails (apply when adding anything):
|
||||
|
||||
- **Declarative-first.** No imperative state in `core/`. Anything mutable lives in `~/.config/nomarchy/state.json` or in NixOS options.
|
||||
- **Downstream-flake friendly.** Every behavior toggle is a `nomarchy.*` option documented in `docs/OPTIONS.md`. Adding a feature without a corresponding option is a bug.
|
||||
- **Opt-in by default.** New features default off (or default to the existing behavior). The installer can flip defaults for the user, but the option must read sensibly when set by hand.
|
||||
- **Reuse before invent.** Before adding a script, grep `core/system/scripts/`, `features/scripts/utils/`, and `themes/engine/scripts/` — there are ~155 of them, and many of the things you want already exist.
|
||||
|
||||
## 2. Now / Next / Later board
|
||||
|
||||
### Now (ready to pick up)
|
||||
|
||||
- **Full QA audit of shipped features.** Walk every feature/component end-to-end on a real install, fix what's small, log what's not. Runs as per-component PR sweeps — methodology in [Pillar 8](#8-pillar-qa-audit--features--components).
|
||||
- **Installer: "What's installed?" summary on first boot.** Surface what the installer actually wrote (theme, font, profiles, drives, form factor) from `state.json` + `nomarchy-system-scripts` introspection so the user can verify before they start customising. Detail in [Pillar 4](#4-pillar-installer).
|
||||
- **Installer: optional non-LUKS branch.** Let users explicitly opt out of FDE during install. Detail in [Pillar 4](#4-pillar-installer).
|
||||
|
||||
### Next (bigger lifts that build on Now)
|
||||
|
||||
- **Accessibility — home-side companion.** Hyprland-side bits the system preset can't reach: slower `input.repeat_rate` / `repeat_delay` defaults, `SUPER+ALT+S` keybinding to launch Orca, and a high-contrast palette under `themes/palettes/`. Gated on a new `nomarchy.accessibility.enable` mirror of the system option.
|
||||
- **Gaming — declarative flathub remote.** `services.flatpak.enable` doesn't ship a declarative remote API in nixpkgs. Either add the `flatpak-managed-install` overlay, write a one-shot systemd unit that runs `flatpak remote-add --if-not-exists flathub …`, or surface the manual step in `nomarchy-welcome`.
|
||||
- **Plymouth theme variants per palette.** Currently one Plymouth theme; could template per-palette so the boot splash matches the active theme.
|
||||
- **Implement `nomarchy.overrides.*` file-based override loader.** The option surface is declared in `core/home/overrides.nix` but the loader doesn't exist — files dropped under `~/.config/nomarchy/overrides/` are ignored. Spec: when `overrides.enable = true`, for each `xdg.configFile.<path>` Nomarchy deploys with `lib.mkDefault`, check whether `~/.config/nomarchy/overrides/<path>` exists at build time; if so, use it as the source. Requires deciding whether discovery happens at activation time (cheap, but rebuild-required to pick up new files) or via a populated `paths` attrset (Nix-side, evaluated once per rebuild). Until shipped, document the per-file workaround (`xdg.configFile.<path>.source = ./mine`) in OPTIONS.md.
|
||||
|
||||
### Later (speculative or research-shaped)
|
||||
|
||||
- **Declarative-state migration.** Move the bits of `state.json` that don't actually need runtime mutability (theme, font, isLightMode) into NixOS / home-manager options, leaving only genuinely runtime-only state behind. Reduces the "two sources of truth" surface.
|
||||
- **Rolling vs pinned channel choice in the installer.** Today the generated flake pins `nomarchy` to a rev. Offer a "rolling" option that follows `main` and a `nomarchy-rollback` helper for stuck rebuilds.
|
||||
- **Theme creation wizard.** A `nomarchy-theme-new` script that scaffolds a new palette from a base16 hex set (or by sampling a wallpaper), runs `nomarchy-themes-prebuild`, and opens a PR template.
|
||||
- **CI matrix on Forgejo Actions.** On every push: `nix flake check`, build `nomarchy-installer`, `nomarchy-live`, `default`. On tag: publish ISOs as release artefacts.
|
||||
- **Golden-image VM tests per palette.** A `nixosTest` per palette that boots the `default` config, takes a screenshot, and diffs against a golden image. Catches Stylix regressions before they hit users.
|
||||
- **Forgejo release pipeline.** `vYY.MM.x` tags matching the upstream NixOS channel; the pipeline pushes the three ISOs and an updated `flake.lock` snapshot.
|
||||
- **Optional `nomarchy-installer-vm`** rebuilt as a real flake app (not a one-off shell script) so users can install Nomarchy into a libvirt VM declaratively.
|
||||
- **Surface support module** via the relevant `nixos-hardware` profile + Surface kernel patches behind a `nomarchy.hardware.isSurface` toggle.
|
||||
- **Consolidate palette imports in `flake.nix` via `nomarchyLib`.** `flake.nix:79-80` re-imports `./themes/palettes` and recomputes `themeNames` even though `lib/default.nix` already exports both. Two computations, same result today — drift risk tomorrow. Import `nomarchyLib = import ./lib { inherit lib; }` once and use `nomarchyLib.{palettes,themeNames}` to make `lib/default.nix` the single source of truth for the theme list.
|
||||
- **Decide what to do about `features/apps/chromium/Default/Preferences`.** The module deploys a static 204-byte `Default/Preferences` (setting `extensions.theme.use_system = false`, `browser.theme.color_scheme = 2`) into chromium's mutable profile directory via Home Manager symlink. Chromium expects to write that file at runtime, so either the symlink is silently replaced on first save (losing the static defaults) or the write fails silently. The real chromium theming work happens via managed policies in `core/system/browser.nix`. Probably the user-profile deployment should be removed; needs someone with chromium-internals knowledge to confirm before deletion.
|
||||
- **`themes/templates/*.tpl` — decide what these are for.** Eleven mustache-style templates (`alacritty.toml.tpl`, `btop.theme.tpl`, `kitty.conf.tpl`, etc.) are deployed to `~/.local/share/nomarchy/templates/` via `themes/engine/files.nix`, but no script in the tree consumes them. Likely vestigial from a pre-stylix templating system. Either delete the directory + the `xdg.dataFile` deployment, or document them as user-reference assets and explain how to use them.
|
||||
- **Move `programs.uwsm` Hyprland session out of `core/system/virtualization.nix`.** Session-manager config is wired in the virtualization module by historical accident — it's loaded unconditionally on every install and has nothing to do with libvirt/docker. Move to a dedicated `core/system/session.nix` (or fold into the Hyprland feature module) so the location matches the responsibility.
|
||||
- **Route installer keymap into Hyprland's Wayland session.** `core/home/config/nomarchy/default/hypr/input.conf:3` hardcodes `kb_layout = us`. The installer writes `services.xserver.xkb.layout = "$KEYMAP_LAYOUT"` (and `console.keyMap`), but Hyprland reads its own input config on native Wayland, so a non-US user's chosen layout works in XWayland apps and the TTY console but not in native Wayland apps — surprising and inconsistent. Fix paths: (a) template `input.conf` from a new `nomarchy.keymap.{layout,variant}` home option that the installer writes alongside `formFactor`, or (b) propagate `XKB_DEFAULT_LAYOUT` via session env so Hyprland's fallback kicks in. Option (a) is the durable fix; needs the installer's heredoc to add the option write.
|
||||
- **Make `nomarchy.toggles.waybar` a Nix-level gate, or document it as runtime-only.** Today the toggle is exported as `NOMARCHY_TOGGLE_WAYBAR` env, consumed only by `nomarchy-toggle-waybar` (which pkill/exec's at runtime). The Nix module always sets `programs.waybar.enable = lib.mkDefault true`, so waybar comes back on every rebuild/reboot regardless of the toggle. Inconsistent with `toggles.idle`, which correctly gates `services.hypridle.enable`. Either gate `programs.waybar.enable` on the toggle (persistent) or rename the option to make its session-only nature obvious.
|
||||
|
||||
## 3. Pillar: Script & menu audit
|
||||
|
||||
Nomarchy ships **~155** `nomarchy-*` scripts across three directories, plus a 379-line `nomarchy-menu` with 23 submenu functions. Some are first-class Nomarchy work; some are direct Omarchy ports that haven't been adapted; some are dangling references the menu calls but no script implements (e.g. `nomarchy-backup`, `nomarchy-debug`, `nomarchy-pkg`, `nomarchy-pkg-aur-add`, `nomarchy-plymouth`, `nomarchy-refresh-hyprland`, `nomarchy-reinstall`, `nomarchy-rollback`, `nomarchy-screenrecord-filename`, `nomarchy-theme`, `nomarchy-update-firmware`, `nomarchy-upload-log`, `nomarchy-version`, `nomarchy-wallpaper`, `nomarchy-skill`, `nomarchy-luks`).
|
||||
|
||||
This pillar fixes that. It runs as two phases.
|
||||
|
||||
### Phase A — Inventory & triage
|
||||
|
||||
Lands as a single PR. Output is `docs/SCRIPTS.md` populated with rows for every script and every menu item.
|
||||
|
||||
1. Run a generator (one-shot helper, doesn't have to be checked in) that produces three lists:
|
||||
- All `nomarchy-*` scripts under `core/system/scripts/`, `features/scripts/utils/`, `themes/engine/scripts/`.
|
||||
- All `nomarchy-*` *callers* (grep `core/`, `features/`, `themes/`, `installer/`, `bin/`).
|
||||
- The set difference (orphaned callers ↔ unreferenced scripts).
|
||||
2. Walk `features/scripts/utils/nomarchy-menu` and list every menu entry with its target script.
|
||||
3. Tag each row with a status:
|
||||
- `kept` — works on Nomarchy, no change needed.
|
||||
- `port-from-omarchy` — exists upstream, needs adapting (drop pacman/yay/AUR, repath to NixOS, talk to `nomarchy.system.*` options).
|
||||
- `delete-dead` — neither used nor needed; remove and update callers.
|
||||
- `stub-with-notify` — temporarily replace with a `notify-send "Not yet implemented in Nomarchy"` so the menu stops looking broken until the work is scheduled.
|
||||
- `unknown` — needs a deeper look before tagging.
|
||||
4. The completed table lives at [`docs/SCRIPTS.md`](SCRIPTS.md). The roadmap links to it; this section just sets the methodology.
|
||||
|
||||
### Phase B — Adapt or remove
|
||||
|
||||
Lands as PR batches of ~10 scripts each, branch named `wave/audit-<batch>`. Per script:
|
||||
|
||||
- For `port-from-omarchy`: rewrite the script for Nomarchy paths (`/etc/nixos`, `nixos-rebuild`, `home-manager`, no Arch idioms), wire it into `nomarchy.system.*` where applicable, and update every caller (menu, waybar, keybindings).
|
||||
- For `delete-dead`: `git rm` the script *and* fix every caller — a `find` + `sed` pass against `nomarchy-menu`, every `*.conf`, and every nix file.
|
||||
- For `stub-with-notify`: write the one-liner stub in place. The roadmap row stays open until the real implementation lands.
|
||||
|
||||
Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes, and reviewers spot-check that no caller still points at a stale name.
|
||||
|
||||
## 4. Pillar: Installer
|
||||
|
||||
- "What's installed?" summary screen on boot of a freshly-installed system, sourced from `state.json` + `nomarchy-system-scripts` introspection (Now).
|
||||
- Optional non-LUKS branch in the installer for users who explicitly opt out of FDE (Now).
|
||||
- Richer disk metadata (Shipped).
|
||||
- `disko-golden.nix` variants for software-RAID and BTRFS-pool-as-root (Shipped).
|
||||
- Pre-flight resume polish (Shipped).
|
||||
- Software-profile multi-select (Shipped).
|
||||
- Form-factor → laptop preset (Shipped).
|
||||
|
||||
## 5. Pillar: Power, hardware, presets
|
||||
|
||||
- Auto-detect dGPU presence in `installer/hardware-db.sh` and pre-fill `hardware.nvidia.prime.{intel,nvidia}BusId` in the generated `system.nix` (driver stack itself is Shipped — see entry below).
|
||||
- Surface support behind `nomarchy.hardware.isSurface` (Later).
|
||||
- Laptop preset: TLP, upower, brightness, lid, hypridle tuning (Shipped).
|
||||
- Desktop preset: performance governor, no laptop UI (already filtered), ZFS hooks (Shipped).
|
||||
- Accessibility preset (Shipped).
|
||||
- Gaming preset (Shipped).
|
||||
- Vendor matchers in `installer/hardware-db.sh` (Shipped — ROG Ally added; Surface/Framework/Lenovo entries corrected; Steam Deck + Snapdragon X documented as nixos-hardware-unsupported. CI now lints DB references).
|
||||
|
||||
## 6. Pillar: Onboarding & docs
|
||||
|
||||
- `nomarchy-welcome` first-run wizard (Shipped).
|
||||
- `docs/KEYBINDINGS.md` auto-generator (Shipped).
|
||||
- `docs/TROUBLESHOOTING.md` (Shipped).
|
||||
- `docs/index.md` / README docs index (Shipped — `README.md` links every doc in `docs/`).
|
||||
- `nomarchy-manual` — opens the local `~/.local/share/nomarchy/README.md` via `xdg-open` (Shipped).
|
||||
|
||||
## 7. Pillar: Test, CI, release
|
||||
|
||||
- Forgejo Actions workflow:
|
||||
- on every push to `main`: `nix flake check` (≈ what we run by hand today).
|
||||
- on every PR: also build all three ISOs (cache hit on most of them).
|
||||
- on tag `vYY.MM.x`: publish ISOs as release artefacts.
|
||||
- Versioning scheme: `vYY.MM.x` matching the upstream NixOS channel (e.g. `v25.11.3`).
|
||||
- `nixosTest` per palette: boots `default` in a VM, screenshots the SDDM splash and the Hyprland desktop, diffs vs golden. Failure surfaces as CI red.
|
||||
- A small `bin/utils/nomarchy-bench-iso-build` that records ISO build time + size into a per-commit JSON so we notice regressions.
|
||||
|
||||
## 8. Pillar: QA audit — features & components
|
||||
|
||||
Nomarchy now spans an installer, ~159 `nomarchy-*` scripts, a Hyprland desktop stack (Hyprland + waybar + walker + nightlight + idle), curated apps, a 22-palette theme engine, and two ISO hosts. Pillar 3 audited script *existence*; this pillar audits feature *behavior*. The goal: walk every shipped feature end-to-end on a real install, fix every bug or surprise inline when small, and capture the rest as new roadmap rows.
|
||||
|
||||
Runs as **per-component sweeps**. One PR per component, branch `wave/qa-<component>`. Don't grow scope mid-PR — bugs that need a new option, refactor, or missing module become a new **Now**/**Next** row.
|
||||
|
||||
Components (each is one sweep):
|
||||
|
||||
1. **Installer** — `installer/install.sh`, `installer/hardware-db.sh`, disko configs. Fresh install + `--resume` + `--dry-run`, on laptop and desktop, with FDE (non-LUKS branch is Later). Verify every generated file (`flake.nix`, `system.nix`, `home.nix`, `hardware-selection.nix`, `state.json`) is correct and idempotent.
|
||||
2. **First-boot UX** — `nomarchy-welcome`, generated `home.nix`, SDDM and Plymouth metadata, default theme/font/panel position. Re-run on a clean VM; note every prompt that confuses and every default that's wrong.
|
||||
3. **Core system modules** — `core/system/*` (laptop, desktop, accessibility, gaming, hybridGPU, impermanence, network, hardware, branding). For each: enable → rebuild → observe the claimed effect → disable → rebuild → observe it's gone. Cross-check against `docs/OPTIONS.md`.
|
||||
4. **Core home modules** — `core/home/*` (options, state, behavior, overrides, deployed config). Verify every home-side `nomarchy.*` option does what its description claims; confirm `~/.config/nomarchy/overrides/` actually overrides.
|
||||
5. **Desktop stack** — Hyprland (keybindings, window rules, monitors, input), waybar (every module × both panel positions × both form factors), walker (every launcher mode), idle, nightlight, notifications (mako). Reconcile `docs/KEYBINDINGS.md` against runtime.
|
||||
6. **Apps** — `features/apps/*`. Each app: launches, themed via Stylix, configured as expected. Catches the "we package it but nobody configured it" class.
|
||||
7. **Theme engine + palettes** — `nomarchy-theme-set` across all 22 palettes, font and wallpaper switchers, light-mode toggle. Verify per-palette Stylix targets render correctly across SDDM, Plymouth, GTK, Qt, terminals, browsers, waybar, walker.
|
||||
8. **Scripts (runtime behavior)** — Pillar 3 confirmed existence; this sweep runs every user-visible script (especially every `nomarchy-menu` entry) on current NixOS and confirms it actually does the thing.
|
||||
9. **ISOs** — boot `nomarchy-installer` and `nomarchy-live`; verify the `nomarchy-test-live-iso` flow; check the installer ISO ships every tool `install.sh` calls (regression class: `hardware-db.sh` missing, already shipped).
|
||||
10. **Lib + state schema** — `lib/state-schema.nix`, color resolution, path helpers. Cross every codepath that produces `state.json` (installer, welcome wizard, hand-edit) against the schema; confirm bad inputs are rejected with a useful message.
|
||||
|
||||
Per-PR deliverable:
|
||||
|
||||
- PR body lists what was tested, what was broken, what was fixed inline, what was deferred (with the new roadmap row linked).
|
||||
- Doc updates ride with the change per `docs/AGENT.md` §5.4.
|
||||
- Don't bundle fixes across components — keep one component per branch so reviewers can spot-check end-to-end without context-switching.
|
||||
|
||||
Pillar is **done** when every component has a closed `wave/qa-<component>` PR and the roadmap captures every deferred finding.
|
||||
|
||||
## 9. Process notes
|
||||
|
||||
- **Branch naming:** `wave/<pillar>-<short-slug>`. Examples: `wave/audit-pkg-scripts`, `wave/installer-disk-metadata`, `wave/laptop-preset`.
|
||||
- **One PR per audit batch.** Reference rows in `docs/SCRIPTS.md`. Smaller PRs review faster.
|
||||
- **Living roadmap.** When an item ships, move it to the **Shipped** section at the bottom of this file rather than deleting it. Future-us gets a free changelog.
|
||||
- **Plan files live separately.** Detailed implementation plans (the per-feature design docs Claude writes in plan mode) belong under `~/.claude/plans/` per session, not in the repo. The roadmap is the durable reference; plan files are working notes.
|
||||
- **Don't widen scope mid-PR.** If the audit reveals a missing feature, file a new roadmap row, don't graft it onto the current PR.
|
||||
|
||||
## Shipped
|
||||
|
||||
(Move items here when they land — keep them brief, link the commit/PR.)
|
||||
|
||||
- _2026-05-18_ — Hardware DB correctness pass + ROG Ally support + CI lint. Audited every `nomarchy-hardware-db` entry against `inputs.nixos-hardware.nixosModules` and found **21 of 43 entries (49%) referenced modules that don't exist** — `microsoft-surface-pro-8`, `lenovo-thinkpad-x1-carbon-gen11`, `framework-13-11th-gen-intel`, etc. were all eval-time failures waiting for a real user. Rewrote the DB to use only valid module names: Framework gens dropped the "13-" prefix in nixos-hardware (`framework-11th-gen-intel`, not `framework-13-11th-gen-intel`); ThinkPad X1 modules are `x1-Nth-gen`, not `x1-carbon-genN`; Surface Pro 6/7/8/10 all share `microsoft-surface-pro-intel`; Surface Book / Intel Surface Laptop have no module (rows dropped, generic detection still emits sensible `common-pc-laptop` + cpu/gpu). Added matchers for **ROG Ally** (RC71L / RC72LA / "ROG Ally" via `asus-ally-rc71l`). Documented Steam Deck and Snapdragon X as nixos-hardware-unsupported in a footer comment (Steam Deck → Jovian-NixOS; Snapdragon X → installer is x86_64 only). Added a CI step (`.forgejo/workflows/check.yml`) that fails on any DB entry whose module name isn't in `nixos-hardware.nixosModules` — closes this regression class.
|
||||
- _2026-05-18_ — `nomarchy-manual` re-targeted at local docs. The script's `xdg-open` previously pointed at `https://learn.omacom.io/2/the-nomarchy-manual` — an upstream Omarchy URL that opened an unrelated page when users hit the menu's Help entry. Now opens `~/.local/share/nomarchy/README.md` (the local docs index per `SKILL.md`'s "Out of Scope" note), with a `notify-send` fallback if the source tree isn't synced.
|
||||
- _2026-05-18_ — Docs hygiene: STRUCTURE.md "Root Directory" + Pillar 6 reality-check. `docs/STRUCTURE.md` listed three top-level files that don't exist (`GEMINI.md`, root-level `STRUCTURE.md`, `TODO.md`) — replaced with an accurate root listing plus a `docs/` sub-tree that names every doc. Pillar 6 in this file had `nomarchy-welcome`, `docs/TROUBLESHOOTING.md`, and the "docs index" bullet still marked Next despite all three shipping on 2026-04-26 — moved to `(Shipped)`. `nomarchy-manual` bullet's "orphaned reference today" claim was stale (the script is called from `nomarchy-menu` and `nomarchy-theme-install`); rewritten to reflect the real remaining issue — its hardcoded `xdg-open https://learn.omacom.io/2/the-nomarchy-manual` is an Omarchy URL.
|
||||
- _2026-05-18_ — Installer state.json is now schema-driven. Replaced the heredoc in `installer/install.sh` that hardcoded the JSON literal (theme/dns/wifi/features/etc.) with a `nix eval` of `lib/state-schema.nix`'s `system` block, overlaid with the installer-chosen timezone. Closes the last source-of-truth split after the centralization batch — adding a new default in the schema now reaches the installer with no further plumbing. Output is identical modulo alphabetical key ordering (Nix's `builtins.toJSON` sorts keys; toggle scripts read/write via `jq` so it's invisible to them). Dry-run path unchanged (still bind-mounts a fake `/mnt` so the generator's absolute paths resolve correctly). `bash -n` + `shellcheck --severity=error` clean.
|
||||
- _2026-05-18_ — Complete the hybrid-GPU wiring + fix unoverridable state-derived options. Two related fixes shipped together. **(1)** `nomarchy.system.features.hybridGPU = true` now wires the full NVIDIA driver stack (`services.xserver.videoDrivers = ["nvidia"]`, `hardware.graphics.{enable,enable32Bit}`, `hardware.nvidia.{modesetting,powerManagement}.enable`, `package = nvidiaPackages.stable`, `boot.kernelParams += "nvidia-drm.modeset=1"`) — was previously enabling only `supergfxd` mode-switching while leaving the system with no NVIDIA driver loaded, so mode switches silently no-op'd. All knobs use `lib.mkDefault` so a downstream `system.nix` can pin a beta driver, flip to the open kernel module, etc. Bus-ID prime config (per-machine) stays user-supplied — `docs/OPTIONS.md` has the full recipe. **(2)** Both `core/system/state.nix` and `core/home/state.nix` now use `lib.mkDefault` on every state.json-derived assignment, fixing a class of "I set X in my system.nix but it doesn't take effect" bugs (the state-derived value was at default priority and conflicted with the user's same-priority override). Side-effect cleanup: `core/system/state.nix` now also reads from `lib/state-schema.nix` like `core/home/state.nix` does, completing the schema-centralization started two batches ago. Verified `nix flake check` + an override test that flips hybridGPU via an overlay and confirms the entire driver stack engages.
|
||||
- _2026-05-18_ — Pillar 4: pre-flight resume polish. Fixed four resume-flow gaps in `installer/install.sh`: (1) `--resume` with a missing state file now errors loudly with a tmpfs explanation instead of silently falling through to a fresh prompt cycle (the most common operator confusion was "rebooted, forgot tmpfs eats /tmp/, watched the installer start over without realising"); (2) on resume, the saved target drive is validated as a block device before any disk-phase step runs — catches the live-ISO USB-unplugged / non-deterministic /dev/sdX class of mid-install failures; (3) `save_state` now stamps an ISO-8601 timestamp and `load_state` shows a `(saved Xm ago)` banner plus a `Target: /dev/X → user @ host` summary line, so the user can `Ctrl-C` if they're resuming onto the wrong host before any destructive prompt fires; (4) `--help` now documents the tmpfs limitation. `shellcheck --severity=error` passes.
|
||||
- _2026-05-18_ — Declarative-state defaults centralization. Made `lib/state-schema.nix` the single source of truth for every state-default that previously lived in three places (the schema itself, `core/system/options.nix` / `core/home/options.nix` `default = …` clauses, and `core/home/state.nix` `or …` fallbacks). Replaced ~25 hardcoded literals with `schema.<scope>.<key>` reads. Side-effect: fixed a lingering bug where `core/home/options.nix:theme` still defaulted to `"summer-night"` after the system-side was moved to `"nord"` — half the codebase's home option resolved to the wrong theme when state.json was missing/blank. `nix flake check --no-build` confirms zero semantic change for every other field. Doesn't touch the installer-written `state.json` (separate batch — needs schema → JSON generation).
|
||||
- _2026-05-18_ — Pillar 7 first step: Forgejo Actions CI (eval + lint). New `.forgejo/workflows/check.yml` runs on every push to `main` and every PR: (1) `nix flake check --no-build` to catch eval regressions, (2) `bash -n` + `shellcheck --severity=error` over every `nomarchy-*` bash script (whole-tree, not just changed files — gates branches that bypass the pre-commit hook), (3) `docs/SCRIPTS.md` drift check (fails loudly if a script change didn't regenerate the audit doc). All three checks pass locally on the current tree. Activation requires enabling Actions on the Forgejo repo and registering a `forgejo-runner`; the workflow itself is dormant until then. ISO build job is intentionally deferred — needs a binary cache (Cachix/Attic) to be tractable.
|
||||
- _2026-05-18_ — **Pillar 3 Phase B: complete.** Final batch (restart/sudo/theme/misc clusters) cleared the last 13 `unused?` rows. Deleted five truly dead scripts: `nomarchy-restart-{hyprctl,mako}` (theme switching calls `hyprctl reload`/`makoctl reload` directly now), `nomarchy-restart-tmux` (one-liner of marginal value), `nomarchy-battery-present` (battery monitor checks `/sys/class/power_supply/BAT*` inline), `nomarchy-sudo-keepalive` (intended-to-be-sourced building block with no users). Surfaced eight useful tools in `SKILL.md` so the audit catches them as `kept` and AI assistants can discover them: `nomarchy-restart-trackpad` (intel_quicki2c reload), `nomarchy-sudo-{passwordless-toggle,reset}`, `nomarchy-theme-{bg-install,refresh,remove}`, `nomarchy-refresh-fastfetch`, `nomarchy-windows-vm` (new Virtualization section). Final state: 159 scripts, all `kept`, `unused?` = 0, missing references = 0.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: webapp/tui/voxtype install-remove pair triage. Deleted two dead webapp URI handlers (`nomarchy-webapp-handler-hey`, `nomarchy-webapp-handler-zoom`) — no `.desktop` MimeType registration anywhere routed `mailto:`/`zoom:` URIs to them, so the handlers could never fire. Surfaced six useful CLI tools in `SKILL.md` "Common Tasks" so they're discoverable by AI assistants and tagged `kept` by the audit: `nomarchy-webapp-{remove,remove-all}`, `nomarchy-tui-{remove,remove-all}`, `nomarchy-voxtype-{install,remove}`. Script count 166 → 164; `unused?` 21 → 13.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: dead-code sweep (NixOS-irrelevant Omarchy ports). Deleted five scripts that duplicated NixOS-native facilities or referenced infrastructure Nomarchy doesn't ship: `nomarchy-rollback` (boot-menu generations + `nixos-rebuild rollback` already cover this), `nomarchy-snapshot` (used `snapper`; impermanence and BTRFS subvolumes are the Nomarchy answer), `nomarchy-migrate-state` (one-shot pre-unification migration, no current callers), `nomarchy-config-direct-boot` (added an EFI entry for a UKI we never build), and `nomarchy-npx-install` (Arch idiom — `nix-shell -p nodejs` is the NixOS path). Kept `nomarchy-build-iso` and `nomarchy-build-live-iso` and surfaced them in README §2 so the audit tags them `kept`. Script count 171 → 166.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: missing-references triage. (1) Wrote `themes/engine/scripts/nomarchy-theme-next` so `SKILL.md`'s documented "cycle to next theme" command resolves; (2) scrubbed three stale `nomarchy-dev-*` references from `core/home/config/nomarchy-skill/SKILL.md`; (3) added a line-context filter to both `nomarchy-docs-scripts` generators that drops `nomarchy-*` tokens appearing in Nix `pname`/derivation idents, `/tmp/` & `/etc/sudoers.d/` paths, `nixosConfigurations.*` / `packages.*` flake outputs, `mktemp -t` prefixes, systemd unit vars, `./result/bin/run-` binaries, and `docker` container references; (4) added a small token-level denylist for five residual non-script identifiers (`nomarchy-plymouth`, `nomarchy-sddm-theme`, `nomarchy-live`, `nomarchy-rev`, `nomarchy-windows`) that survive line filtering. `docs/SCRIPTS.md` "Missing references" section is now empty (was 15).
|
||||
- _2026-05-04_ — Pillar 8: Distro Branding. (1) Scrubbed remaining "Omarchy" and "Spirit of Omarchy" references from README, scripts, and welcome wizard; (2) Updated `nomarchy-welcome` banner and `nomarchy-version` codename ("Sovereign"); (3) Verified existing `core/system/branding.nix` handles OS-release and bootloader labels; (4) Confirmed SDDM and Plymouth metadata are already Nomarchy-branded.
|
||||
- _2026-05-04_ — Thorough Out-of-the-Box QA Audit. (1) Restored automatic wallpaper switching by removing image filters from deployed themes; (2) Fixed broken "Style" menu entries by creating missing `about.txt` and `screensaver.txt` branding files; (3) Cleaned up conflicting keybindings by removing deprecated `tiling.conf` and updating the doc generator; (4) Removed legacy Nord theme hack from `nomarchy-theme-set`; (5) Fixed JSON parse error in `summer-day` waybar theme.
|
||||
- _2026-05-03_ — Fixed multi-disk LUKS/BTRFS boot hang. (1) Moved temporary LUKS keyfile to `/tmp/` so Disko correctly omits it from the runtime configuration; (2) Injected `x-systemd.requires` and `x-systemd.device-timeout=0` into BTRFS mount options to ensure all LUKS drives are decrypted before mounting.
|
||||
- _2026-05-03_ — Fixed CLI wrappers and removed obsolete code. (1) Updated `nomarchy-font`, `nomarchy-theme`, and `nomarchy-wallpaper` CLI wrappers to use modern Walker menus; (2) Removed the obsolete and broken `themes/engine/switcher.nix` and its associated Nix-inlined scripts; (3) Cleaned up remaining `$NOMARCHY_PATH` references from the Omarchy era.
|
||||
- _2026-05-03_ — Fixed `/etc/nixos` ownership after installation. Added a `chown -R $USERNAME:users /etc/nixos` step via `nixos-enter` at the end of `installer/install.sh` so the main user owns their configuration and can run `home-manager` commands without `sudo`.
|
||||
- _2026-05-01_ — Installer & Script Audit Polish. (1) Fixed a critical bash dynamic scoping bug in `installer/install.sh` where `rc=0` assignments inside functions (Impermanence, Form Factor) were clobbering the main loop's return code, causing the installer to abort when "No" was selected; (2) Polished `hosts/nomarchy-live.nix` with auto-login for the `nixos` user and passwordless sudo for the `wheel` group; (3) Repurposed `nomarchy-toggle-suspend` to execute `systemctl suspend` directly and updated `nomarchy-menu` to reflect this; (4) Updated `nomarchy-launch-wifi` to use `nmtui` in Alacritty; (5) Regenerated `docs/SCRIPTS.md` to reflect the updated script mappings.
|
||||
- _2026-04-30_ — `set -e` sweep across `nomarchy-*` scripts. Added `set -e` to 142 of 169 bash scripts that lacked it (27 already had it). Halts a class of "command failed silently in the middle of a chain, system left in half-applied state" bugs that produced repeat-fix commits. One deliberate exception: `nomarchy-menu` runs without `set -e` because it's an interactive UX loop where action failures should re-display the menu rather than abort the script. Pre-commit hook now enforces `bash -n` + `shellcheck --severity=error` so future scripts can't regress this.
|
||||
- _2026-04-30_ — Installer disk-phase reliability. Hardened `installer/install.sh` and consolidated the disko configs: (1) `select_disk` now hides the live-ISO boot device(s) so the installer can't format its own boot media (`NOMARCHY_INSTALL_ALLOW_ISO_TARGET=1` to override); (2) added a 10 GiB minimum-capacity preflight; (3) `prewipe_target_drive` enumerates every active dm-crypt mapping backed by the target drive and closes them, drops the silent `|| true` from `wipefs`/`sgdisk`/`dd`, bounds `udevadm settle` to 30s, and refuses to continue if anything is still mounted; (4) wrapped the disko call in `run_disko_with_retry` with last-30-lines + Retry / View full log / Abort dialog on failure; (5) replaced the sed-templated `disko-golden.nix` + `disko-btrfs-multi.nix` pair with a single `disko-config.nix` Nix function called via `--argstr mainDrive … --arg extraDrives '[…]'` — eliminates a class of escaping bugs (cf. `3aadc36`); (6) added an EXIT trap so the tmpfs LUKS key file is removed even on early abort.
|
||||
- _2026-04-30_ — Gaming home-side companion. New `nomarchy.gaming.enable` option (mirror of `nomarchy.system.gaming.enable`) and `core/home/gaming.nix` module that injects a Hyprland `windowrulev2 = fullscreen, class:^(steam_app_).*$` so Steam-launched games grab the whole screen. Closes the "Gaming — Hyprland window rule" Next-column row.
|
||||
- _2026-04-26_ — Default to highest resolution (`highres`) for monitors. Updated `features/desktop/hyprland/config/monitors.conf` and forced it in the live ISO (`nomarchy-live`) to resolve issues where some hardware would default to a low resolution (1024x768).
|
||||
- _2026-04-26_ — First-run welcome wizard (`nomarchy-welcome`). Extended from a one-shot greeter into a guided picker for theme, font, and panel position. Added Step 4 to generate a starter `home.nix` if missing. State is now persisted in `state.json` via `.welcome_done`. Added `nomarchy.panelPosition` option to Waybar.
|
||||
- _2026-04-26_ — Multi-disk BTRFS support in the installer. Added `installer/disko-btrfs-multi.nix` template and updated `installer/install.sh` to allow selecting multiple drives via `gum choose --no-limit`. Implements BTRFS "single" data + RAID1 metadata across multiple LUKS-encrypted drives.
|
||||
- _2026-04-26_ — Distro Branding Phase 2. Updated bootloader entries to use "Nomarchy" as the label. Set ISO volume IDs to `NOMARCHY_INSTALLER` and `NOMARCHY_LIVE`. Fixed branding in Plymouth theme metadata and SDDM metadata.
|
||||
- _2026-04-26_ — Distro Branding Phase 1. Renamed `installerIso` to `nomarchy-installer` and `installerIsoGraphical` to `nomarchy-live`. Updated metadata and host configurations. Scrubbed "Omarchy" from Plymouth and installer messages.
|
||||
- _2026-04-26_ — Fix `hardware-db.sh` missing in `nomarchy-installer.nix`. Resolved boot error where `install.sh` failed to source the hardware database on the TTY installer ISO.
|
||||
- _2026-04-26_ — Installer review-then-edit flow (`installer/install.sh`). Review screen now offers Continue / Edit a field / Abort. Edit opens a multi-select of saved fields; chosen fields clear and the next loop iteration re-prompts only those. Benefits both fresh installs (typo fixes without abort+restart) and `--resume` (lands on review immediately, since the loaded vars short-circuit each prompt). LUKS passphrase is held in memory across loop iterations so re-edits don't re-ask for it.
|
||||
- _2026-04-26_ — `docs/TROUBLESHOOTING.md`. The five most common rebuild errors (option-already-declared, attribute-missing, Stylix target conflict, home-manager `.hm-bak` churn, impermanence path missing) with copy-paste fixes. Linked from `README.md` and `docs/MIGRATION.md`.
|
||||
- _2026-04-26_ — Gaming preset module (`core/system/gaming.nix`). Opt-in `nomarchy.system.gaming.enable` (default false). Wires `programs.steam` (with `remotePlay`/`localNetworkGameTransfers` firewall holes via `mkDefault`), `programs.gamemode`, and `services.flatpak`. Flathub remote and Hyprland window-rule split into separate Next-column rows.
|
||||
- _2026-04-26_ — Accessibility preset module (`core/system/accessibility.nix`). New `nomarchy.system.accessibility.{enable,cursorSize}` options (opt-in, default off — accessibility isn't a hardware-derived signal). Enables `services.gnome.at-spi2-core`, installs Orca, and sets `XCURSOR_SIZE=32` (configurable). Hyprland-side companion (key-repeat slowdown, Orca keybinding, high-contrast palette) split into a new Next-column row.
|
||||
- _2026-04-26_ — Desktop preset module (`core/system/desktop.nix`). New `nomarchy.system.desktop.enable` option; defaults to `formFactor == "desktop"` (mirror of the laptop preset's auto-enable). Pins `powerManagement.cpuFreqGovernor` to `"performance"` and enables `services.zfs.{autoScrub,trim}` so a future ZFS pool gets sensible maintenance for free.
|
||||
- _2026-04-26_ — Laptop preset module (`core/system/laptop.nix`). New `nomarchy.system.laptop.{enable,thermald}` options; `enable` defaults to `formFactor == "laptop"` so the installer's existing `formFactor` write auto-flips it on. Wires TLP (governors + 75/80 charge thresholds), force-disables `power-profiles-daemon`, enables `upower` and `thermald` (x86_64), adds the brightnessctl udev rule for backlight without root, and sets a logind lid-switch policy that defers to `hibernation.enable`. Closes both the Now item and the largest Next item.
|
||||
- _2026-04-25_ — Software-profile multi-select in the installer. Users can now pick Dev, Gaming, Office, Media, and CLI Utils profiles during install; logic emits corresponding `home.packages` and system toggles into the generated config.
|
||||
- _2026-04-25_ — Pillar 3 Phase B: script & menu audit. Ported/implemented/stubbed ~40 scripts including `nomarchy-version`, `nomarchy-debug`, `nomarchy-reinstall`, `nomarchy-rollback`, `nomarchy-update-firmware`, `nomarchy-pkg-*`, and `nomarchy-theme-*` wrappers. Moved desktop scripts to packaged utility directory.
|
||||
- _2026-04-25_ — Docker & fwupd support. Added `nomarchy.system.virtualization.docker.enable` and `nomarchy.hardware.fwupd` options. Wires system services and adds `docker-compose` and `fwupdmgr` to PATH.
|
||||
- _2026-04-25_ — Installer VM testing. Added `installerVm` to flake nixosConfigurations, packages, and apps. `nomarchy-test-installer` now uses `nix run .#installerVm`.
|
||||
- _2026-04-25_ — `docs/KEYBINDINGS.md` auto-generator. New repo-tooling script `bin/utils/nomarchy-docs-keybindings` parses every `bindd =` / `bindeld =` line into a Markdown doc; README's keybinding table slimmed to highlights + link.
|
||||
- _2026-04-25_ — Installer disk picker shows NAME / SIZE / TYPE / VENDOR / MODEL / SERIAL columns instead of bare `lsblk`. Type derived from `ROTA` + `TRAN` (NVMe / USB / SSD / HDD). Filters loop, ram, zram, sr.
|
||||
- _2026-04-25_ — Pillar 3 Phase A: script & menu audit. New `bin/utils/nomarchy-docs-scripts` generator produces `docs/SCRIPTS.md` with 136 scripts and the menu walk pre-tagged via heuristics (`kept` / `unused?` / `missing`). Phase B (per-batch porting / removal) opens.
|
||||
- _2026-04-25_ — Installer prompts for keyboard layout + locale, applies live; new `nomarchy.{system,}.formFactor` option; waybar drops battery widget on desktop; nm-applet visibility fix in default theme; live-ISO baseline keymap/locale (`a7e7fa9`).
|
||||
- _2026-04-25_ — `docs/OPTIONS.md` reference; `docs/MIGRATION.md` linked from `README.md` (`3cb012b`, `6ef28f0`).
|
||||
282
docs/SCRIPTS.md
Normal file
282
docs/SCRIPTS.md
Normal file
@@ -0,0 +1,282 @@
|
||||
# Nomarchy Script & Menu Audit
|
||||
|
||||
Auto-generated table for [Pillar 3 of the roadmap](ROADMAP.md#3-pillar-script--menu-audit).
|
||||
**Do not edit by hand.** Regenerate after script or menu changes:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
```
|
||||
|
||||
The status column uses a Phase A heuristic — `kept` / `unused?` / `missing`.
|
||||
Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
`delete-dead`, or `stub-with-notify` and updates the rows.
|
||||
|
||||
## Status legend
|
||||
|
||||
- `kept` — script exists and is called from somewhere outside its own directory.
|
||||
- `unused?` — script exists but no caller was found. Could be dead, could be
|
||||
intentional public API. Phase B triage decides.
|
||||
- `missing` — referenced from code but no script file exists. Phase B triage
|
||||
decides whether to port from Omarchy upstream, delete the caller, or stub
|
||||
with `notify-send`.
|
||||
- `port-from-omarchy` — Phase B verdict: lift the upstream Omarchy script,
|
||||
rewrite for NixOS paths.
|
||||
- `delete-dead` — Phase B verdict: remove and update callers.
|
||||
- `stub-with-notify` — Phase B verdict: temporary `notify-send` stub.
|
||||
|
||||
## Scripts (159)
|
||||
|
||||
| Script | Location | Callers | Status | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `nomarchy-backup` | `features/scripts/utils` | features/scripts/utils/nomarchy-sync | `kept` | |
|
||||
| `nomarchy-battery-capacity` | `core/system/scripts` | core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-monitor` | `core/system/scripts` | features/scripts/battery-monitor.nix | `kept` | |
|
||||
| `nomarchy-battery-remaining` | `core/system/scripts` | core/system/scripts/nomarchy-battery-monitor,core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-remaining-time` | `core/system/scripts` | core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-status` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/system/scripts/nomarchy-battery-capacity, +1 more | `kept` | |
|
||||
| `nomarchy-brightness-display` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/media.conf,core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-brightness-display-apple` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-brightness-keyboard` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/media.conf | `kept` | |
|
||||
| `nomarchy-build-iso` | `features/scripts/utils` | README.md | `kept` | |
|
||||
| `nomarchy-build-live-iso` | `features/scripts/utils` | README.md | `kept` | |
|
||||
| `nomarchy-cmd-audio-switch` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/media.conf | `kept` | |
|
||||
| `nomarchy-cmd-present` | `features/scripts/utils` | core/home/config/nomarchy/hooks/battery-low.sample,features/scripts/utils/nomarchy-launch-editor, +4 more | `kept` | |
|
||||
| `nomarchy-cmd-screenrecord` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-cmd-screensaver` | `features/scripts/utils` | features/scripts/utils/nomarchy-launch-screensaver | `kept` | |
|
||||
| `nomarchy-cmd-screenshot` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-cmd-share` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-cmd-terminal-cwd` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||
| `nomarchy-debug` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-docs-keybindings` | `features/scripts/utils` | bin/utils/nomarchy-docs-keybindings | `kept` | |
|
||||
| `nomarchy-docs-scripts` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts | `kept` | |
|
||||
| `nomarchy-drive-info` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-select | `kept` | |
|
||||
| `nomarchy-drive-select` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-info,features/scripts/utils/nomarchy-drive-set-password | `kept` | |
|
||||
| `nomarchy-drive-set-password` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-select,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-env-update` | `core/system/scripts` | core/home/bash.nix,core/system/scripts.nix, +7 more | `kept` | |
|
||||
| `nomarchy-font` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy-skill/SKILL.md, +6 more | `kept` | |
|
||||
| `nomarchy-font-current` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-font-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-font, +2 more | `kept` | |
|
||||
| `nomarchy-font-set` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-font, +4 more | `kept` | |
|
||||
| `nomarchy-haptic-touchpad` | `core/system/scripts` | core/system/hardware.nix | `kept` | |
|
||||
| `nomarchy-hibernation-available` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hibernation-remove` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hibernation-setup` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hook` | `features/scripts/utils` | core/system/scripts/nomarchy-battery-monitor,themes/engine/scripts/nomarchy-font-set, +1 more | `kept` | |
|
||||
| `nomarchy-hw-asus-rog` | `core/system/scripts` | features/scripts/utils/nomarchy-on-boot | `kept` | |
|
||||
| `nomarchy-hw-match` | `core/system/scripts` | features/scripts/utils/nomarchy-on-boot | `kept` | |
|
||||
| `nomarchy-hw-vulkan` | `core/system/scripts` | features/scripts/utils/nomarchy-voxtype-install | `kept` | |
|
||||
| `nomarchy-hyprland-active-window-transparency-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-hyprland-monitor-scaling-cycle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-hyprland-window-close-all` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf,core/system/scripts/nomarchy-system-logout, +2 more | `kept` | |
|
||||
| `nomarchy-hyprland-window-gaps-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hyprland-window-pop` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf | `kept` | |
|
||||
| `nomarchy-hyprland-window-single-square-aspect-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hyprland-workspace-layout-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,hosts/nomarchy-installer.nix, +2 more | `kept` | |
|
||||
| `nomarchy-install-docker-dbs` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-launch-about` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-launch-audio` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +2 more | `kept` | |
|
||||
| `nomarchy-launch-bluetooth` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-launch-browser` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-launch-editor` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf, +2 more | `kept` | |
|
||||
| `nomarchy-launch-floating-terminal-with-presentation` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
||||
| `nomarchy-launch-or-focus` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/hyprland/config/bindings.conf, +6 more | `kept` | |
|
||||
| `nomarchy-launch-or-focus-tui` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
||||
| `nomarchy-launch-or-focus-webapp` | `features/scripts/utils` | features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||
| `nomarchy-launch-screensaver` | `features/scripts/utils` | features/desktop/idle.nix,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-launch-tui` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/hyprland/config/bindings.conf, +2 more | `kept` | |
|
||||
| `nomarchy-launch-walker` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/clipboard.conf,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +4 more | `kept` | |
|
||||
| `nomarchy-launch-webapp` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf, +5 more | `kept` | |
|
||||
| `nomarchy-launch-wifi` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/default/mako/core.ini, +4 more | `kept` | |
|
||||
| `nomarchy-lock-screen` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/extensions/menu.sh, +3 more | `kept` | |
|
||||
| `nomarchy-manual` | `features/scripts/utils` | core/branding/about.txt,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-menu` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +10 more | `kept` | |
|
||||
| `nomarchy-menu-keybindings` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/default/mako/core.ini, +2 more | `kept` | |
|
||||
| `nomarchy-notification-dismiss` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini | `kept` | |
|
||||
| `nomarchy-on-boot` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf | `kept` | |
|
||||
| `nomarchy-pkg-add` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-pkg-install, +2 more | `kept` | |
|
||||
| `nomarchy-pkg-aur-add` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-pkg-drop` | `features/scripts/utils` | features/scripts/utils/nomarchy-voxtype-remove | `kept` | |
|
||||
| `nomarchy-pkg-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-pkg-remove` | `core/system/scripts` | features/scripts/utils/nomarchy-pkg-drop | `kept` | |
|
||||
| `nomarchy-powerprofiles-list` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-preflight-migration` | `core/system/scripts` | core/system/scripts/nomarchy-env-update | `kept` | |
|
||||
| `nomarchy-refresh-config` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-refresh-fastfetch | `kept` | |
|
||||
| `nomarchy-refresh-fastfetch` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-refresh-hyprland` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-refresh-waybar` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-reinstall` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-app` | `features/scripts/utils` | core/system/scripts/nomarchy-restart-xcompose,features/scripts/utils/nomarchy-restart-hypridle, +3 more | `kept` | |
|
||||
| `nomarchy-restart-bluetooth` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-btop` | `features/scripts/utils` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-restart-hypridle` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-hyprsunset` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-opencode` | `features/scripts/utils` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-restart-pipewire` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-swayosd` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-terminal` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-trackpad` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-walker` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-restart-waybar` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu, +4 more | `kept` | |
|
||||
| `nomarchy-restart-wifi` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-xcompose` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-setup-dns` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-setup-fido2` | `core/system/scripts` | features/scripts/utils/nomarchy-menu,installer/install.sh | `kept` | |
|
||||
| `nomarchy-setup-fingerprint` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-show-done` | `themes/engine/scripts` | features/scripts/utils/nomarchy-launch-floating-terminal-with-presentation | `kept` | |
|
||||
| `nomarchy-show-logo` | `themes/engine/scripts` | features/scripts/utils/nomarchy-launch-floating-terminal-with-presentation | `kept` | |
|
||||
| `nomarchy-skill` | `features/scripts/utils` | core/home/configs.nix | `kept` | |
|
||||
| `nomarchy-state` | `features/scripts/utils` | core/system/scripts/nomarchy-system-reboot,core/system/scripts/nomarchy-system-shutdown, +2 more | `kept` | |
|
||||
| `nomarchy-state-write` | `features/scripts/utils` | features/scripts/utils/nomarchy-welcome | `kept` | |
|
||||
| `nomarchy-sudo-passwordless-toggle` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-sudo-reset` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-swayosd-brightness` | `core/system/scripts` | core/system/scripts/nomarchy-brightness-display,core/system/scripts/nomarchy-brightness-display-apple | `kept` | |
|
||||
| `nomarchy-swayosd-kbd-brightness` | `core/system/scripts` | core/system/scripts/nomarchy-brightness-keyboard | `kept` | |
|
||||
| `nomarchy-sync` | `features/scripts/utils` | features/scripts/utils/nomarchy-backup,README.md | `kept` | |
|
||||
| `nomarchy-system-logout` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-system-reboot` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md,core/system/scripts/nomarchy-hibernation-setup, +2 more | `kept` | |
|
||||
| `nomarchy-system-shutdown` | `core/system/scripts` | core/home/config/nomarchy/extensions/menu.sh,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-sys-update` | `features/scripts/utils` | core/home/bash.nix,core/system/scripts/nomarchy-setup-dns, +5 more | `kept` | |
|
||||
| `nomarchy-test-installer` | `features/scripts/utils` | features/scripts/utils/nomarchy-test-vm,README.md | `kept` | |
|
||||
| `nomarchy-test-live-iso` | `features/scripts/utils` | hosts/nomarchy-live.nix | `kept` | |
|
||||
| `nomarchy-test-vm` | `features/scripts/utils` | features/scripts/utils/nomarchy-test-live-iso | `kept` | |
|
||||
| `nomarchy-theme` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/elephant/nomarchy_background_selector.lua, +17 more | `kept` | |
|
||||
| `nomarchy-theme-bg-install` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-bg-next` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-wallpaper, +1 more | `kept` | |
|
||||
| `nomarchy-theme-bg-set` | `themes/engine/scripts` | core/home/config/nomarchy/default/elephant/nomarchy_background_selector.lua,features/scripts/utils/nomarchy-wallpaper | `kept` | |
|
||||
| `nomarchy-theme-current` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,themes/engine/scripts/nomarchy-theme-next | `kept` | |
|
||||
| `nomarchy-theme-install` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-theme, +2 more | `kept` | |
|
||||
| `nomarchy-theme-next` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-refresh` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-remove` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-set` | `themes/engine/scripts` | core/home/config/nomarchy/default/elephant/nomarchy_themes.lua,core/home/config/nomarchy-skill/SKILL.md, +9 more | `kept` | |
|
||||
| `nomarchy-theme-set-keyboard` | `themes/engine/scripts` | features/scripts/utils/nomarchy-on-boot | `kept` | |
|
||||
| `nomarchy-theme-set-keyboard-asus-rog` | `themes/engine/scripts` | features/scripts/utils/nomarchy-on-boot,themes/engine/scripts/nomarchy-theme-set-keyboard | `kept` | |
|
||||
| `nomarchy-theme-set-keyboard-f16` | `themes/engine/scripts` | features/scripts/utils/nomarchy-on-boot,themes/engine/scripts/nomarchy-theme-set-keyboard | `kept` | |
|
||||
| `nomarchy-theme-set-obsidian` | `themes/engine/scripts` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-theme-set-templates` | `themes/engine/scripts` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-themes-prebuild` | `themes/engine/scripts` | installer/install.sh | `kept` | |
|
||||
| `nomarchy-theme-update` | `themes/engine/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-hybrid-gpu` | `core/system/scripts` | features/scripts/utils/nomarchy-menu,features/scripts/utils/nomarchy-sys-update, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-idle` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +2 more | `kept` | |
|
||||
| `nomarchy-toggle-nightlight` | `themes/engine/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-notification-silencing` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-screensaver` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-suspend` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-waybar` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-tui-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-tui-remove-all | `kept` | |
|
||||
| `nomarchy-tui-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-tui-remove-all` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-tz-select` | `core/system/scripts` | features/desktop/waybar/config/config.jsonc,features/scripts/utils/nomarchy-menu, +2 more | `kept` | |
|
||||
| `nomarchy-update` | `core/system/scripts` | core/home/config/nomarchy/default/mako/core.ini,core/home/config/nomarchy-skill/SKILL.md, +4 more | `kept` | |
|
||||
| `nomarchy-update-available` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-update-firmware` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-update-time` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-upload-log` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-debug | `kept` | |
|
||||
| `nomarchy-version` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-debug | `kept` | |
|
||||
| `nomarchy-voxtype-config` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-voxtype-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-voxtype-model` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-voxtype-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-voxtype-status` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-wallpaper` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/autostart.conf, +2 more | `kept` | |
|
||||
| `nomarchy-webapp-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-webapp-remove-all | `kept` | |
|
||||
| `nomarchy-webapp-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-webapp-remove-all` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-welcome` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf | `kept` | |
|
||||
| `nomarchy-wifi-powersave` | `core/system/scripts` | features/scripts/utils/nomarchy-sys-update,installer/install.sh | `kept` | |
|
||||
| `nomarchy-windows-vm` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
|
||||
## Missing references
|
||||
|
||||
Tokens grepped from `core/`, `features/`, `themes/`, `installer/`, `hosts/`, `bin/`, `lib/` that have no matching script file.
|
||||
|
||||
| Token | Referenced in | Status |
|
||||
| --- | --- | --- |
|
||||
|
||||
## Menu items
|
||||
|
||||
Walked from `features/scripts/utils/nomarchy-menu`. Each `case` arm in a `show_*_menu` function becomes one row.
|
||||
|
||||
| Submenu | Entry | Calls | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| `show_learn_menu` | Keybindings | `nomarchy-menu-keybindings` | `kept` |
|
||||
| `show_learn_menu` | Nomarchy | `nomarchy-launch-webapp` | `kept` |
|
||||
| `show_learn_menu` | Hyprland | `nomarchy-launch-webapp` | `kept` |
|
||||
| `show_learn_menu` | Arch | `nomarchy-launch-webapp` | `kept` |
|
||||
| `show_learn_menu` | Bash | `nomarchy-launch-webapp` | `kept` |
|
||||
| `show_learn_menu` | Neovim | `nomarchy-launch-webapp` | `kept` |
|
||||
| `show_trigger_menu` | Capture | `_(inline)_` | `kept` |
|
||||
| `show_trigger_menu` | Share | `_(inline)_` | `kept` |
|
||||
| `show_trigger_menu` | Toggle | `_(inline)_` | `kept` |
|
||||
| `show_trigger_menu` | Hardware | `_(inline)_` | `kept` |
|
||||
| `show_capture_menu` | Screenshot | `nomarchy-cmd-screenshot` | `kept` |
|
||||
| `show_capture_menu` | Screenrecord | `_(inline)_` | `kept` |
|
||||
| `show_capture_menu` | Color | `_(inline)_` | `kept` |
|
||||
| `show_share_menu` | Clipboard | `nomarchy-cmd-share` | `kept` |
|
||||
| `show_share_menu` | File | `nomarchy-cmd-share` | `kept` |
|
||||
| `show_share_menu` | Folder | `nomarchy-cmd-share` | `kept` |
|
||||
| `show_toggle_menu` | Screensaver | `nomarchy-toggle-screensaver` | `kept` |
|
||||
| `show_toggle_menu` | Nightlight | `nomarchy-toggle-nightlight` | `kept` |
|
||||
| `show_toggle_menu` | Idle | `nomarchy-toggle-idle` | `kept` |
|
||||
| `show_toggle_menu` | Bar | `nomarchy-toggle-waybar` | `kept` |
|
||||
| `show_toggle_menu` | Layout | `nomarchy-hyprland-workspace-layout-toggle` | `kept` |
|
||||
| `show_toggle_menu` | Ratio | `nomarchy-hyprland-window-single-square-aspect-toggle` | `kept` |
|
||||
| `show_toggle_menu` | Gaps | `nomarchy-hyprland-window-gaps-toggle` | `kept` |
|
||||
| `show_toggle_menu` | Scaling | `nomarchy-hyprland-monitor-scaling-cycle` | `kept` |
|
||||
| `show_style_menu` | Theme | `_(inline)_` | `kept` |
|
||||
| `show_style_menu` | Font | `_(inline)_` | `kept` |
|
||||
| `show_style_menu` | Background | `_(inline)_` | `kept` |
|
||||
| `show_style_menu` | Hyprland | `_(inline)_` | `kept` |
|
||||
| `show_style_menu` | Screensaver | `_(inline)_` | `kept` |
|
||||
| `show_style_menu` | About | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | Audio | `nomarchy-launch-audio` | `kept` |
|
||||
| `show_setup_menu` | Wifi | `nomarchy-launch-wifi` | `kept` |
|
||||
| `show_setup_menu` | Bluetooth | `nomarchy-launch-bluetooth` | `kept` |
|
||||
| `show_setup_menu` | Power | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | System | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | Monitors | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | Keybindings | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | Input | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | DNS | `nomarchy-setup-dns` | `kept` |
|
||||
| `show_setup_menu` | Security | `_(inline)_` | `kept` |
|
||||
| `show_setup_menu` | Config | `_(inline)_` | `kept` |
|
||||
| `show_setup_security_menu` | Fingerprint | `nomarchy-setup-fingerprint` | `kept` |
|
||||
| `show_setup_security_menu` | Fido2 | `nomarchy-setup-fido2` | `kept` |
|
||||
| `show_setup_config_menu` | Defaults | `_(inline)_` | `kept` |
|
||||
| `show_setup_config_menu` | Hyprland | `_(inline)_` | `kept` |
|
||||
| `show_setup_config_menu` | Hypridle | `nomarchy-restart-hypridle` | `kept` |
|
||||
| `show_setup_config_menu` | Hyprlock | `_(inline)_` | `kept` |
|
||||
| `show_setup_config_menu` | Hyprsunset | `nomarchy-restart-hyprsunset` | `kept` |
|
||||
| `show_setup_config_menu` | Swayosd | `nomarchy-restart-swayosd` | `kept` |
|
||||
| `show_setup_config_menu` | Walker | `nomarchy-restart-walker` | `kept` |
|
||||
| `show_setup_config_menu` | Waybar | `nomarchy-restart-waybar` | `kept` |
|
||||
| `show_setup_config_menu` | XCompose | `nomarchy-restart-xcompose` | `kept` |
|
||||
| `show_setup_config_menu` | Overrides | `_(inline)_` | `kept` |
|
||||
| `show_update_menu` | Nomarchy | `nomarchy-update` | `kept` |
|
||||
| `show_update_menu` | Themes | `nomarchy-theme-update` | `kept` |
|
||||
| `show_update_menu` | Process | `_(inline)_` | `kept` |
|
||||
| `show_update_menu` | Hardware | `_(inline)_` | `kept` |
|
||||
| `show_update_menu` | Firmware | `nomarchy-update-firmware` | `kept` |
|
||||
| `show_update_menu` | Timezone | `nomarchy-tz-select` | `kept` |
|
||||
| `show_update_menu` | Time | `nomarchy-update-time` | `kept` |
|
||||
| `show_update_menu` | Password | `_(inline)_` | `kept` |
|
||||
| `show_update_process_menu` | Hypridle | `nomarchy-restart-hypridle` | `kept` |
|
||||
| `show_update_process_menu` | Hyprsunset | `nomarchy-restart-hyprsunset` | `kept` |
|
||||
| `show_update_process_menu` | Swayosd | `nomarchy-restart-swayosd` | `kept` |
|
||||
| `show_update_process_menu` | Walker | `nomarchy-restart-walker` | `kept` |
|
||||
| `show_update_process_menu` | Waybar | `nomarchy-restart-waybar` | `kept` |
|
||||
| `show_update_hardware_menu` | Audio | `nomarchy-restart-pipewire` | `kept` |
|
||||
| `show_update_hardware_menu` | Wi-Fi | `nomarchy-restart-wifi` | `kept` |
|
||||
| `show_update_hardware_menu` | Bluetooth | `nomarchy-restart-bluetooth` | `kept` |
|
||||
| `show_update_password_menu` | Drive | `nomarchy-drive-set-password` | `kept` |
|
||||
| `show_update_password_menu` | User | `_(inline)_` | `kept` |
|
||||
| `show_system_menu` | Screensaver | `nomarchy-launch-screensaver` | `kept` |
|
||||
| `show_system_menu` | Lock | `nomarchy-lock-screen` | `kept` |
|
||||
| `show_system_menu` | Suspend | `nomarchy-toggle-suspend` | `kept` |
|
||||
| `show_system_menu` | Hibernate | `_(inline)_` | `kept` |
|
||||
| `show_system_menu` | Logout | `nomarchy-system-logout` | `kept` |
|
||||
| `show_system_menu` | Restart | `nomarchy-system-reboot` | `kept` |
|
||||
| `show_system_menu` | Shutdown | `nomarchy-system-shutdown` | `kept` |
|
||||
|
||||
@@ -31,12 +31,21 @@ While the system is defined declaratively, Nomarchy uses a small, local state fi
|
||||
- **Outputs:**
|
||||
- `nixosModules.system`: Exports the foundational OS logic (`./core`).
|
||||
- `nixosModules.home`: Exports the application and desktop logic (`./features`).
|
||||
- `nixosConfigurations`: Defines pre-configured targets like `installerIso`, `live-iso`, and a testing `vm`.
|
||||
- `nixosConfigurations`: Defines pre-configured targets like `nomarchy-installer`, `nomarchy-live`, and a testing `vm`.
|
||||
- **`flake.lock`**: Locks dependency versions for reproducible builds.
|
||||
- **`GEMINI.md`**: Foundational mandates and architectural rules for the Nomarchy Agent.
|
||||
- **`STRUCTURE.md`**: (This file) Detailed architectural documentation.
|
||||
- **`README.md`**: Project overview, installation instructions, and basic usage.
|
||||
- **`TODO.md`**: Roadmap and pending tasks.
|
||||
- **`docs/`**: All long-form documentation. Key entry points:
|
||||
- **`AGENT.md`**: Onboarding for AI coding agents picking up Nomarchy.
|
||||
- **`STRUCTURE.md`**: (This file) Detailed architectural documentation.
|
||||
- **`OPTIONS.md`**: Reference for every `nomarchy.*` option.
|
||||
- **`ROADMAP.md`**: Now / Next / Later board and the Shipped log.
|
||||
- **`MIGRATION.md`**: Layering Nomarchy onto an existing NixOS install.
|
||||
- **`KEYBINDINGS.md`**: Auto-generated keybinding reference.
|
||||
- **`SCRIPTS.md`**: Auto-generated `nomarchy-*` script audit.
|
||||
- **`TROUBLESHOOTING.md`**: Common rebuild errors and fixes.
|
||||
- **`creating-themes.md`**: Theme palette authoring guide.
|
||||
- **`.forgejo/workflows/`**: Forgejo Actions CI. Runs `nix flake check --no-build`, lints every `nomarchy-*` bash script with `bash -n` + `shellcheck --severity=error`, and verifies `docs/SCRIPTS.md` is up to date on every push to `main` and every PR. To activate: enable Actions on the repo in Forgejo and register a `forgejo-runner` (any Docker-capable Linux host works; the workflow uses `ubuntu-latest` and installs Nix itself).
|
||||
- **`.githooks/`**: Optional per-clone git hooks (`pre-commit` lints changed scripts and regenerates `docs/SCRIPTS.md`). Enable with `git config core.hooksPath .githooks`. CI enforces the same invariants tree-wide.
|
||||
|
||||
---
|
||||
|
||||
@@ -61,8 +70,8 @@ The `core/` directory contains the foundational modules required for a functiona
|
||||
- **`default.nix`**: The entry point for the base Home Manager module.
|
||||
- **`options.nix`**: Defines the `nomarchy` user options (Toggles, Theme, Fonts, etc.).
|
||||
- **`state.nix`**: Loads and applies user-level state (from `~/.config/nomarchy/state.json`).
|
||||
- **`behavior.nix`**: Deploys non-visual configs (Keybindings, Input settings, Window rules) with `lib.mkDefault`.
|
||||
- **`configs.nix`**: Manages static configuration files and directories in `~/.config/`.
|
||||
- **`overrides.nix`**: Declares `nomarchy.overrides.*` (reserved for a future file-based override loader; currently no-op).
|
||||
- **`configs.nix`**: Manages static configuration files and directories in `~/.config/`. Honors `nomarchy.configOverrides` as a bulk redirect to a replacement config dir.
|
||||
- **`bash.nix`**: Shell environment, aliases, and specialized `env-update` hooks.
|
||||
- **`security.nix`**: Polkit, keyring management, and GPG settings.
|
||||
- **`config/`**: Contains the physical source files for the base user configuration (e.g., `starship.toml`, `hypr/` behavior configs).
|
||||
@@ -93,7 +102,6 @@ The theming system is the "soul" of Nomarchy, providing dynamic, consistent aest
|
||||
### `themes/engine/` (The Logic)
|
||||
- **`loader.nix`**: The core theme loader. It reads the active theme from state and selectively deploys app-specific themed configs (e.g., `btop.theme`, `kitty.conf`) to `~/.config/`.
|
||||
- **`stylix.nix`**: Integration with Stylix for base color palette and wallpaper management.
|
||||
- **`switcher.nix`**: Provides the `nomarchy-theme-selector` and `nomarchy-wallpaper-selector` tools.
|
||||
- **`plymouth.nix`** & **`sddm.nix`**: System-level theming for the boot screen and login manager.
|
||||
|
||||
### `themes/palettes/` (The Data)
|
||||
@@ -125,9 +133,8 @@ The `lib/` directory provides centralized logic and data structures to maintain
|
||||
|
||||
### `installer/` (Bootstrap)
|
||||
- **`install.sh`**: The interactive TTY-based installer. It handles disk partitioning, NixOS installation, and generating a clean "Downstream" flake for the user.
|
||||
- **`disko-golden.nix`**: The standard partition layout (BTRFS on top of LUKS2).
|
||||
- **`disko-btrfs-luks.nix`**: A simpler reference layout for disk management.
|
||||
- **`disko-config.nix`**: The disko partition layout (BTRFS on top of LUKS2). A Nix function of `{ mainDrive, extraDrives ? [] }` — single-disk path is `extraDrives = []`; multi-disk adds BTRFS `-d single -m raid1` across the extras. Invoked by `install.sh` via `disko --argstr mainDrive … --arg extraDrives '[…]'`.
|
||||
|
||||
### `hosts/` (Targets)
|
||||
- **`installer-iso.nix`**: Configuration for the minimal, TTY-based installation ISO.
|
||||
- **`live-iso.nix`**: Configuration for the full graphical live environment, used for testing and GUI-based installation.
|
||||
- **`nomarchy-installer.nix`**: Configuration for the minimal, TTY-based installation ISO.
|
||||
- **`nomarchy-live.nix`**: Configuration for the full graphical live environment, used for testing and GUI-based installation.
|
||||
|
||||
121
docs/TROUBLESHOOTING.md
Normal file
121
docs/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Troubleshooting
|
||||
|
||||
The five rebuild errors a Nomarchy user is most likely to hit, with copy-paste fixes. If your error isn't here, the [Options Reference](OPTIONS.md) and [Migration Guide](MIGRATION.md) cover most other surfaces.
|
||||
|
||||
---
|
||||
|
||||
## 1. `error: The option 'X' is already declared in multiple modules`
|
||||
|
||||
**Looks like:**
|
||||
|
||||
```
|
||||
error: The option `services.foo.enable' is already declared in multiple modules:
|
||||
- /nix/store/…-source/modules/foo.nix
|
||||
- /nix/store/…-source/core/system/foo.nix
|
||||
```
|
||||
|
||||
**Cause:** Two modules — usually one of yours and one of Nomarchy's — both `mkOption` the same path. Nix can't merge two declarations of the *same option*; it can only merge two *values* for one option.
|
||||
|
||||
**Fix:** Find the duplicate. If it's yours and Nomarchy's, delete yours; Nomarchy already declares it. If it's two of yours, delete one. To grep:
|
||||
|
||||
```bash
|
||||
grep -rn "options\..*foo\.enable" /etc/nixos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. `error: attribute 'X' missing`
|
||||
|
||||
**Looks like:**
|
||||
|
||||
```
|
||||
error: attribute 'nomarchy' missing
|
||||
at /etc/nixos/system.nix:7:5:
|
||||
7| nomarchy.system.formFactor = "laptop";
|
||||
```
|
||||
|
||||
**Cause:** You're setting `nomarchy.*` options but didn't import the Nomarchy modules. The flake's `nixosModules.system` declares the option namespace; without the import, the option doesn't exist.
|
||||
|
||||
**Fix:** In your `/etc/nixos/flake.nix`, make sure both modules are in the system's `modules = [ … ]` list:
|
||||
|
||||
```nix
|
||||
modules = [
|
||||
nomarchy.nixosModules.system
|
||||
./system.nix
|
||||
./hardware-selection.nix
|
||||
];
|
||||
```
|
||||
|
||||
The home side is the same shape — `nomarchy.nixosModules.home` plus your `./home.nix`. See [MIGRATION.md](MIGRATION.md) for the full skeleton.
|
||||
|
||||
---
|
||||
|
||||
## 3. Stylix target conflict
|
||||
|
||||
**Looks like:**
|
||||
|
||||
```
|
||||
error: The option `stylix.targets.gtk.enable' has conflicting definition values:
|
||||
- In `/nix/store/…/stylix.nix': true
|
||||
- In `/etc/nixos/home.nix': false
|
||||
Use `lib.mkForce' or `lib.mkDefault' to resolve.
|
||||
```
|
||||
|
||||
**Cause:** Stylix's per-target options are `bool`, not `enum`, so two equally-priority `true`/`false` values from two modules collide. Nomarchy's theming engine sets most targets to `true` via `mkDefault`, so the conflict almost always means *you* set one without `mkDefault`.
|
||||
|
||||
**Fix:** Wrap your override in `lib.mkForce`:
|
||||
|
||||
```nix
|
||||
stylix.targets.gtk.enable = lib.mkForce false;
|
||||
```
|
||||
|
||||
If you want the default-on behavior back, just delete your line — Nomarchy's default fires automatically.
|
||||
|
||||
---
|
||||
|
||||
## 4. home-manager `backupFileExtension` churn
|
||||
|
||||
**Looks like:** every rebuild leaves another `~/.config/foo/bar.conf.hm-bak` next to the file home-manager just wrote, until your `~/.config` is half backups.
|
||||
|
||||
**Cause:** home-manager refuses to overwrite files it didn't itself write; it backs them up first. Nomarchy's flake sets `backupFileExtension = "hm-bak"` (see `flake.nix:161,210`) so the first rebuild after a fresh ISO install doesn't fail — but every subsequent rebuild then re-backs-up the same files because the previous backup is still there.
|
||||
|
||||
**Fix:** After the first successful rebuild, delete the backups:
|
||||
|
||||
```bash
|
||||
find ~/.config -name '*.hm-bak' -print -delete
|
||||
```
|
||||
|
||||
If churn continues, you have a config under `~/.config/<app>/` that home-manager wants to manage but you've also touched by hand. Either let home-manager own it (don't edit by hand; use `nomarchy.*` options or `~/.config/nomarchy/overrides/`) or delete the home-manager declaration if you want the file to remain user-mutable.
|
||||
|
||||
---
|
||||
|
||||
## 5. impermanence path missing after a wipe
|
||||
|
||||
**Looks like:** after enabling `nomarchy.system.impermanence.enable = true;` and rebooting, an app forgets state — Bluetooth pairings vanish, NetworkManager forgets Wi-Fi, GPG keys are gone — or the rebuild itself errors with:
|
||||
|
||||
```
|
||||
error: The path '/persist' does not exist
|
||||
```
|
||||
|
||||
**Cause:** Impermanence requires (a) a `/persist` mountpoint that survives the boot wipe, and (b) every directory you want to keep must be in the persistence list. Nomarchy persists the basics in `core/system/impermanence.nix:46-72` (NetworkManager, Bluetooth, fprint, SSH host keys, the user's `.ssh` / `.gnupg` / Documents / Downloads / Pictures / Videos / Projects). Anything else you care about — Steam library, Flatpak data, custom dotfiles — must be added.
|
||||
|
||||
**Fix:** Make sure `/persist` is mounted (check `mount | grep persist`). Then add the missing path in your `system.nix`:
|
||||
|
||||
```nix
|
||||
environment.persistence."/persist".users.nomarchy.directories = [
|
||||
".local/share/Steam"
|
||||
".var/app" # flatpak data
|
||||
".local/share/keyrings" # already in Nomarchy defaults — example only
|
||||
];
|
||||
```
|
||||
|
||||
Per-app data lives in `~/.local/share/<app>` or `~/.var/app/<id>` (flatpak); check the app's docs. After adding, rebuild and reboot — the path is created on the next mount of `/persist`.
|
||||
|
||||
---
|
||||
|
||||
## Where to look next
|
||||
|
||||
- **Option reference:** [docs/OPTIONS.md](OPTIONS.md) — every `nomarchy.*` setting.
|
||||
- **Existing-NixOS install:** [docs/MIGRATION.md](MIGRATION.md) — how to layer Nomarchy onto a working NixOS without reformatting.
|
||||
- **Repo layout:** [docs/STRUCTURE.md](STRUCTURE.md) — where each module lives.
|
||||
- **Roadmap:** [docs/ROADMAP.md](ROADMAP.md) — what's planned and what's shipped.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user