Skip to content

Commit

Permalink
Tidy up overridable scheme type ♻️
Browse files Browse the repository at this point in the history
  • Loading branch information
danth committed Nov 18, 2023
1 parent 5d666dc commit 2481fc6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 62 deletions.
114 changes: 54 additions & 60 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ in mergeModules [
name = "static";
description = "static wallpaper";
descriptionClass = "noun";

check = value:
builtins.attrNames value == [ "colors" "image" ];

constructor =
{ image, polarity ? "either" }:
{
Expand All @@ -57,8 +59,10 @@ in mergeModules [
name = "slideshow";
description = "slideshow wallpaper";
descriptionClass = "noun";

check = value:
builtins.attrNames value == [ "colors" "delay" "image" "images" ];

constructor =
{ images, delay ? 300, polarity ? "either" }:
rec {
Expand All @@ -72,8 +76,10 @@ in mergeModules [
name = "animation";
description = "animated wallpaper";
descriptionClass = "noun";

check = value:
builtins.attrNames value == [ "animation" "colors" "image" ];

constructor =
{ animation, polarity ? "either" }:
rec {
Expand All @@ -87,8 +93,10 @@ in mergeModules [
name = "video";
description = "video wallpaper";
descriptionClass = "noun";

check = value:
builtins.attrNames value == [ "colors" "image" "video" ];

constructor =
{ video, polarity ? "either" }:
rec {
Expand All @@ -104,74 +112,60 @@ in mergeModules [
types.oneOf [ static slideshow animation video ];
}

(typeModule {
name = "scheme";
description = "base16 scheme";
descriptionClass = "noun";
check = value:
let
bases = [
"base00" "base01" "base02" "base03"
"base04" "base05" "base06" "base07"
"base08" "base09" "base0A" "base0B"
"base0C" "base0D" "base0E" "base0F"
];
meta = [
"scheme" "author" "description" "slug"
];
requiredAttrs = bases;
allowedAttrs = bases ++ meta;
in
types.path.check value ||
(builtins.isAttrs value
&& all (a: elem a allowedAttrs) (builtins.attrNames value)
&& all (a: elem a (builtins.attrNames value)) requiredAttrs
);
})
(let
bases = [
"base00" "base01" "base02" "base03"
"base04" "base05" "base06" "base07"
"base08" "base09" "base0A" "base0B"
"base0C" "base0D" "base0E" "base0F"
];
meta = [
"scheme" "author" "description" "slug"
];

(typeModule {
name = "override";
description = "override for base16 scheme";
descriptionClass = "noun";
emptyValue.value = { };
check = value:
let allowedAttrs = [
"base00" "base01" "base02" "base03"
"base04" "base05" "base06" "base07"
"base08" "base09" "base0A" "base0B"
"base0C" "base0D" "base0E" "base0F"
"scheme" "author" "description" "slug"
];
in builtins.isAttrs value
&& all (a: elem a allowedAttrs) (builtins.attrNames value);
})
hasOnlyPermittedAttrs = set:
all (a: elem a (bases ++ meta)) (attrNames set);

hasAllRequiredAttrs = set:
all (a: elem a (attrNames set)) bases;

isSchemeOrOverride = value:
types.path.check value ||
(builtins.isAttrs value && hasOnlyPermittedAttrs value);

isScheme = value:
types.path.check value ||
(builtins.isAttrs value && hasAllRequiredAttrs value);

(typeModule {
name = "overridableScheme";
description = "base16 scheme with overrides";
descriptionClass = "conjunction";
emptyValue.value = { };
check = value:
config.lib.stylix.types.scheme.check value ||
config.lib.stylix.types.override.check value;
merge = optionName: definitions:
let
values = catAttrs "value" definitions;
partitioned = partition config.lib.stylix.types.scheme.check values;
scheme =
if length partitioned.right < 1

partitioned = partition isScheme values;
schemes = partitioned.right;
overrides = partitioned.wrong;

schemeDefinition =
if length schemes < 1
then
# If only overrides were provided, try applying them to the option default.
# If only overrides were found, try looking at the option default for a scheme.
if hasAttrByPath (optionName ++ [ "default" ]) options
then getAttrFromPath (optionName ++ [ "default" ]) options
else throw "At least one definition for `${showOption optionName}' must be a whole scheme."
else throw "At least one definition for `${showOption optionName}' must contain a whole scheme."
else
if length partitioned.right > 1
then throw "Only one definition for `${showOption optionName}' may be a whole scheme."
else elemAt partitioned.right 0;
in foldr
(o: s: s.override o)
(base16.mkSchemeAttrs scheme)
partitioned.wrong;
if length schemes > 1
then throw "Only one definition for `${showOption optionName}' may contain a whole scheme."
else elemAt schemes 0;

scheme = base16.mkSchemeAttrs schemeDefinition;

in foldr (o: s: s.override o) scheme overrides;

in typeModule {
name = "scheme";
description = "base16 scheme";
descriptionClass = "noun";
check = isSchemeOrOverride;
inherit merge;
})
]
6 changes: 4 additions & 2 deletions stylix/palette.nix
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ in {
};

colors = mkOption {
type = config.lib.stylix.types.overridableScheme;
type = config.lib.stylix.types.scheme;
default = config.stylix.wallpaper.colors;
defaultText = literalMD "generated scheme based on `stylix.wallpaper`";
description = ''
Expand All @@ -127,6 +127,8 @@ in {
- Anything from `base00` to `base0F`, but not all of them
- Optionally `scheme`, `author`, `description` or `slug`
There must be exactly one whole scheme.
Popular files can be imported from
[`base16-schemes`](https://github.com/tinted-theming/base16-schemes):
Expand All @@ -137,7 +139,7 @@ in {
}
```
To choose a scheme and override it from the same place, use `mkMerge`:
To choose a scheme and override it from the same file, use `mkMerge`:
```nix
{ pkgs, lib, ... }:
Expand Down

0 comments on commit 2481fc6

Please sign in to comment.