Add opt-in nomarchy.updates (modules/home/updates.nix): a nomarchy-updates checker on a systemd user timer (interval, default daily) that surfaces a Waybar indicator + a notification when updates are available, without ever changing anything (you still run sys-update / flatpak update). It counts: - flake inputs behind upstream — only the flake's DIRECT inputs (root.inputs: nixpkgs, the Nomarchy input, home-manager, stylix…), not the transitive closure, via `git ls-remote` vs the locked rev. Offline → skipped, never a false alarm. - Flatpak updates, when the flatpak CLI is present (.flatpak, gated on services.flatpak being on) — Bernardo's suggestion. Waybar custom/updates self-gates (hidden until the timer finds something; accent " N", signal 9 for instant refresh), in the generated bar and both summer whole-swaps. The notification fires only when the count grows, so a daily timer doesn't nag. Click → the upgrade flow in a terminal (sys-update / flatpak update, each confirmed). nomarchy-updates ships always on PATH and self-gates so the static whole-swap bars can exec it even when the feature is off. Verified: flake check clean; home generation builds; the jq direct-input filter + status self-gate exercised against the real flake.lock; script passes bash -n. Pending an on-machine check (ls-remote/notify/timer need a live session). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
372 lines
24 KiB
Markdown
372 lines
24 KiB
Markdown
# Nomarchy
|
||
|
||
**The rock-solid reproducibility of NixOS 26.05. The out-of-the-box polish of
|
||
Omarchy/Omakub.** One JSON file rules the look of the entire desktop; every
|
||
theme change is a Home Manager generation — atomic, rollbackable, never
|
||
partial.
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────────────┐
|
||
│ theme-state.json (single source of truth) │
|
||
│ lives INSIDE your flake checkout, git-tracked │
|
||
└───────────────────────────────────┬──────────────────────────────────────┘
|
||
│
|
||
nomarchy-theme-sync apply gruvbox
|
||
1. merges the preset into the JSON (atomic write)
|
||
2. runs `home-manager switch` (no sudo, no system rebuild)
|
||
│
|
||
▼ pure read (nomarchy.stateFile)
|
||
┌──────────────────────────────────────────────────────────────────────────┐
|
||
│ Home Manager bakes EVERYTHING into one read-only generation: │
|
||
│ Hyprland (colors/gaps/borders) Waybar (palette or whole-swap) │
|
||
│ Ghostty (full ANSI palette) btop (asset or generated) │
|
||
│ Stylix → GTK, Qt, cursors, fonts │
|
||
└───────────────────────────────────┬──────────────────────────────────────┘
|
||
▼
|
||
wallpaper via awww (the one runtime piece:
|
||
applied post-switch + at session start, `bg next` cycles)
|
||
```
|
||
|
||
## 1. Layout
|
||
|
||
Flat on purpose. Two module trees, one options file each, no hidden layers.
|
||
|
||
```
|
||
.
|
||
├── flake.nix # inputs + the downstream API (exports below)
|
||
├── lib.nix # nomarchy.lib.mkFlake — one-call downstream wrapper
|
||
├── theme-state.json # ★ THE single source of truth (git-tracked!)
|
||
├── themes/ # 21 presets: <slug>.json + optional <slug>/ assets
|
||
│ ├── nord.json # palette (required, works alone)
|
||
│ └── nord/ # assets (optional, fixed filenames)
|
||
│ ├── backgrounds/ # wallpapers (auto-picked, SUPER+SHIFT+T cycles)
|
||
│ ├── btop.theme # hand-made config drop (else generated)
|
||
│ └── waybar.css # whole-swap: replaces the generated bar style
|
||
├── modules/
|
||
│ ├── nixos/ # the distro, system side
|
||
│ │ ├── default.nix # Hyprland session, Pipewire, greetd, fonts
|
||
│ │ ├── options.nix # nomarchy.system.* toggles
|
||
│ │ ├── plymouth.nix # boot splash, tinted from the JSON
|
||
│ │ ├── file-manager.nix # Thunar GUI + gvfs/tumbler/udisks2
|
||
│ │ └── power.nix # power-profiles-daemon/TLP, thermald, charge limit
|
||
│ └── home/ # the distro, user side
|
||
│ ├── default.nix # entry point
|
||
│ ├── options.nix # nomarchy.* option surface
|
||
│ ├── theme.nix # JSON ingestion + wallpaper hook
|
||
│ ├── stylix.nix # GTK/Qt/cursors/fonts from the same JSON
|
||
│ ├── hyprland.nix # all JSON-driven
|
||
│ ├── waybar.nix
|
||
│ ├── ghostty.nix
|
||
│ ├── btop.nix
|
||
│ ├── rofi.nix # launcher + nomarchy-menu (calc, emoji, clip…)
|
||
│ ├── keybinds.nix # single source: Hyprland binds + SUPER+? sheet
|
||
│ ├── swaync.nix # notifications, same JSON
|
||
│ ├── idle.nix # hyprlock + hypridle, same JSON
|
||
│ ├── yazi.nix # flagship TUI file manager + plugins
|
||
│ ├── osd.nix # swayosd volume/brightness OSD
|
||
│ ├── shell.nix # zsh + starship + bat/eza/zoxide
|
||
│ ├── keys.nix # gpg-agent fronting SSH, pinentry-qt
|
||
│ └── fastfetch.nix # themed Nomarchy logo + system info
|
||
├── hosts/
|
||
│ ├── default/ # reference machine (thin: boot, user, hostname)
|
||
│ └── live.nix # bootable live ISO (try the distro, no install)
|
||
├── pkgs/
|
||
│ ├── nomarchy-theme-sync/ # state writer + rebuild dispatcher (Python)
|
||
│ └── nomarchy-install/ # live-ISO installer (gum + disko + mkFlake)
|
||
├── templates/downstream/ # `nix flake init -t` starter for users
|
||
├── docs/TESTING.md # how to verify changes (incl. AI-agent rules)
|
||
├── docs/OVERRIDES.md # how downstream users override defaults
|
||
├── docs/ROADMAP.md # forward-looking plans + shipped-fixes log
|
||
└── tools/ # maintainer-only
|
||
├── import-palettes.py # converts old-distro themes → JSON + assets
|
||
├── test-live-iso.sh # build the ISO + boot it in QEMU
|
||
├── test-install.sh # full offline-install regression in QEMU
|
||
└── vm/ # headless-VM helpers (QMP keys, VNC shots,
|
||
# offline-pin gap analysis)
|
||
```
|
||
|
||
**Rule of thumb:** `modules/` is the distro (reusable, no machine specifics),
|
||
`hosts/` is a machine, `themes/` is data, `pkgs/` is code, `tools/` is
|
||
maintainer-only. If a new file doesn't obviously belong to one of those, it
|
||
probably shouldn't exist.
|
||
|
||
## 2. Try it first (live ISO)
|
||
|
||
Boot the full desktop from a USB stick or VM without installing anything:
|
||
|
||
```sh
|
||
nix build .#nixosConfigurations.nomarchy-live.config.system.build.isoImage
|
||
# → result/iso/*.iso — dd to a stick, or boot it in QEMU:
|
||
tools/test-live-iso.sh
|
||
```
|
||
|
||
The live session auto-logs-in, seeds the flake at `~/.nomarchy`, and pins
|
||
the locked inputs into the ISO store — so theme switching (including the
|
||
`home-manager switch` it triggers) works **offline**, exactly like on an
|
||
installed system. Verification checklist: [docs/TESTING.md](docs/TESTING.md).
|
||
|
||
Like what you see? **`nomarchy-install`** (in a terminal) walks you through
|
||
installing to disk: pick a disk, LUKS2 full-disk encryption **by default**
|
||
(in exchange the desktop logs in passwordless — the passphrase already
|
||
gates the machine), user + hostname + timezone, hardware autodetection
|
||
(DMI → nixos-hardware profile), a hibernation-ready swapfile sized to RAM,
|
||
then disko partitions (GPT + ESP + BTRFS subvolumes incl. `@snapshots` —
|
||
snapper timeline snapshots are on) and `nixos-install` runs — **without a
|
||
network** when the ISO was built from a clean tree (the target's
|
||
`flake.lock` is composed from the rev the ISO carries). The installed
|
||
machine gets the standard downstream layout: the flake at `~/.nomarchy`
|
||
(`/etc/nixos` symlinks to it), one `mkFlake` call, your
|
||
`system.nix`/`home.nix`. First boot lands in the fully themed desktop —
|
||
the installer pre-activates the Home Manager generation. UEFI only for now.
|
||
|
||
## 3. Using Nomarchy on your machine (downstream)
|
||
|
||
Nomarchy is consumed as a flake input — you never fork or edit this repo:
|
||
|
||
```sh
|
||
mkdir my-machine && cd my-machine
|
||
nix flake init -t "git+https://git.bemagri.xyz/bernardo/nomarchy.git?ref=v1"
|
||
```
|
||
|
||
You own two files day-to-day: `system.nix` and `home.nix` (plus
|
||
`theme-state.json`, written by the CLI). Your `flake.nix` is set up once —
|
||
later by the installer — and never hand-edited; it's a single call:
|
||
|
||
```nix
|
||
outputs = { nomarchy, ... }:
|
||
nomarchy.lib.mkFlake {
|
||
src = ./.;
|
||
username = "me";
|
||
hardwareProfile = "framework-13-7040-amd"; # optional, nixos-hardware name
|
||
};
|
||
```
|
||
|
||
| `mkFlake` arg | Default | Purpose |
|
||
|---|---|---|
|
||
| `src` | — (required) | Your flake directory (`./.`) |
|
||
| `username` | — (required) | Login name; flows into `system.nix` and names the HM config |
|
||
| `hardwareProfile` | `null` | One [nixos-hardware](https://github.com/NixOS/nixos-hardware) module name, or a list of them (pinned + tested by Nomarchy; unknown names fail with suggestions) |
|
||
| `system` | `"x86_64-linux"` | Platform |
|
||
|
||
(Power users can skip `mkFlake` and wire `nixosModules.nomarchy` /
|
||
`homeModules.nomarchy` / `overlays.default` by hand — the wrapper is sugar.)
|
||
|
||
Two deliberately separate rebuild paths:
|
||
|
||
```sh
|
||
sudo nixos-rebuild switch --flake .#default # system: rare
|
||
home-manager switch --flake .#me # desktop: every theme change, no sudo
|
||
```
|
||
|
||
Day-to-day you'll use the shipped shortcuts instead:
|
||
|
||
```sh
|
||
sys-update # nix flake update + system rebuild (BTRFS snapshot first when available)
|
||
home-update # home-manager switch (no flake update, no sudo)
|
||
```
|
||
|
||
**Order matters when pulling distro updates.** `home-update` does *not*
|
||
touch the lock — it rebuilds the desktop against the **current**
|
||
`flake.lock`. A new Nomarchy revision (new keybinds, theming, modules)
|
||
arrives only when the lock is updated, which `sys-update` does
|
||
(`nix flake update`). So to pull an update that affects the desktop layer:
|
||
run `sys-update` **first** (updates the lock + rebuilds the system), **then**
|
||
`home-update` (re-applies the desktop against the new lock). Doing them in
|
||
the other order rebuilds the desktop against the *old* inputs and silently
|
||
skips the new home-side changes. After a home-side keybind/config change,
|
||
also `hyprctl reload` (or relogin) so the running session re-reads it.
|
||
|
||
Override anything via the `nomarchy.*` surface or plain NixOS/HM options:
|
||
appearance (gaps/colors/fonts) changes through `nomarchy-theme-sync`,
|
||
behaviour (input/misc/monitor/chrome) is `mkDefault` so a plain `home.nix`
|
||
assignment wins, and bind/exec-once lists concatenate. Full guide with
|
||
examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**.
|
||
|
||
| Option | Default | Purpose |
|
||
|---|---|---|
|
||
| `nomarchy.stateFile` | — (required) | Path to your theme-state.json |
|
||
| `nomarchy.terminal` | `"ghostty"` | Terminal for keybinds and `$TERMINAL` |
|
||
| `nomarchy.keyboard.layout` | `"us"` | XKB layout for the Hyprland session (installer writes the matching `services.xserver.xkb` in system.nix; the console + LUKS prompt follow via the distro default) |
|
||
| `nomarchy.keyboard.variant` | `""` | XKB variant for the session |
|
||
| `nomarchy.keyboard.devices` | `{}` | Per-device layout overrides (Hyprland `device` blocks keyed by `hyprctl devices` name) — e.g. an external keyboard with its own layout/variant |
|
||
| `nomarchy.keyboard.layouts` | `[]` | Extra candidate layouts; when set, a watcher prompts (rofi) for a layout on a newly-connected keyboard and remembers it per-device |
|
||
| `nomarchy.nightlight.enable` | `false` | Scheduled blue-light filter (hyprsunset) — warm at night (`.temperature`, default 4000K) between `.sunset`/`.sunrise`, no shift by day; toggle it on/off from the menu (System › Night light) or the Waybar moon/sun indicator |
|
||
| `nomarchy.updates.enable` | `false` | Passive update awareness: a background check (`.interval`, default daily) that flags when flake inputs (nixpkgs, the Nomarchy input, …) are behind upstream — and, with Flatpak on, when apps have updates (`.flatpak`) — via a Waybar indicator + notification. Never changes anything; click the indicator to run the upgrade flow |
|
||
| `nomarchy.hyprland.enable` | `true` | Nomarchy's Hyprland config |
|
||
| `nomarchy.waybar.enable` | `true` | Nomarchy's Waybar |
|
||
| `nomarchy.rofi.enable` | `true` | Themed rofi launcher + `nomarchy-menu` dispatcher |
|
||
| `nomarchy.swaync.enable` | `true` | swaync notifications, themed |
|
||
| `nomarchy.idle.enable` | `true` | hyprlock + hypridle (idle lock 5 min, display off 10, suspend 30) |
|
||
| `nomarchy.yazi.enable` | `true` | yazi TUI file manager, themed + curated plugins |
|
||
| `nomarchy.osd.enable` | `true` | swayosd on-screen display for volume/brightness/mute |
|
||
| `nomarchy.shell.enable` | `true` | zsh + starship prompt + bat/eza/zoxide (zsh is the default login shell) |
|
||
| `nomarchy.ghostty.enable` | `true` | Nomarchy's Ghostty |
|
||
| `nomarchy.btop.enable` | `true` | btop with per-theme colors |
|
||
| `nomarchy.stylix.enable` | `true` | GTK/Qt/cursor theming |
|
||
| `nomarchy.fastfetch.enable` | `true` | fastfetch fronted by the themed Nomarchy logo |
|
||
| `nomarchy.keys.enable` | `true` | gpg-agent fronting SSH + pinentry-qt |
|
||
| `nomarchy.displays.enable` | `true` | nwg-displays interactive monitor arranger (helper for `nomarchy.monitors`) |
|
||
| `nomarchy.monitors` | `[]` | Declarative per-output layout → Hyprland `monitor` rules (applied on hotplug); `,preferred,auto,1` wildcard kept as fallback |
|
||
| `nomarchy.themesDir` | Nomarchy's `themes/` | Where per-theme app overrides are probed |
|
||
| `nomarchy.system.plymouth.enable` | `true` | Branded boot splash, background from the theme JSON (recolors on system rebuilds) |
|
||
| `nomarchy.system.fileManager.enable` | `true` | Thunar GUI + gvfs/tumbler/udisks2 (the "open folder" handler) |
|
||
| `nomarchy.system.greeter.enable` | `true` | greetd/tuigreet |
|
||
| `nomarchy.system.greeter.autoLogin` | `null` | Auto-login this user into Hyprland (installer sets it on LUKS machines) |
|
||
| `nomarchy.system.audio.enable` | `true` | Pipewire stack |
|
||
| `nomarchy.system.bluetooth.enable` | `true` | Bluetooth + blueman |
|
||
| `nomarchy.system.snapper.enable` | `false` | Hourly/daily BTRFS timeline snapshots + `nixos-rebuild-snap` (installer enables it; no-op unless root is BTRFS) |
|
||
| `nomarchy.system.power.enable` | `true` | Active power management (see below) |
|
||
| `nomarchy.system.power.backend` | `"ppd"` | `"ppd"` (power-profiles-daemon + menu/Waybar switcher) or `"tlp"` (deeper battery tuning, no switcher) — mutually exclusive |
|
||
| `nomarchy.system.power.laptop` | `false` | Marks a laptop, gating battery-only features; the installer sets it when a battery is present |
|
||
| `nomarchy.system.power.thermal.enable` | `false` | thermald (Intel-only); the installer enables it on a GenuineIntel CPU |
|
||
| `nomarchy.system.power.batteryChargeLimit` | `null` | Stop charging at this % (e.g. `80`) where the hardware supports it; needs `power.laptop` |
|
||
| `nomarchy.hardware.intel.enable` | `false` | Intel enablement above nixos-hardware (GuC/HuC via `i915.enable_guc=3`); the installer sets it on an Intel CPU/GPU |
|
||
| `nomarchy.hardware.intel.computeRuntime` | `false` | Opt-in: Intel GPU compute — OpenCL/Level-Zero (`intel-compute-runtime`) + oneVPL (`vpl-gpu-rt`) |
|
||
| `nomarchy.hardware.amd.enable` | `false` | AMD enablement above nixos-hardware (amd-pstate EPP + radeonsi VA-API); installer-set on an AMD CPU/GPU |
|
||
| `nomarchy.hardware.amd.rocm.enable` | `false` | Opt-in: ROCm HIP/OpenCL GPU compute (multi-GB); pair with `.gfxOverride` (e.g. `"11.0.0"`) for an unlisted iGPU |
|
||
| `nomarchy.hardware.fingerprint.enable` | `false` | fprintd for a detected fingerprint reader (installer-set); enroll with `fprintd-enroll` |
|
||
| `nomarchy.hardware.fingerprint.pam` | `false` | Opt-in: use the fingerprint for login + sudo (PAM) |
|
||
| `nomarchy.hardware.npu.enable` | `false` | Opt-in/experimental: load the on-die NPU driver (`amdxdna`/`intel_vpu`); userspace runtime is BYO |
|
||
| `nomarchy.hardware.latestKernel` | `false` | Opt-in: ship `linuxPackages_latest` instead of the default kernel — for very new hardware whose drivers landed recently |
|
||
| `nomarchy.services.tailscale.enable` | `false` | Opt-in: Tailscale mesh VPN (then `sudo tailscale up`) |
|
||
| `nomarchy.services.syncthing.enable` | `false` | Opt-in: Syncthing file sync as the login user (GUI at `127.0.0.1:8384`) |
|
||
| `nomarchy.services.podman.enable` | `false` | Opt-in: rootless Podman (`docker` aliased to it) |
|
||
| `nomarchy.services.flatpak.enable` | `false` | Opt-in: Flatpak + the Flathub remote |
|
||
| `nomarchy.services.pika.enable` | `false` | Opt-in: Pika Backup (GUI Borg backups) |
|
||
| `nomarchy.services.steam.enable` | `false` | Opt-in: Steam via `programs.steam` (32-bit libs, controller udev, Remote-Play ports) |
|
||
| `nomarchy.services.libvirt.enable` | `false` | Opt-in: libvirt/KVM + virt-manager GUI (login user added to `libvirtd`) |
|
||
| `nomarchy.services.obs.enable` | `false` | Opt-in: OBS Studio + a v4l2loopback virtual camera (selectable as a webcam in Zoom/Teams) |
|
||
| `nomarchy.services.docker.enable` | `false` | Opt-in: rootful Docker (user in `docker` group); don't enable alongside podman |
|
||
| `nomarchy.services.kdeconnect.enable` | `false` | Opt-in: KDE Connect phone integration (opens its firewall ports) |
|
||
| `nomarchy.services.gamemode.enable` | `false` | Opt-in: Feral GameMode performance daemon (`gamemoderun`) |
|
||
| `nomarchy.services.adb.enable` | `false` | Opt-in: Android adb/fastboot tools (systemd handles device udev rules) |
|
||
| `nomarchy.services.wireshark.enable` | `false` | Opt-in: Wireshark Qt GUI (user in `wireshark` group, capture without root) |
|
||
| `nomarchy.services.ollama.enable` | `false` | Opt-in: Ollama local LLM runtime on `127.0.0.1:11434` (CPU; GPU via `services.ollama.acceleration`) |
|
||
| `nomarchy.services.printing.enable` | `false` | Opt-in: CUPS + Avahi/mDNS network printer discovery |
|
||
| `nomarchy.services.openrgb.enable` | `false` | Opt-in: OpenRGB daemon for RGB peripheral/motherboard lighting |
|
||
| `nomarchy.services.restic.enable` | `false` | Opt-in: scheduled daily restic backup (set `.repository` + `.passwordFile`; 7/4/6 retention; list/restore via the `restic-nomarchy` wrapper) |
|
||
|
||
Beyond the `nomarchy.*` surface, the system layer turns on the usual
|
||
desktop services with `lib.mkDefault` (override natively). One worth
|
||
calling out: **`services.fwupd.enable`** is on by default for firmware
|
||
updates via LVFS — it only refreshes metadata, never flashes on its own,
|
||
so run `fwupdmgr update` to apply. Disable with `services.fwupd.enable =
|
||
false;` on machines without real firmware (VMs/headless).
|
||
|
||
## 4. How theming works
|
||
|
||
### Pure JSON ingestion
|
||
|
||
The trap with "read a mutable file from Nix" is pure evaluation: flakes
|
||
cannot read arbitrary `$HOME` paths without `--impure` (the old prototype
|
||
required it — never again). Nomarchy's convention: **the state file lives
|
||
inside the consuming flake** and is wired via
|
||
`nomarchy.stateFile = ./theme-state.json;`. Reading it is pure — it's flake
|
||
source. It must be git-tracked (`nomarchy-theme-sync` runs
|
||
`git add --intent-to-add` after every write as a safety net).
|
||
|
||
### One change = one generation
|
||
|
||
`nomarchy-theme-sync apply <theme>` merges the preset into the JSON and runs
|
||
`home-manager switch` (override the command with `$NOMARCHY_REBUILD`, or pass
|
||
`--no-switch` to only write). Everything is baked: Hyprland, Waybar, Ghostty,
|
||
btop, and — via Stylix, mapped onto base16 roles — GTK, Qt, cursors and
|
||
fonts. No runtime patching means no partial states, and `home-manager
|
||
generations` is also your theme history. Waybar even restyles in place: it
|
||
re-reads `style.css` when the symlink flips.
|
||
|
||
The **wallpaper** is the one runtime piece (awww — nixpkgs' swww — is
|
||
imperative; nothing in Nix consumes the path): applied at session start and
|
||
after every switch via a tiny activation hook, cycled instantly with
|
||
`bg next`.
|
||
|
||
### Per-theme app assets (`themes/<slug>/`)
|
||
|
||
Recoloring covers 95% of theming; the rest is one optional assets directory
|
||
per theme — a single place to look, unlike the old distro's split:
|
||
|
||
| Asset | Mechanism |
|
||
|---|---|
|
||
| `backgrounds/` | wallpapers; empty `wallpaper` in the state means "first one"; `bg next` cycles |
|
||
| `btop.theme` | baked into the generation (generated from the palette when absent) |
|
||
| `waybar.css` | **whole-swap**: replaces the generated bar style entirely (probed at eval time, self-contained) |
|
||
| `waybar.jsonc` | whole-swap for the bar *layout* (must be plain JSON) |
|
||
| `rofi.rasi` | **whole-swap**: replaces the generated launcher/menu theme entirely |
|
||
|
||
Six ported themes ship a `waybar.css` identity (catppuccin, lumon, nord,
|
||
retro-82, summer-day, summer-night). Custom user themes can live in
|
||
`$NOMARCHY_PATH/themes/` (preset lookup) and `nomarchy.themesDir` (eval-time
|
||
asset probe).
|
||
|
||
## 5. Day-to-day
|
||
|
||
```sh
|
||
nomarchy-theme-sync list # 21 presets (nord, gruvbox, rose-pine, …)
|
||
nomarchy-theme-sync apply kanagawa # whole desktop, one generation (~a switch)
|
||
nomarchy-theme-sync set ui.gapsOut 16 # tweak one knob (also a switch)
|
||
nomarchy-theme-sync bg next # cycle wallpapers — instant, no rebuild
|
||
nomarchy-theme-sync bg auto # back to the theme's default wallpaper
|
||
nomarchy-theme-sync get colors.accent
|
||
sys-update # update inputs + rebuild the system (snapshots first)
|
||
home-update # rebuild just the desktop layer
|
||
```
|
||
|
||
Keybinds: `SUPER+Return` terminal · `SUPER+D` launcher · `SUPER+T` theme
|
||
picker · `SUPER+SHIFT+T` next wallpaper · `SUPER+X` power menu ·
|
||
`SUPER+E` file manager (yazi) · `SUPER+N` notifications · `SUPER+CTRL+V`
|
||
clipboard history · `SUPER+Q`
|
||
close · `SUPER+1..9` workspaces · `Print` region screenshot.
|
||
|
||
Shell aliases (zsh, gated on `nomarchy.shell.enable`) — `alias` lists them
|
||
all; the curated set:
|
||
|
||
```sh
|
||
# navigation
|
||
.. ... .... # cd up 1 / 2 / 3 levels
|
||
|
||
# git
|
||
g gst # git · git status -sb
|
||
ga gaa # git add · git add -A
|
||
gc gcm # git commit · git commit -m
|
||
gco gsw gb # checkout · switch · branch
|
||
gd gds # diff · diff --staged
|
||
gl glg # log graph (last 20 · all branches)
|
||
gp gpl gf # push · pull · fetch --all --prune
|
||
|
||
# nix (system/home rebuilds keep their full sys-update / home-update names)
|
||
ns nr # nix shell · nix run (e.g. ns nixpkgs#ripgrep)
|
||
nfu nfc # nix flake update · check
|
||
nsearch ngc # nix search nixpkgs · nix-collect-garbage -d
|
||
|
||
# misc
|
||
path # print $PATH, one entry per line
|
||
reload # exec zsh (reload the shell)
|
||
```
|
||
|
||
## 6. Extending
|
||
|
||
- **New theme:** drop a JSON into `themes/` (schema = any existing preset),
|
||
plus an optional `themes/<slug>/` assets directory.
|
||
- **New themed value:** add the key to `theme-state.json` and consume it in
|
||
the Nix modules. One place — there is no second renderer to keep in sync.
|
||
- **Importing more old-distro palettes:**
|
||
`tools/import-palettes.py <palettes-dir> themes/`.
|
||
- **New opt-in feature (convention):** when a feature is off by default and
|
||
needs the user to set `nomarchy.*` options (e.g. night light, per-device
|
||
keyboard layouts, monitor layout, power management), ship a **commented**
|
||
example of it in `templates/downstream/home.nix` or `system.nix`. New
|
||
installs then enable it by uncommenting + tweaking, rather than hunting the
|
||
docs for the option name.
|
||
- **Applications:** the starter complete-workstation set (LibreOffice, VS
|
||
Code, GIMP, Inkscape) lives in the `home.packages` list in your
|
||
`home.nix` — it's a plain package list, so curate it directly: delete a
|
||
line to slim the machine, uncomment an extra (a browser, email, full TeX
|
||
Live), or add your own. No `nomarchy.apps.*` toggles — a package list is
|
||
already its own opt-out, so the distro doesn't impose these or wrap them.
|
||
|
||
## Roadmap & known issues
|
||
|
||
See **[docs/ROADMAP.md](docs/ROADMAP.md)** — forward-looking plans plus the
|
||
log of shipped fixes. Kept out of the README so this stays a focused entry
|
||
point.
|