# This module is heavily inspired by the corresponding NixOS module. See # # https://github.com/NixOS/nixpkgs/blob/23.11/nixos/modules/config/fonts/fontconfig.nix { config, lib, pkgs, ... }: with lib; let cfg = config.fonts.fontconfig; profileDirectory = config.home.profileDirectory; in { meta.maintainers = [ maintainers.rycee ]; imports = [ (mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [ "fonts" "fontconfig" "enable" ]) ]; options = { fonts.fontconfig = { enable = mkOption { type = types.bool; default = false; description = '' Whether to enable fontconfig configuration. This will, for example, allow fontconfig to discover fonts and configurations installed through {var}`home.packages` and {command}`nix-env`. ''; }; defaultFonts = { monospace = mkOption { type = with types; listOf str; default = [ ]; description = '' Per-user default monospace font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; sansSerif = mkOption { type = with types; listOf str; default = [ ]; description = '' Per-user default sans serif font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; serif = mkOption { type = with types; listOf str; default = [ ]; description = '' Per-user default serif font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; emoji = mkOption { type = with types; listOf str; default = [ ]; description = '' Per-user default emoji font(s). Multiple fonts may be listed in case a font does not support all emoji. Note that fontconfig matches color emoji fonts preferentially, so if you want to use a black and white font while having a color font installed (eg. Noto Color Emoji installed alongside Noto Emoji), fontconfig will still choose the color font even when it is later in the list. ''; }; }; }; }; config = mkIf cfg.enable { home.packages = [ # Make sure that buildEnv creates a real directory path so that we avoid # trying to write to a read-only location. (pkgs.runCommandLocal "dummy-fc-dir1" { } "mkdir -p $out/lib/fontconfig") (pkgs.runCommandLocal "dummy-fc-dir2" { } "mkdir -p $out/lib/fontconfig") ]; home.extraProfileCommands = '' if [[ -d $out/lib/X11/fonts || -d $out/share/fonts ]]; then export FONTCONFIG_FILE="$(pwd)/fonts.conf" cat > $FONTCONFIG_FILE << EOF <?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <dir>$out/lib/X11/fonts</dir> <dir>$out/share/fonts</dir> <cachedir>$out/lib/fontconfig/cache</cachedir> </fontconfig> EOF ${getBin pkgs.fontconfig}/bin/fc-cache -f rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache rm "$FONTCONFIG_FILE" unset FONTCONFIG_FILE fi # Remove the fontconfig directory if no files were available. if [[ -d $out/lib/fontconfig ]] ; then rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig fi ''; xdg.configFile = let mkFontconfigConf = conf: '' <?xml version='1.0'?> <!-- Generated by Home Manager. --> <!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'> <fontconfig> ${conf} </fontconfig> ''; in { "fontconfig/conf.d/10-hm-fonts.conf".text = mkFontconfigConf '' <description>Add fonts in the Nix user profile</description> <include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include> <include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include> <dir>${config.home.path}/lib/X11/fonts</dir> <dir>${config.home.path}/share/fonts</dir> <dir>${profileDirectory}/lib/X11/fonts</dir> <dir>${profileDirectory}/share/fonts</dir> <cachedir>${config.home.path}/lib/fontconfig/cache</cachedir> ''; "fontconfig/conf.d/52-hm-default-fonts.conf".text = let genDefault = fonts: name: optionalString (fonts != [ ]) '' <alias binding="same"> <family>${name}</family> <prefer> ${ concatStringsSep "" (map (font: '' <family>${font}</family> '') fonts) } </prefer> </alias> ''; in mkFontconfigConf '' <!-- Default fonts --> ${genDefault cfg.defaultFonts.sansSerif "sans-serif"} ${genDefault cfg.defaultFonts.serif "serif"} ${genDefault cfg.defaultFonts.monospace "monospace"} ${genDefault cfg.defaultFonts.emoji "emoji"} ''; }; }; }