From 38429a32df3b4023dd5bf0af2b2a5f8a0b856e18 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Fri, 22 May 2026 18:49:19 +0100 Subject: [PATCH] feat(overrides): wire nomarchy.overrides.paths into xdg.configFile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The option surface (`enable`, `paths`) lived in core/home/overrides.nix since 2026-05-18 but didn't do anything — paths was a reserved attrset that never reached xdg.configFile. Now wired: every entry in nomarchy.overrides.paths substitutes the matching xdg.configFile..source at lib.mkForce priority, beating Nomarchy's own lib.mkDefault writes. Other fields on the original entry (recursive, etc.) survive via the standard module-system merge. nomarchy.overrides.paths = { "nomarchy/default/hypr/looknfeel.conf" = ./looknfeel.conf; "waybar/style.css" = ./waybar.css; }; Picked the attrset model from the row's two options rather than runtime ~/.config/nomarchy/overrides/ directory discovery — Nix needs every managed file declared at evaluation time, and the attrset matches the explicit-config shape used everywhere else in the Nomarchy surface. docs/OPTIONS.md updated: both overrides.{enable,paths} entries get real content + an example, the configOverrides row now contrasts bulk-vs-per-file accurately, and the "Where these are defined" footer drops the (reserved) tag. `nix flake check --no-build` clean. --- core/home/overrides.nix | 52 ++++++++++++++++++++++++++++++++--------- docs/OPTIONS.md | 19 +++++++++++---- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/core/home/overrides.nix b/core/home/overrides.nix index 48c11de..b4fdd3c 100644 --- a/core/home/overrides.nix +++ b/core/home/overrides.nix @@ -2,33 +2,63 @@ # File-based override system for Nomarchy. # -# 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. +# When `nomarchy.overrides.enable = true` (default), every entry in +# `nomarchy.overrides.paths` substitutes the `xdg.configFile..source` +# Nomarchy ships by default. The substitution is done with `lib.mkForce` +# so it wins over Nomarchy's own `lib.mkDefault` writes. Other fields on +# the original entry (e.g. `recursive`) survive the merge. # -# When implemented, this module should substitute sources in -# `xdg.configFile..source` based on the presence of matching files -# under ~/.config/nomarchy/overrides/. +# Usage in a downstream home.nix: +# +# nomarchy.overrides.paths = { +# "nomarchy/default/hypr/looknfeel.conf" = ./mine/looknfeel.conf; +# "waybar/style.css" = ./mine/waybar.css; +# }; +# +# The keys are xdg.configFile paths (i.e. relative to ~/.config/). Drop- +# in-a-dir discovery is intentionally not supported — Nix needs every +# managed file declared at evaluation time, and the attrset is the +# explicit-config shape the rest of the Nomarchy module surface uses. +let + cfg = config.nomarchy.overrides; +in { options.nomarchy.overrides = { enable = lib.mkOption { type = lib.types.bool; default = true; description = '' - Reserved for the future file-based override loader. Currently a - no-op — setting this has no effect. See docs/ROADMAP.md. + Whether file-based overrides in nomarchy.overrides.paths are + applied. Defaults to true so an empty `paths` is a no-op and + a populated one Just Works without a second toggle. ''; }; paths = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = {}; + example = lib.literalExpression '' + { + "nomarchy/default/hypr/looknfeel.conf" = ./looknfeel.conf; + "waybar/style.css" = ./waybar.css; + } + ''; description = '' - Reserved for the future file-based override loader. Currently - unused. + Attribute set mapping xdg.configFile paths (relative to + ~/.config/) to Nix paths whose contents should replace the + Nomarchy-shipped source. Each entry deploys at lib.mkForce + priority so it overrides Nomarchy's lib.mkDefault writes; + recursive flags and other fields on the original entry are + preserved. Pointing at a path Nomarchy doesn't manage just + creates a new xdg.configFile entry. ''; }; }; + + config = lib.mkIf cfg.enable { + xdg.configFile = lib.mapAttrs (_path: src: { + source = lib.mkForce src; + }) cfg.paths; + }; } diff --git a/docs/OPTIONS.md b/docs/OPTIONS.md index 01023f6..e50fa7e 100644 --- a/docs/OPTIONS.md +++ b/docs/OPTIONS.md @@ -247,7 +247,7 @@ Without prime config, supergfxd still switches modes but render-offload via `nvi ### `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 `/` 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). +`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 `/` instead of the bundled defaults. Distinct from `nomarchy.overrides.*` below — `configOverrides` is a working *bulk* redirect; `overrides.paths` is a *per-file* attrset map. ### `nomarchy.apps.opencode.enable` @@ -275,11 +275,22 @@ Without prime config, supergfxd still switches modes but render-offload via `nvi ### `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..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`. +`bool`, default `true`. Whether the entries in `nomarchy.overrides.paths` are applied. Default `true` so an empty `paths` is a no-op and a populated one Just Works without a second toggle. ### `nomarchy.overrides.paths` -`attrsOf path`, default `{}`. **Reserved — currently unused.** Will be populated by the future override loader. +`attrsOf path`, default `{}`. Per-file overrides. Each key is an `xdg.configFile` path (relative to `~/.config/`); each value is a Nix path whose contents replace the Nomarchy-shipped source. Substitution is done with `lib.mkForce` so it wins over Nomarchy's own `lib.mkDefault` writes. Other fields on the original entry (`recursive` etc.) survive the merge. Overriding a path Nomarchy doesn't manage just creates a new `xdg.configFile` entry. + +Example: + +```nix +nomarchy.overrides.paths = { + "nomarchy/default/hypr/looknfeel.conf" = ./looknfeel.conf; + "waybar/style.css" = ./waybar.css; +}; +``` + +Drop-in-a-dir discovery (a runtime walk of `~/.config/nomarchy/overrides/`) is intentionally not supported — Nix needs every managed file declared at evaluation time, and the attrset is the explicit-config shape the rest of the Nomarchy module surface uses. --- @@ -331,6 +342,6 @@ The same pattern works for any file Nomarchy deploys via `xdg.configFile.. - `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) +- `core/home/overrides.nix` — `nomarchy.overrides.*` - `themes/engine/loader.nix` — `nomarchy.themeLoader.*` - `features/apps/vscode.nix` — `nomarchy.vscode.*`