mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-21 16:39:00 +02:00
Extracted the `optionsRenamedToSettings` implementation from`mkVimPlugin` and `mkNeovimPlugin` into a new public helper.
95 lines
3.1 KiB
Nix
95 lines
3.1 KiB
Nix
{ lib }:
|
||
with lib;
|
||
rec {
|
||
# Get a (sub)option by walking the path,
|
||
# checking for submodules along the way
|
||
getOptionRecursive =
|
||
opt: prefix: optionPath:
|
||
if optionPath == [ ] then
|
||
opt
|
||
else if isOption opt then
|
||
getOptionRecursive (opt.type.getSubOptions prefix) prefix optionPath
|
||
else
|
||
let
|
||
name = head optionPath;
|
||
opt' = getAttr name opt;
|
||
prefix' = prefix ++ [ name ];
|
||
optionPath' = drop 1 optionPath;
|
||
in
|
||
getOptionRecursive opt' prefix' optionPath';
|
||
|
||
# Like mkRemovedOptionModule, but has support for nested sub-options
|
||
# and uses warnings instead of assertions.
|
||
mkDeprecatedSubOptionModule =
|
||
optionPath: replacementInstructions:
|
||
{ options, ... }:
|
||
{
|
||
options = setAttrByPath optionPath (mkOption {
|
||
# When (e.g.) `mkAttrs` is used on a submodule, this option will be evaluated.
|
||
# Therefore we have to apply _something_ (null) when there's no definition.
|
||
apply =
|
||
v:
|
||
let
|
||
# Avoid "option used but not defined" errors
|
||
res = builtins.tryEval v;
|
||
in
|
||
if res.success then res.value else null;
|
||
visible = false;
|
||
});
|
||
config.warnings =
|
||
let
|
||
opt = getOptionRecursive options [ ] optionPath;
|
||
in
|
||
optional opt.isDefined ''
|
||
The option definition `${showOption optionPath}' in ${showFiles opt.files} is deprecated.
|
||
${replacementInstructions}
|
||
'';
|
||
};
|
||
|
||
mkSettingsRenamedOptionModules =
|
||
oldPrefix: newPrefix:
|
||
map (
|
||
option':
|
||
let
|
||
option = toList option';
|
||
oldPath = oldPrefix ++ option;
|
||
newPath = newPrefix ++ map nixvim.toSnakeCase option;
|
||
in
|
||
mkRenamedOptionModule oldPath newPath
|
||
);
|
||
|
||
# A clone of types.coercedTo, but it prints a warning when oldType is used.
|
||
transitionType =
|
||
oldType: coerceFn: newType:
|
||
assert lib.assertMsg (
|
||
oldType.getSubModules == null
|
||
) "transitionType: oldType must not have submodules (it’s a ${oldType.description})";
|
||
lib.mkOptionType rec {
|
||
name = "transitionType";
|
||
inherit (newType) description;
|
||
check = x: (oldType.check x && newType.check (coerceFn x)) || newType.check x;
|
||
merge =
|
||
opt: defs:
|
||
let
|
||
coerceVal =
|
||
val:
|
||
if oldType.check val then
|
||
lib.warn ''
|
||
Passing a ${oldType.description} for `${lib.showOption opt}' is deprecated, use ${newType.description} instead. Definitions: ${lib.options.showDefs defs}
|
||
'' (coerceFn val)
|
||
else
|
||
val;
|
||
in
|
||
newType.merge opt (map (def: def // { value = coerceVal def.value; }) defs);
|
||
inherit (newType) emptyValue;
|
||
inherit (newType) getSubOptions;
|
||
inherit (newType) getSubModules;
|
||
substSubModules = m: transitionType oldType coerceFn (newType.substSubModules m);
|
||
typeMerge = t1: t2: null;
|
||
functor = (lib.types.defaultFunctor name) // {
|
||
wrapped = newType;
|
||
};
|
||
nestedTypes.coercedType = oldType;
|
||
nestedTypes.finalType = newType;
|
||
};
|
||
}
|