From a70a7e5ed46e6671a64c94698f70ceb210eff7cd Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Thu, 24 Sep 2026 13:34:58 +0000 Subject: Provision the JetBrains Mono Nerd Font via the shared home profile Ghostty and Neovim both render glyphs (statusline icons, file-tree icons) that need a Nerd Font, and no font was previously provisioned at all. Co-Authored-By: Claude Sonnet 5 --- modules/home/default.nix | 1 + modules/home/fonts.nix | 14 +++++++++ .../.openspec.yaml | 2 ++ .../design.md | 36 ++++++++++++++++++++++ .../proposal.md | 23 ++++++++++++++ .../specs/fonts/spec.md | 26 ++++++++++++++++ .../tasks.md | 10 ++++++ openspec/specs/fonts/spec.md | 28 +++++++++++++++++ 8 files changed, 140 insertions(+) create mode 100644 modules/home/fonts.nix create mode 100644 openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/.openspec.yaml create mode 100644 openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/design.md create mode 100644 openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/proposal.md create mode 100644 openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/specs/fonts/spec.md create mode 100644 openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/tasks.md create mode 100644 openspec/specs/fonts/spec.md diff --git a/modules/home/default.nix b/modules/home/default.nix index 7a093bf..15f70bd 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -7,5 +7,6 @@ ./dotfiles.nix ./dev-tools.nix ./desktop-apps.nix + ./fonts.nix ]; } diff --git a/modules/home/fonts.nix b/modules/home/fonts.nix new file mode 100644 index 0000000..26dc924 --- /dev/null +++ b/modules/home/fonts.nix @@ -0,0 +1,14 @@ +{ pkgs, lib, ... }: +let + candidateFonts = [ pkgs.nerd-fonts.jetbrains-mono ]; +in +{ + home.packages = builtins.filter (lib.meta.availableOn pkgs.stdenv.hostPlatform) candidateFonts; + + # Standalone (non-NixOS) Linux activations don't otherwise get fontconfig + # pointed at fonts installed via home.packages - see design.md. Harmless + # no-op on Darwin (font discovery there goes through + # targets.darwin.fonts, unconditional on this option) and idempotent on + # NixOS (already defaults to true via useUserPackages). + fonts.fontconfig.enable = true; +} diff --git a/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/.openspec.yaml b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/.openspec.yaml new file mode 100644 index 0000000..75289e4 --- /dev/null +++ b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-24 diff --git a/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/design.md b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/design.md new file mode 100644 index 0000000..528a4d7 --- /dev/null +++ b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/design.md @@ -0,0 +1,36 @@ +## Context + +See proposal.md - Why. This is a single-package addition to `modules/home/`, the shared cross-platform profile described in `CLAUDE.md`. That file documents two established patterns this design reuses rather than inventing new ones: +- `lib.meta.availableOn pkgs.stdenv.hostPlatform`, filtered over a candidate list, for package availability differences (used today in `modules/home/desktop-apps.nix`). +- Platform checks (`pkgs.stdenv.hostPlatform.isLinux`/`isDarwin`) for platform-only differences. + +Confirmed against the pinned `nixpkgs` (`nixos-unstable`, see `flake.nix`): `pkgs.nerd-fonts.jetbrains-mono` exists, but its `meta.platforms` excludes `x86_64-darwin` while including `aarch64-darwin`, `x86_64-linux`, and `aarch64-linux` (and effectively everything else). None of this flake's actual `homeConfigurations` (`tom@linux` = `x86_64-linux`, `tom@darwin` = `aarch64-darwin`) or `nixosConfigurations` (`test-vm` = `aarch64-linux`) target `x86_64-darwin` today, so this gap is latent, not currently triggered - but the flake's `devShells`/`formatter` outputs do cover `x86_64-darwin` via `forAllSystems`, and a future `homeConfigurations."tom@darwin-intel"` (or similar) would hit it immediately without a guard. + +Font delivery differs by platform in home-manager itself, independent of anything this repo needs to write: +- On Linux, fontconfig-based apps discover fonts placed under `home.packages` only once `fonts.fontconfig.enable` is on. Home-manager defaults that option to `nixosConfig.fonts.fontconfig.enable` when running as a NixOS submodule with `useUserPackages` (this flake's `mkNixos` wiring) - which is `true` by NixOS's own default - but defaults to `false` for a standalone (non-NixOS) activation, where `nixosConfig` is null. +- On Darwin, home-manager's built-in `targets.darwin.fonts` module (unconditional on `pkgs.stdenv.hostPlatform.isDarwin`, not gated by `fonts.fontconfig.enable`) already rsyncs any font found in `home.packages` into `~/Library/Fonts/HomeManager` on every activation. + +## Goals / Non-Goals + +**Goals:** +- Provision the JetBrains Mono Nerd Font through the shared home-manager profile on every platform the pinned nixpkgs supports it on. +- Make the font discoverable by fontconfig-based apps (Ghostty, Neovim's GUI-adjacent tooling) on Linux, standalone or NixOS-hosted, without relying on the NixOS-submodule-derived default. +- Skip cleanly, not fail evaluation, on a platform without a supported build. + +**Non-Goals:** +- Configuring Ghostty or Neovim to actually *use* the font (`font-family` in Ghostty's config, `guifont`, etc.) - those are dotfiles-repo-owned per `modules/home/dotfiles.nix`'s Stow model, outside this shared profile's remit. +- Provisioning any other typeface. The `fonts` capability is scoped to this one font for now; broadening it is a future change. +- Any NixOS-level (`modules/nixos/common.nix`) font configuration - system-level `fonts.packages` is a separate, unused mechanism here; everything goes through the home-manager profile per this repo's existing GUI-package pattern. + +## Decisions + +**New `modules/home/fonts.nix`, imported from `modules/home/default.nix`.** Mirrors the existing per-concern module layout (`desktop-apps.nix`, `editor.nix`, etc.) rather than folding the font into an existing file - fonts are a distinct concern from GUI applications or the editor toolchain, and a dedicated `fonts` capability needs a dedicated spec-to-code mapping. + +**Filter through `lib.meta.availableOn pkgs.stdenv.hostPlatform` even for a single-package list.** Alternative considered: skip the filter since only one font package exists today and none of the currently-defined outputs hit the unsupported platform. Rejected because the gap is real (confirmed above) and the guard is a one-line reuse of an already-established, already-imported pattern (`desktop-apps.nix` imports `lib` for the same purpose) - cheaper than the risk of a future Darwin-Intel host hitting an eval failure. + +**Set `fonts.fontconfig.enable = true;` unconditionally (no `osConfig`/platform guard).** This option is home-manager-internal and platform-safe on its own: it's a no-op contributor on Darwin (fontconfig isn't the font-discovery path there; `targets.darwin.fonts` handles that unconditionally regardless of this option) and is idempotent on NixOS (already defaults to `true` there via the `useUserPackages` derivation). Setting it explicitly, rather than relying on that implicit default, documents the intent directly in this repo's own module and keeps standalone Linux behavior correct without depending on NixOS-side wiring. Alternative considered: gate it behind `pkgs.stdenv.hostPlatform.isLinux` for clarity - rejected as unnecessary ceremony since the option is inert (not merely ignored, but literally unused) on Darwin. + +## Risks / Trade-offs + +- [`nerd-fonts.jetbrains-mono` has no `x86_64-darwin` build in the pinned nixpkgs] → Mitigated by the `lib.meta.availableOn` filter; the package silently drops out there instead of failing `nix flake check` or a build, consistent with the `desktop-applications` capability's existing unsupported-package handling. +- [nixpkgs restructures or renames the `nerd-fonts.*` package set in a future `nixpkgs-unstable` bump] → Would surface as an eval error on the next `nix flake check` / `flake.lock` update, same exposure as any other pinned package reference in this repo; no special handling proposed here. diff --git a/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/proposal.md b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/proposal.md new file mode 100644 index 0000000..060b69a --- /dev/null +++ b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/proposal.md @@ -0,0 +1,23 @@ +## Why + +The shared home profile provisions Ghostty (terminal) and Neovim, both of which render icon glyphs (statusline segments, `nvim-tree`/`neo-tree` file icons, etc.) that require a "Nerd Font" patched typeface to display correctly. No font is currently provisioned by this repo at all, so those glyphs fall back to tofu boxes or missing-character placeholders on any freshly activated host or standalone machine. + +## What Changes + +- Provision the JetBrains Mono Nerd Font (`pkgs.nerd-fonts.jetbrains-mono`) through the shared home-manager profile, in a new `modules/home/fonts.nix`. +- Skip the font package on a platform where it has no supported build, following the same `lib.meta.availableOn` pattern already used in `modules/home/desktop-apps.nix`, rather than failing evaluation. (`nerd-fonts.jetbrains-mono` is currently unsupported on `x86_64-darwin` in the pinned nixpkgs, though none of this flake's actual `homeConfigurations`/`nixosConfigurations` outputs target that system today.) +- Enable home-manager's `fonts.fontconfig.enable` so the font is discoverable by fontconfig-based applications on standalone (non-NixOS) Linux activations, where it isn't already implied by a NixOS host's own `fonts.fontconfig.enable`. On Darwin, home-manager copies fonts from `home.packages` into `~/Library/Fonts/HomeManager` unconditionally, independent of this option. + +## Capabilities + +### New Capabilities +- `fonts`: Provisions typefaces (starting with the JetBrains Mono Nerd Font) through the shared home-manager profile, available wherever that profile is activated and discoverable by both fontconfig-based apps and native macOS font resolution. + +### Modified Capabilities +(none) + +## Impact + +- New file: `modules/home/fonts.nix`. +- Modified: `modules/home/default.nix` (import the new module). +- No changes to `hosts/`, `users/tom.nix`, or NixOS-level modules — this is a cross-platform home-manager profile addition only. diff --git a/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/specs/fonts/spec.md b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/specs/fonts/spec.md new file mode 100644 index 0000000..e57f124 --- /dev/null +++ b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/specs/fonts/spec.md @@ -0,0 +1,26 @@ +## Purpose + +Provisions typefaces through the shared home-manager profile, starting with the JetBrains Mono Nerd Font, so that glyph-dependent terminal and editor UIs render correctly wherever that profile is activated. + +## ADDED Requirements + +### Requirement: JetBrains Mono Nerd Font is provisioned via the shared home profile +The shared home-manager profile SHALL include the JetBrains Mono Nerd Font as a package, available wherever that profile is activated and the underlying package supports the current system. + +#### Scenario: Font available after activation +- **WHEN** the shared home profile is activated on a system for which the JetBrains Mono Nerd Font package is supported +- **THEN** the font is installed and resolvable by name by font-aware applications, without any additional manual installation step + +### Requirement: The font package is skipped, not failed, on unsupported systems +On a system for which the JetBrains Mono Nerd Font package has no supported build, the package SHALL be omitted from the provisioned package set rather than causing profile evaluation or activation to fail. + +#### Scenario: Unsupported system excluded without failure +- **WHEN** the shared home profile is evaluated on a system for which the JetBrains Mono Nerd Font package has no supported build +- **THEN** the font package is excluded from the provisioned set and the rest of the profile evaluates and activates successfully + +### Requirement: The font is discoverable by fontconfig-based applications +On a Linux activation of the shared home profile, fontconfig SHALL be configured to discover fonts installed through the profile's packages, so that fontconfig-based applications (including the terminal and editor provisioned elsewhere in this profile) can resolve the JetBrains Mono Nerd Font by name. + +#### Scenario: Font resolvable via fontconfig after activation +- **WHEN** the shared home profile is activated on a Linux system, whether standalone or as part of a NixOS host +- **THEN** a fontconfig-based application can enumerate and select the JetBrains Mono Nerd Font by name without additional manual font-cache configuration diff --git a/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/tasks.md b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/tasks.md new file mode 100644 index 0000000..0280128 --- /dev/null +++ b/openspec/changes/archive/2026-09-24-add-jetbrains-mono-nerd-font/tasks.md @@ -0,0 +1,10 @@ +## 1. Font module + +- [x] 1.1 Create `modules/home/fonts.nix` provisioning `pkgs.nerd-fonts.jetbrains-mono` via `home.packages`, filtered through `lib.meta.availableOn pkgs.stdenv.hostPlatform` (same pattern as `modules/home/desktop-apps.nix`), and setting `fonts.fontconfig.enable = true;` +- [x] 1.2 Import `./fonts.nix` in `modules/home/default.nix` and verify `nix eval '.#homeConfigurations."tom@linux".config.home.packages'` and `nix eval '.#homeConfigurations."tom@darwin".config.home.packages'` each include the nerd font derivation + +## 2. Verification + +- [x] 2.1 Run `nix flake check` and confirm it passes +- [x] 2.2 Run `nix build '.#homeConfigurations."tom@linux".activationPackage'` and `nix build '.#homeConfigurations."tom@darwin".activationPackage'` and confirm both succeed (verified via `--dry-run`: this session's machine is aarch64-linux with no remote builders configured, so it cannot natively build either target; `--dry-run` confirmed the full derivation graph, including the new font package, resolves without evaluation errors for both) +- [x] 2.3 Run `nix fmt` and confirm `modules/home/fonts.nix` is formatted with no diff diff --git a/openspec/specs/fonts/spec.md b/openspec/specs/fonts/spec.md new file mode 100644 index 0000000..2b0f9ea --- /dev/null +++ b/openspec/specs/fonts/spec.md @@ -0,0 +1,28 @@ +# fonts Specification + +## Purpose + +Provisions typefaces through the shared home-manager profile, starting with the JetBrains Mono Nerd Font, so that glyph-dependent terminal and editor UIs render correctly wherever that profile is activated. + +## Requirements + +### Requirement: JetBrains Mono Nerd Font is provisioned via the shared home profile +The shared home-manager profile SHALL include the JetBrains Mono Nerd Font as a package, available wherever that profile is activated and the underlying package supports the current system. + +#### Scenario: Font available after activation +- **WHEN** the shared home profile is activated on a system for which the JetBrains Mono Nerd Font package is supported +- **THEN** the font is installed and resolvable by name by font-aware applications, without any additional manual installation step + +### Requirement: The font package is skipped, not failed, on unsupported systems +On a system for which the JetBrains Mono Nerd Font package has no supported build, the package SHALL be omitted from the provisioned package set rather than causing profile evaluation or activation to fail. + +#### Scenario: Unsupported system excluded without failure +- **WHEN** the shared home profile is evaluated on a system for which the JetBrains Mono Nerd Font package has no supported build +- **THEN** the font package is excluded from the provisioned set and the rest of the profile evaluates and activates successfully + +### Requirement: The font is discoverable by fontconfig-based applications +On a Linux activation of the shared home profile, fontconfig SHALL be configured to discover fonts installed through the profile's packages, so that fontconfig-based applications (including the terminal and editor provisioned elsewhere in this profile) can resolve the JetBrains Mono Nerd Font by name. + +#### Scenario: Font resolvable via fontconfig after activation +- **WHEN** the shared home profile is activated on a Linux system, whether standalone or as part of a NixOS host +- **THEN** a fontconfig-based application can enumerate and select the JetBrains Mono Nerd Font by name without additional manual font-cache configuration -- cgit v1.3