From 8edf330a06f59347077df1e0c3aaddc490a2771c Mon Sep 17 00:00:00 2001 From: alexion Date: Sun, 11 Oct 2026 20:16:43 -0400 Subject: [PATCH] refactor(nix): share glyph decoding helper --- .../nixos/modules/desktop/apps/firefox.nix | 3 ++- .../nixos/modules/desktop/apps/ghostty.nix | 3 ++- .../nixos/modules/desktop/apps/obsidian.nix | 3 ++- configs/nixos/modules/desktop/apps/signal.nix | 3 ++- configs/nixos/modules/desktop/apps/steam.nix | 3 ++- .../nixos/modules/desktop/apps/vencord.nix | 3 ++- .../desktop/session/hyprland/default.nix | 3 ++- .../desktop/session/hyprland/hyprlock.nix | 11 ++++++++-- .../nixos/modules/desktop/session/mako.nix | 7 +++--- .../nixos/modules/desktop/session/waybar.nix | 22 ++++++++----------- .../nixos/modules/desktop/utilities/audio.nix | 16 ++++++-------- .../modules/desktop/utilities/recording.nix | 3 ++- configs/nixos/modules/network/vpn-client.nix | 6 ++++- src/dotfiles/util.nix | 8 +++++++ 14 files changed, 57 insertions(+), 37 deletions(-) diff --git a/configs/nixos/modules/desktop/apps/firefox.nix b/configs/nixos/modules/desktop/apps/firefox.nix index 0f5e768..65140b7 100644 --- a/configs/nixos/modules/desktop/apps/firefox.nix +++ b/configs/nixos/modules/desktop/apps/firefox.nix @@ -3,6 +3,7 @@ inputs, lib, pkgs, + util, ... }: # Configures Firefox as the desktop browser. @@ -28,7 +29,7 @@ in config = lib.mkIf cfg.enable { registry.window-icon.${config.networking.hostName}.firefox = { class = ".*[Ff]irefox.*"; - icon = builtins.fromJSON ''"\uf269"''; + icon = util.glyph "f269"; }; home-manager.users.${config.user.name} = hm: { diff --git a/configs/nixos/modules/desktop/apps/ghostty.nix b/configs/nixos/modules/desktop/apps/ghostty.nix index 2813299..d8e1e73 100644 --- a/configs/nixos/modules/desktop/apps/ghostty.nix +++ b/configs/nixos/modules/desktop/apps/ghostty.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Ghostty as the desktop terminal. @@ -22,7 +23,7 @@ in registry.window-icon.${config.networking.hostName}.ghostty = { class = "com.mitchellh.ghostty"; - icon = builtins.fromJSON ''"\uf120"''; + icon = util.glyph "f120"; }; home-manager.users.${user}.home.packages = [ pkgs.ghostty ]; diff --git a/configs/nixos/modules/desktop/apps/obsidian.nix b/configs/nixos/modules/desktop/apps/obsidian.nix index e62fd4d..49648aa 100644 --- a/configs/nixos/modules/desktop/apps/obsidian.nix +++ b/configs/nixos/modules/desktop/apps/obsidian.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Obsidian as the desktop note-taking vault. @@ -17,7 +18,7 @@ in registry.window-icon.${config.networking.hostName}.obsidian = { class = "obsidian"; - icon = builtins.fromJSON ''"\uf02d"''; + icon = util.glyph "f02d"; }; }; } diff --git a/configs/nixos/modules/desktop/apps/signal.nix b/configs/nixos/modules/desktop/apps/signal.nix index bf3ca0d..534d0f0 100644 --- a/configs/nixos/modules/desktop/apps/signal.nix +++ b/configs/nixos/modules/desktop/apps/signal.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Signal desktop messenger. @@ -16,7 +17,7 @@ in registry.window-icon.${config.networking.hostName}.signal = { class = "[Ss]ignal"; - icon = builtins.fromJSON ''"\uf4ad"''; + icon = util.glyph "f4ad"; }; }; } diff --git a/configs/nixos/modules/desktop/apps/steam.nix b/configs/nixos/modules/desktop/apps/steam.nix index d952f00..eb252ce 100644 --- a/configs/nixos/modules/desktop/apps/steam.nix +++ b/configs/nixos/modules/desktop/apps/steam.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Steam game launcher and runtime integration. @@ -26,7 +27,7 @@ registry.window-icon.${config.networking.hostName}.steam = { class = "[Ss]team"; - icon = builtins.fromJSON ''"\uf1b6"''; + icon = util.glyph "f1b6"; }; }; } diff --git a/configs/nixos/modules/desktop/apps/vencord.nix b/configs/nixos/modules/desktop/apps/vencord.nix index 90edaa0..53a634c 100644 --- a/configs/nixos/modules/desktop/apps/vencord.nix +++ b/configs/nixos/modules/desktop/apps/vencord.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Vesktop, a Discord client with Vencord built in. @@ -17,7 +18,7 @@ in registry.window-icon.${config.networking.hostName}.vesktop = { class = "[Vv]esktop"; - icon = builtins.fromJSON ''"\uf1ff"''; + icon = util.glyph "f1ff"; }; }; } diff --git a/configs/nixos/modules/desktop/session/hyprland/default.nix b/configs/nixos/modules/desktop/session/hyprland/default.nix index 284e406..0d39fd8 100644 --- a/configs/nixos/modules/desktop/session/hyprland/default.nix +++ b/configs/nixos/modules/desktop/session/hyprland/default.nix @@ -1,6 +1,7 @@ { config, lib, + util, ... }: # The Hyprland compositor. @@ -235,7 +236,7 @@ on-click = "activate"; format = "{id} {windows}"; format-window-separator = " "; - window-rewrite-default = builtins.fromJSON ''"\uf2d0"''; + window-rewrite-default = util.glyph "f2d0"; window-rewrite = lib.mapAttrs' ( _name: windowIcon: lib.nameValuePair "class<${windowIcon.class}>" windowIcon.icon ) (lib.attrByPath [ config.networking.hostName ] { } config.registry.window-icon); diff --git a/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix b/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix index d1f8909..ae8fbcb 100644 --- a/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix +++ b/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix @@ -2,12 +2,19 @@ config, lib, pkgs, + util, ... }: # The lock screen: a hyprlock session-lock surface the compositor owns. let - sleepIcon = builtins.fromJSON ''"\udb81\udcb2"''; - sleepOffIcon = builtins.fromJSON ''"\udb81\udcb3"''; + sleepIcon = util.glyph [ + "db81" + "dcb2" + ]; + sleepOffIcon = util.glyph [ + "db81" + "dcb3" + ]; idleLockToggle = pkgs.writeShellScript "lockscreen-idle-inhibit-toggle" '' unit=lockscreen-idle-inhibit.service diff --git a/configs/nixos/modules/desktop/session/mako.nix b/configs/nixos/modules/desktop/session/mako.nix index 5c9448d..ec81c8b 100644 --- a/configs/nixos/modules/desktop/session/mako.nix +++ b/configs/nixos/modules/desktop/session/mako.nix @@ -2,17 +2,16 @@ config, lib, pkgs, + util, ... }: # mako as the notification daemon: toasts, a do-not-disturb mode, and history recall. let - glyph = code: builtins.fromJSON ''"\u${code}"''; - dndStatus = pkgs.writeShellScript "waybar-dnd-status" '' if ${lib.getExe' pkgs.mako "makoctl"} mode 2>/dev/null | ${lib.getExe pkgs.gnugrep} -qx dnd; then - printf '{"text":"${glyph "f1f6"}","tooltip":"Do not disturb: on","class":"dnd"}\n' + printf '{"text":"${util.glyph "f1f6"}","tooltip":"Do not disturb: on","class":"dnd"}\n' else - printf '{"text":"${glyph "f0f3"}","tooltip":"Notifications on","class":"active"}\n' + printf '{"text":"${util.glyph "f0f3"}","tooltip":"Notifications on","class":"active"}\n' fi ''; diff --git a/configs/nixos/modules/desktop/session/waybar.nix b/configs/nixos/modules/desktop/session/waybar.nix index 4a56b9b..078ab91 100644 --- a/configs/nixos/modules/desktop/session/waybar.nix +++ b/configs/nixos/modules/desktop/session/waybar.nix @@ -2,6 +2,7 @@ config, lib, pkgs, + util, ... }: # Waybar: a top status bar reading system state at a glance. @@ -30,10 +31,6 @@ let registeredWaybarModuleSettings = lib.mapAttrs (_name: module: module.settings) hostWaybarModules; - # A Nerd Font Private-Use-Area codepoint as a literal character, decoded - # through JSON so the glyph survives as bytes rather than an editor paste. - g = code: builtins.fromJSON ''"\u${code}"''; - networkStatus = pkgs.writeShellScript "waybar-network-status" '' active=$( ${lib.getExe' pkgs.networkmanager "nmcli"} -t -f DEVICE,TYPE,STATE,CONNECTION device status \ @@ -42,7 +39,7 @@ let if [ -z "$active" ]; then ${lib.getExe pkgs.jq} -cn \ - --arg text "${g "f127"} off" \ + --arg text "${util.glyph "f127"} off" \ --arg tooltip "Network disconnected" \ --arg class "disconnected" \ '{ text: $text, tooltip: $tooltip, class: $class }' @@ -52,7 +49,7 @@ let IFS=: read -r device type _state connection <<< "$active" case "$type" in - wifi) icon="${g "f1eb"}" ;; + wifi) icon="${util.glyph "f1eb"}" ;; ethernet) icon="LAN" ;; *) icon="NET" ;; esac @@ -99,7 +96,6 @@ in modules-left = waybarModulesFor "left"; modules-center = waybarModulesFor "center"; modules-right = waybarModulesFor "right"; - } registeredWaybarModuleSettings ]; @@ -133,13 +129,13 @@ in order = 70; settings = { format = "{icon} {capacity}%"; - format-charging = "${g "f0e7"} {capacity}%"; + format-charging = "${util.glyph "f0e7"} {capacity}%"; format-icons = [ - (g "f244") - (g "f243") - (g "f242") - (g "f241") - (g "f240") + (util.glyph "f244") + (util.glyph "f243") + (util.glyph "f242") + (util.glyph "f241") + (util.glyph "f240") ]; states = { warning = 20; diff --git a/configs/nixos/modules/desktop/utilities/audio.nix b/configs/nixos/modules/desktop/utilities/audio.nix index b832d65..d34ef91 100644 --- a/configs/nixos/modules/desktop/utilities/audio.nix +++ b/configs/nixos/modules/desktop/utilities/audio.nix @@ -2,12 +2,10 @@ config, lib, pkgs, + util, ... }: # PipeWire as the desktop audio server. -let - glyph = code: builtins.fromJSON ''"\u${code}"''; -in { options.modules.desktop.utilities.audio.enable = lib.mkEnableOption "the PipeWire audio server"; @@ -45,8 +43,8 @@ in mpris = { order = 30; settings = { - format = "${glyph "f001"} {title}"; - format-paused = "${glyph "f04c"} {title}"; + format = "${util.glyph "f001"} {title}"; + format-paused = "${util.glyph "f04c"} {title}"; max-length = 40; on-click = "play-pause"; on-scroll-up = "next"; @@ -58,11 +56,11 @@ in order = 40; settings = { format = "{icon} {volume}%"; - format-muted = "${glyph "f026"} muted"; + format-muted = "${util.glyph "f026"} muted"; format-icons = [ - (glyph "f026") - (glyph "f027") - (glyph "f028") + (util.glyph "f026") + (util.glyph "f027") + (util.glyph "f028") ]; on-click = "${lib.getExe' pkgs.wireplumber "wpctl"} set-mute @DEFAULT_AUDIO_SINK@ toggle"; }; diff --git a/configs/nixos/modules/desktop/utilities/recording.nix b/configs/nixos/modules/desktop/utilities/recording.nix index 9efcff5..8ded309 100644 --- a/configs/nixos/modules/desktop/utilities/recording.nix +++ b/configs/nixos/modules/desktop/utilities/recording.nix @@ -2,11 +2,12 @@ config, lib, pkgs, + util, ... }: # Keybound screen recording: pick a region, then toggle a video-only capture. let - recordingIcon = builtins.fromJSON ''"\uf03d"''; + recordingIcon = util.glyph "f03d"; # A single key both starts and stops. # A running wf-recorder is stopped with SIGINT so it finalises the file. diff --git a/configs/nixos/modules/network/vpn-client.nix b/configs/nixos/modules/network/vpn-client.nix index 62677e8..624f6df 100644 --- a/configs/nixos/modules/network/vpn-client.nix +++ b/configs/nixos/modules/network/vpn-client.nix @@ -2,12 +2,16 @@ config, lib, pkgs, + util, ... }: let cfg = config.modules.network.vpn-client; # NOLINT(let_order) - vpnIcon = builtins.fromJSON ''"\udb83\udc9d"''; + vpnIcon = util.glyph [ + "db83" + "dc9d" + ]; vpnStatus = pkgs.writeShellScript "waybar-vpn-status" '' interface=${lib.escapeShellArg cfg.interface} diff --git a/src/dotfiles/util.nix b/src/dotfiles/util.nix index b461c7c..01c44ff 100644 --- a/src/dotfiles/util.nix +++ b/src/dotfiles/util.nix @@ -25,6 +25,14 @@ in removeNixSuffix = path: lib.removeSuffix ".nix" (builtins.baseNameOf path); + glyph = + code: + builtins.fromJSON ( + "\"" + + (if builtins.isList code then lib.concatMapStrings (part: "\\u${part}") code else "\\u${code}") + + "\"" + ); + registry.predicates.uniqueValue = uniqueValue; registry.predicates.uniquePerHost =