feat(lib): Add helper fns to handle theme naming

Rose Pine names the default theme flavor something like "Rose Pine", and
when a theme needs to be kebab case that requires extra logic to avoid a
hanging - when the main flavor is selected.
This commit is contained in:
punkfairie 2024-11-04 13:05:50 -08:00
parent 91374e5df4
commit 0f2722c5f7
Signed by: punkfairie
GPG key ID: 01823C057725C266

View file

@ -3,17 +3,20 @@
lib, lib,
pkgs, pkgs,
... ...
}: let }:
let
# this is a recursive attribute with all the functions below # this is a recursive attribute with all the functions below
inherit (lib) rp; inherit (lib) rp;
in { in
{
# string -> type -> string -> a # string -> type -> string -> a
# this is an internal function and shouldn't be # this is an internal function and shouldn't be
# used unless you know what you're doing. it takes # used unless you know what you're doing. it takes
# a string (the name of the property, i.e., flavor # a string (the name of the property, i.e., flavor
# or accent), the type of the property, the name of # or accent), the type of the property, the name of
# the module, followed by local config attrset # the module, followed by local config attrset
mkBasicOpt = attr: type: name: mkBasicOpt =
attr: type: name:
lib.mkOption { lib.mkOption {
inherit type; inherit type;
default = config.rose-pine.${attr}; default = config.rose-pine.${attr};
@ -42,47 +45,65 @@ in {
]; ];
}; };
# string -> string
# this returns a blank string when string == "main",
# because Rose Pine names the default flavor rose pine
getFlavor = flavor: (if flavor == "main" then "" else flavor);
# string -> string
# convert flavor to full theme name in kebab case
# a convenience to deal with the main flavor naming
getKebabTheme = flavor: (if flavor == "main" then "rose-pine" else "rose-pine-${flavor}");
# string -> string # string -> string
# this capitalizes the first letter in a string, # this capitalizes the first letter in a string,
# which is sometimes needed in order to format # which is sometimes needed in order to format
# the names of themes correctly # the names of themes correctly
mkUpper = str: mkUpper =
str:
(lib.toUpper (builtins.substring 0 1 str)) + (builtins.substring 1 (builtins.stringLength str) str); (lib.toUpper (builtins.substring 0 1 str)) + (builtins.substring 1 (builtins.stringLength str) str);
# a -> path -> a # a -> path -> a
# fromJSON but for yaml (and without readFile) # fromJSON but for yaml (and without readFile)
# a should be the local pkgs attrset # a should be the local pkgs attrset
fromYaml = file: let fromYaml =
# convert to json file:
json = pkgs.runCommand "converted.json" {} '' let
${lib.getExe pkgs.yj} < ${file} > $out # convert to json
''; json = pkgs.runCommand "converted.json" { } ''
in ${lib.getExe pkgs.yj} < ${file} > $out
'';
in
builtins.fromJSON (builtins.readFile json); builtins.fromJSON (builtins.readFile json);
# a -> path -> a # a -> path -> a
# fromJSON but for ini (and without readFile) # fromJSON but for ini (and without readFile)
# a should be the local pkgs attrset # a should be the local pkgs attrset
fromINI = file: let fromINI =
# convert to json file:
json = pkgs.runCommand "converted.json" {} '' let
${lib.getExe pkgs.jc} --ini < ${file} > $out # convert to json
''; json = pkgs.runCommand "converted.json" { } ''
in ${lib.getExe pkgs.jc} --ini < ${file} > $out
'';
in
builtins.fromJSON (builtins.readFile json); builtins.fromJSON (builtins.readFile json);
# a -> path -> a # a -> path -> a
# fromJSON but for raw ini (and without readFile) # fromJSON but for raw ini (and without readFile)
# a should be the local pkgs attrset # a should be the local pkgs attrset
fromINIRaw = file: let fromINIRaw =
inherit (builtins) fromJSON readFile; file:
let
inherit (builtins) fromJSON readFile;
# convert to json # convert to json
json = with pkgs; json =
runCommand "converted.json" {} '' with pkgs;
${jc}/bin/jc --ini -r < ${file} > $out runCommand "converted.json" { } ''
''; ${jc}/bin/jc --ini -r < ${file} > $out
in '';
in
fromJSON (readFile json); fromJSON (readFile json);
# string -> a # string -> a
@ -91,18 +112,18 @@ in {
# of the module, while `enableDefault` is a boolean # of the module, while `enableDefault` is a boolean
# representing the default of the created `enable` # representing the default of the created `enable`
# option # option
mkRosePineOpt = { mkRosePineOpt =
name, {
enableDefault ? config.rose-pine.enable, name,
}: { enableDefault ? config.rose-pine.enable,
enable = }:
lib.mkEnableOption "Rose Pine theme for ${name}" {
// { enable = lib.mkEnableOption "Rose Pine theme for ${name}" // {
default = enableDefault; default = enableDefault;
}; };
flavor = rp.mkFlavorOpt name; flavor = rp.mkFlavorOpt name;
}; };
# string -> a # string -> a
# this creates an accent option for modules # this creates an accent option for modules
@ -120,17 +141,18 @@ in {
# returns the current release version of nixos or home-manager. throws an evaluation error if neither are # returns the current release version of nixos or home-manager. throws an evaluation error if neither are
# found # found
getModuleRelease = getModuleRelease =
config.home.version.release config.home.version.release or config.system.nixos.release
or config.system.nixos.release or (throw "Couldn't determine release version!");
or (throw "Couldn't determine release version!");
# string -> a -> a # string -> a -> a
# if the current module release is less than `minVersion`, all options are made no-ops with # if the current module release is less than `minVersion`, all options are made no-ops with
# `lib.mkSinkUndeclaredOptions` # `lib.mkSinkUndeclaredOptions`
mkVersionedOpts = minVersion: option: mkVersionedOpts =
if lib.versionAtLeast rp.getModuleRelease minVersion minVersion: option:
then option if lib.versionAtLeast rp.getModuleRelease minVersion then
else lib.mkSinkUndeclaredOptions {}; option
else
lib.mkSinkUndeclaredOptions { };
# string -> a # string -> a
# this is to ensure users are running a supported version of nixos/home-manager # this is to ensure users are running a supported version of nixos/home-manager