nix-community.nixvim/lib/types.nix
2024-11-16 17:20:11 +00:00

183 lines
5.5 KiB
Nix

# Custom types to be included in `lib.types`
{ lib }:
let
inherit (lib) types;
inherit (lib.nixvim)
deprecation
mkNullOrStr
mkNullOrOption
;
mkStrLuaType =
description:
lib.mkOptionType {
name = "strLua";
inherit description;
descriptionClass = "noun";
check = v: lib.isString v || types.rawLua.check v;
merge =
loc: defs:
lib.pipe defs [
# Coerce strings to rawLua
# TODO: consider deprecating this behaviour
(lib.map (def: def // { value = lib.nixvim.mkRaw def.value; }))
(lib.options.mergeEqualOption loc)
];
};
isRawType = v: lib.isString (v.__raw or null);
in
rec {
# TODO: deprecate in favor of types.rawLua.check
# Or move to utils, lua, etc?
inherit isRawType;
rawLua = lib.mkOptionType {
name = "rawLua";
description = "raw lua code";
descriptionClass = "noun";
merge = lib.options.mergeEqualOption;
check = v: isRawType v || lib.nixvim.lua.isInline v || v ? __empty;
};
maybeRaw =
elemType:
let
luaFirst = types.either rawLua elemType;
elemFirst = types.either elemType rawLua;
in
luaFirst
// {
name = "maybeRaw";
inherit (elemFirst) description;
nestedTypes = {
left = lib.warn "maybeRaw.nestedTypes: `left` is a deprecated alias for `elemType`." elemType;
right = lib.warn "maybeRaw.nestedTypes: `right` is a deprecated alias for `rawLua`." rawLua;
inherit rawLua elemType;
};
};
# Describes an boolean-like integer flag that is either 0 or 1
# Has legacy support for boolean definitions, added 2024-09-08
intFlag =
with types;
deprecation.transitionType bool (v: if v then 1 else 0) (enum [
0
1
]);
border =
with types;
oneOf [
str
(listOf str)
(listOf (listOf str))
];
logLevel = types.enum [
"off"
"error"
"warn"
"info"
"debug"
"trace"
];
highlight = types.submodule {
# Adds flexibility for other keys
freeformType = types.attrs;
# :help nvim_set_hl()
options = with types; {
fg = mkNullOrStr "Color for the foreground (color name or '#RRGGBB').";
bg = mkNullOrStr "Color for the background (color name or '#RRGGBB').";
sp = mkNullOrStr "Special color (color name or '#RRGGBB').";
blend = mkNullOrOption (numbers.between 0 100) "Integer between 0 and 100.";
bold = mkNullOrOption bool "";
standout = mkNullOrOption bool "";
underline = mkNullOrOption bool "";
undercurl = mkNullOrOption bool "";
underdouble = mkNullOrOption bool "";
underdotted = mkNullOrOption bool "";
underdashed = mkNullOrOption bool "";
strikethrough = mkNullOrOption bool "";
italic = mkNullOrOption bool "";
reverse = mkNullOrOption bool "";
nocombine = mkNullOrOption bool "";
link = mkNullOrStr "Name of another highlight group to link to.";
default = mkNullOrOption bool "Don't override existing definition.";
ctermfg = mkNullOrStr "Sets foreground of cterm color.";
ctermbg = mkNullOrStr "Sets background of cterm color.";
cterm = mkNullOrOption (either str attrs) ''
cterm attribute map, like |highlight-args|.
If not set, cterm attributes will match those from the attribute map documented above.
'';
};
};
strLua = mkStrLuaType "lua code string";
strLuaFn = mkStrLuaType "lua function string";
# When building the documentation `either` is extended to return the nestedType's sub-options
# This type can be used to avoid infinite recursion when evaluating the docs
# TODO: consider deprecating this in favor of using `config.isDocs` in option declarations
eitherRecursive =
t1: t2:
types.either t1 t2
// {
getSubOptions = _: { };
};
listOfLen =
elemType: len:
types.addCheck (types.listOf elemType) (v: builtins.length v == len)
// {
description = "list of ${toString len} ${
types.optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType
}";
};
pluginLuaConfig = types.submodule (
{ config, ... }:
let
inherit (builtins) toString;
inherit (lib.nixvim.utils) mkBeforeSection mkAfterSection;
in
{
options = {
pre = lib.mkOption {
type = with types; nullOr lines;
default = null;
description = ''
Lua code inserted at the start of the plugin's configuration.
This is the same as using `lib.nixvim.utils.mkBeforeSection` when defining `content`.
'';
};
post = lib.mkOption {
type = with types; nullOr lines;
default = null;
description = ''
Lua code inserted at the end of the plugin's configuration.
This is the same as using `lib.nixvim.utils.mkAfterSection` when defining `content`.
'';
};
content = lib.mkOption {
type = types.lines;
default = "";
description = ''
Configuration of the plugin.
If `pre` and/or `post` are non-null, they will be merged using the order priorities
${toString (mkBeforeSection null).priority} and ${toString (mkBeforeSection null).priority}
respectively.
'';
};
};
config.content = lib.mkMerge (
lib.optional (config.pre != null) (mkBeforeSection config.pre)
++ lib.optional (config.post != null) (mkAfterSection config.post)
);
}
);
}