mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
277 lines
7 KiB
Nix
277 lines
7 KiB
Nix
{
|
|
lib,
|
|
gvariant ? import ./gvariant.nix { inherit lib; },
|
|
}:
|
|
|
|
let
|
|
inherit (lib)
|
|
all
|
|
concatMap
|
|
foldl'
|
|
getFiles
|
|
getValues
|
|
head
|
|
isFunction
|
|
literalExpression
|
|
mergeAttrs
|
|
mergeDefaultOption
|
|
mergeOneOption
|
|
mkOption
|
|
mkOptionType
|
|
showFiles
|
|
showOption
|
|
types
|
|
;
|
|
|
|
typesDag = import ./types-dag.nix { inherit lib; };
|
|
|
|
# Needed since the type is called gvariant and its merge attribute
|
|
# must refer back to the type.
|
|
gvar = gvariant;
|
|
|
|
in
|
|
rec {
|
|
|
|
inherit (typesDag) dagOf;
|
|
|
|
selectorFunction = mkOptionType {
|
|
name = "selectorFunction";
|
|
description =
|
|
"Function that takes an attribute set and returns a list"
|
|
+ " containing a selection of the values of the input set";
|
|
check = isFunction;
|
|
merge =
|
|
_loc: defs: as:
|
|
concatMap (select: select as) (getValues defs);
|
|
};
|
|
|
|
overlayFunction = mkOptionType {
|
|
name = "overlayFunction";
|
|
description =
|
|
"An overlay function, takes self and super and returns"
|
|
+ " an attribute set overriding the desired attributes.";
|
|
check = isFunction;
|
|
merge =
|
|
_loc: defs: self: super:
|
|
foldl' (res: def: mergeAttrs res (def.value self super)) { } defs;
|
|
};
|
|
|
|
fontType = types.submodule {
|
|
options = {
|
|
package = mkOption {
|
|
type = types.nullOr types.package;
|
|
default = null;
|
|
example = literalExpression "pkgs.dejavu_fonts";
|
|
description = ''
|
|
Package providing the font. This package will be installed
|
|
to your profile. If `null` then the font
|
|
is assumed to already be available in your profile.
|
|
'';
|
|
};
|
|
|
|
name = mkOption {
|
|
type = types.str;
|
|
example = "DejaVu Sans";
|
|
description = ''
|
|
The family name of the font within the package.
|
|
'';
|
|
};
|
|
|
|
size = mkOption {
|
|
type = types.nullOr types.number;
|
|
default = null;
|
|
example = "8";
|
|
description = ''
|
|
The size of the font.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
gvariant = mkOptionType rec {
|
|
name = "gvariant";
|
|
description = "GVariant value";
|
|
check = v: gvar.mkValue v != null;
|
|
merge =
|
|
loc: defs:
|
|
let
|
|
vdefs = map (
|
|
d:
|
|
d
|
|
// {
|
|
value = if gvar.isGVariant d.value then d.value else gvar.mkValue d.value;
|
|
}
|
|
) defs;
|
|
vals = map (d: d.value) vdefs;
|
|
defTypes = map (x: x.type) vals;
|
|
sameOrNull = x: y: if x == y then y else null;
|
|
# A bit naive to just check the first entry…
|
|
sharedDefType = foldl' sameOrNull (head defTypes) defTypes;
|
|
allChecked = all (x: check x) vals;
|
|
in
|
|
if sharedDefType == null then
|
|
throw (
|
|
"Cannot merge definitions of `${showOption loc}' with"
|
|
+ " mismatched GVariant types given in"
|
|
+ " ${showFiles (getFiles defs)}."
|
|
)
|
|
else if gvar.isArray sharedDefType && allChecked then
|
|
gvar.mkValue ((types.listOf gvariant).merge loc (map (d: d // { value = d.value.value; }) vdefs))
|
|
// {
|
|
type = sharedDefType;
|
|
}
|
|
else if gvar.isTuple sharedDefType && allChecked then
|
|
mergeOneOption loc defs
|
|
else if gvar.isMaybe sharedDefType && allChecked then
|
|
mergeOneOption loc defs
|
|
else if gvar.isDictionaryEntry sharedDefType && allChecked then
|
|
mergeOneOption loc defs
|
|
else if gvar.type.variant == sharedDefType && allChecked then
|
|
mergeOneOption loc defs
|
|
else if gvar.type.string == sharedDefType && allChecked then
|
|
types.str.merge loc defs
|
|
else if gvar.type.double == sharedDefType && allChecked then
|
|
types.float.merge loc defs
|
|
else
|
|
mergeDefaultOption loc defs;
|
|
};
|
|
|
|
nushellValue =
|
|
let
|
|
valueType = types.nullOr (
|
|
types.oneOf [
|
|
(lib.mkOptionType {
|
|
name = "nushell";
|
|
description = "Nushell inline value";
|
|
descriptionClass = "name";
|
|
check = lib.isType "nushell-inline";
|
|
})
|
|
types.bool
|
|
types.int
|
|
types.float
|
|
types.str
|
|
types.path
|
|
(
|
|
types.attrsOf valueType
|
|
// {
|
|
description = "attribute set of Nushell values";
|
|
descriptionClass = "name";
|
|
}
|
|
)
|
|
(
|
|
types.listOf valueType
|
|
// {
|
|
description = "list of Nushell values";
|
|
descriptionClass = "name";
|
|
}
|
|
)
|
|
]
|
|
);
|
|
in
|
|
valueType;
|
|
|
|
sourceFile =
|
|
targetDir: fileName:
|
|
let
|
|
targetFile = "${targetDir}/${fileName}";
|
|
in
|
|
types.submodule (
|
|
{ config, ... }:
|
|
{
|
|
options = {
|
|
target = mkOption {
|
|
type = types.singleLineStr;
|
|
internal = true;
|
|
readOnly = true;
|
|
};
|
|
source = mkOption {
|
|
type = types.nullOr types.path;
|
|
default = null;
|
|
description = ''
|
|
The path to be linked to `${targetDir}` if {option}`source` is a directory,
|
|
or to `${targetFile}` if it is a file.
|
|
'';
|
|
};
|
|
text = mkOption {
|
|
type = types.lines;
|
|
default = "";
|
|
description = ''
|
|
Text to be included in `${targetFile}`.
|
|
'';
|
|
};
|
|
recursive = lib.mkEnableOption ''
|
|
Whether to recursively link files from {option}`source` (if it is a directory) in `${targetDir}`.
|
|
'';
|
|
};
|
|
config = {
|
|
target =
|
|
if config.source != null && lib.pathIsDirectory config.source then targetDir else targetFile;
|
|
};
|
|
}
|
|
);
|
|
|
|
sourceFileOrLines =
|
|
targetDir: fileName:
|
|
let
|
|
fileType = sourceFile targetDir fileName;
|
|
union = types.either types.lines fileType;
|
|
in
|
|
union
|
|
// {
|
|
merge =
|
|
loc: defs:
|
|
fileType.merge loc (
|
|
map (
|
|
def:
|
|
if types.lines.check def.value then
|
|
{
|
|
inherit (def) file;
|
|
value = {
|
|
text = def.value;
|
|
source = null;
|
|
recursive = false;
|
|
};
|
|
}
|
|
else
|
|
def
|
|
) defs
|
|
);
|
|
};
|
|
|
|
SCFGDirectives =
|
|
let
|
|
inherit (types)
|
|
listOf
|
|
nullOr
|
|
submodule
|
|
;
|
|
primType =
|
|
with types;
|
|
oneOf [
|
|
int
|
|
float
|
|
str
|
|
bool
|
|
];
|
|
directive =
|
|
(submodule {
|
|
options = {
|
|
name = mkOption { type = types.str; };
|
|
params = mkOption {
|
|
type = nullOr (listOf primType);
|
|
default = null;
|
|
};
|
|
children = mkOption {
|
|
type = nullOr directives;
|
|
default = null;
|
|
};
|
|
};
|
|
})
|
|
// {
|
|
description = "test";
|
|
};
|
|
directives = listOf directive;
|
|
in
|
|
# directives;
|
|
lib.types.anything;
|
|
}
|