nix-community.nixvim/lib/helpers.nix

295 lines
7.7 KiB
Nix
Raw Normal View History

{lib, ...}:
with lib; rec {
keymaps = import ./keymap-helpers.nix {inherit lib;};
autocmd = import ./autocmd-helpers.nix {inherit lib;};
# vim dictionaries are, in theory, compatible with JSON
toVimDict = args:
toJSON
(lib.filterAttrs (n: v: v != null) args);
# Black functional magic that converts a bunch of different Nix types to their
# lua equivalents!
toLuaObject = args:
if builtins.isAttrs args
then
if hasAttr "__raw" args
then args.__raw
else if hasAttr "__empty" args
then "{ }"
else
"{"
+ (concatStringsSep ","
(mapAttrsToList
(n: v:
if (builtins.match "__unkeyed.*" n) != null
then toLuaObject v
else if n == "__emptyString"
then "[''] = " + (toLuaObject v)
else "[${toLuaObject n}] = " + (toLuaObject v))
(filterAttrs
(
n: v:
v != null && (toLuaObject v != "{}")
)
args)))
+ "}"
else if builtins.isList args
then "{" + concatMapStringsSep "," toLuaObject args + "}"
else if builtins.isString args
then
# This should be enough!
builtins.toJSON args
else if builtins.isPath args
then builtins.toJSON (toString args)
else if builtins.isBool args
then "${boolToString args}"
else if builtins.isFloat args
then "${toString args}"
else if builtins.isInt args
then "${toString args}"
else if (args == null)
then "nil"
else "";
2023-10-15 17:31:03 +02:00
listToUnkeyedAttrs = list:
builtins.listToAttrs
(lib.lists.imap0 (idx: lib.nameValuePair "__unkeyed-${toString idx}") list);
emptyTable = {"__empty" = null;};
highlightType = with lib.types;
submodule {
# Adds flexibility for other keys
freeformType = types.attrs;
# :help nvim_set_hl()
options = {
fg = mkNullOrOption str "Color for the foreground (color name or '#RRGGBB').";
bg = mkNullOrOption str "Color for the background (color name or '#RRGGBB').";
sp = mkNullOrOption str "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 = mkNullOrOption str "Name of another highlight group to link to.";
default = mkNullOrOption bool "Don't override existing definition.";
ctermfg = mkNullOrOption str "Sets foreground of cterm color.";
ctermbg = mkNullOrOption str "Sets background of cterm color.";
cterm = mkNullOrOption attrs ''
cterm attribute map, like |highlight-args|.
If not set, cterm attributes will match those from the attribute map documented above.
'';
2023-09-10 09:59:22 +02:00
};
};
2023-11-06 10:49:38 +01:00
borderType = with lib.types;
oneOf [
str
(listOf str)
(listOf (listOf str))
];
# Creates an option with a nullable type that defaults to null.
mkNullOrOption = type: desc:
lib.mkOption {
type = lib.types.nullOr type;
default = null;
description = desc;
};
mkIfNonNull' = x: y: (mkIf (x != null) y);
mkIfNonNull = x: (mkIfNonNull' x x);
ifNonNull' = x: y:
if (x == null)
then null
else y;
mkCompositeOption = desc: options:
mkNullOrOption (types.submodule {inherit options;}) desc;
2023-03-06 23:45:38 +01:00
defaultNullOpts = rec {
mkNullable = type: default: desc:
mkNullOrOption type (
let
defaultDesc = "default: `${default}`";
in
if desc == ""
then defaultDesc
else ''
${desc}
${defaultDesc}
''
);
mkNum = default: mkNullable lib.types.number (toString default);
mkInt = default: mkNullable lib.types.int (toString default);
# Positive: >0
mkPositiveInt = default: mkNullable lib.types.ints.positive (toString default);
# Unsigned: >=0
mkUnsignedInt = default: mkNullable lib.types.ints.unsigned (toString default);
mkBool = default:
mkNullable lib.types.bool (
if default
then "true"
else "false"
);
mkStr = default: mkNullable lib.types.str ''${builtins.toString default}'';
mkAttributeSet = default: mkNullable lib.types.attrs ''${default}'';
mkEnum = enum: default: mkNullable (lib.types.enum enum) ''"${default}"'';
mkEnumFirstDefault = enum: mkEnum enum (head enum);
mkBorder = default: name: desc:
mkNullable
2023-11-06 10:49:38 +01:00
borderType
default
(let
defaultDesc = ''
Defines the border to use for ${name}.
Accepts same border values as `nvim_open_win()`. See `:help nvim_open_win()` for more info.
'';
in
if desc == ""
then defaultDesc
else ''
${desc}
${defaultDesc}
'');
mkHighlight = default: name: desc:
mkNullable
highlightType
default
(
if desc == ""
then "Highlight settings."
else desc
);
};
mkPackageOption = name: default:
mkOption {
type = types.package;
inherit default;
description = "Plugin to use for ${name}";
};
2023-09-10 09:59:22 +02:00
mkPlugin = {
config,
lib,
...
}: {
name,
description,
package ? null,
extraPlugins ? [],
extraPackages ? [],
options ? {},
globalPrefix ? "",
...
}: let
cfg = config.plugins.${name};
# TODO support nested options!
pluginOptions = mapAttrs (k: v: v.option) options;
globals =
mapAttrs'
(name: opt: {
name = globalPrefix + opt.global;
value =
if cfg.${name} != null
then opt.value cfg.${name}
else null;
})
options;
# does this evaluate package?
packageOption =
if package == null
then {}
else {
package = mkPackageOption name package;
2023-09-10 09:59:22 +02:00
};
in {
options.plugins.${name} =
{
enable = mkEnableOption description;
}
// packageOption
// pluginOptions;
config = mkIf cfg.enable {
inherit extraPackages globals;
# does this evaluate package? it would not be desired to evaluate pacakge if we use another package.
extraPlugins = extraPlugins ++ optional (package != null) cfg.package;
};
};
globalVal = val:
if builtins.isBool val
then
(
if !val
then 0
else 1
)
else val;
mkDefaultOpt = {
type,
global,
description ? null,
example ? null,
default ? null,
value ? v: (globalVal v),
...
}: {
option = mkOption {
type = types.nullOr type;
inherit default description example;
2023-09-10 09:59:22 +02:00
};
inherit value global;
};
extraOptionsOptions = {
extraOptions = mkOption {
default = {};
type = types.attrs;
description = ''
These attributes will be added to the table parameter for the setup function.
(Can override other attributes set by nixvim)
'';
};
};
mkRaw = r:
if (isString r && (r != ""))
then {__raw = r;}
else null;
wrapDo = string: ''
do
${string}
end
'';
rawType = mkOptionType {
name = "rawType";
description = "raw lua code";
descriptionClass = "noun";
merge = mergeEqualOption;
check = isRawType;
};
isRawType = v: lib.isAttrs v && lib.hasAttr "__raw" v && lib.isString v.__raw;
}