yazi: Assert plugin/flavor structure and warn about plugin/flavor suffix

- Always append suffix `.yazi` to plugin's and flavor's attribute names.
- Warn if the attribute names already have the suffix.
- Assert that plugin's and flavor's values point to directories
  containing an `init.lua` file.
This commit is contained in:
lordkekz 2024-06-05 21:24:18 +02:00 committed by Robert Helgesson
parent 09bc5c5949
commit 16f86c94ce
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
3 changed files with 66 additions and 43 deletions

View file

@ -144,7 +144,9 @@ in {
type = with types; attrsOf (oneOf [ path package ]); type = with types; attrsOf (oneOf [ path package ]);
default = { }; default = { };
description = '' description = ''
Lua plugins. Will be linked into {file}`$XDG_CONFIG_HOME/yazi/plugins/`. Lua plugins.
Values should be a package or path containing an `init.lua` file.
Will be linked to {file}`$XDG_CONFIG_HOME/yazi/plugins/<name>.yazi`.
See <https://yazi-rs.github.io/docs/plugins/overview> See <https://yazi-rs.github.io/docs/plugins/overview>
for documentation. for documentation.
@ -162,6 +164,8 @@ in {
default = { }; default = { };
description = '' description = ''
Pre-made themes. Pre-made themes.
Values should be a package or path containing an `init.lua` file.
Will be linked to {file}`$XDG_CONFIG_HOME/yazi/flavors/<name>.yazi`.
See <https://yazi-rs.github.io/docs/flavors/overview/> for documentation. See <https://yazi-rs.github.io/docs/flavors/overview/> for documentation.
''; '';
@ -198,42 +202,52 @@ in {
source = tomlFormat.generate "yazi-theme" cfg.theme; source = tomlFormat.generate "yazi-theme" cfg.theme;
}; };
"yazi/init.lua" = mkIf (cfg.initLua != null) { source = cfg.initLua; }; "yazi/init.lua" = mkIf (cfg.initLua != null) { source = cfg.initLua; };
} // (mapAttrs' } // (mapAttrs' (name: value:
(name: value: nameValuePair "yazi/flavors/${name}" { source = value; }) nameValuePair "yazi/flavors/${name}.yazi" { source = value; })
cfg.flavors) // (let cfg.flavors) // (mapAttrs' (name: value:
# Make sure that the directory ends in `.yazi`, to comply with specification. nameValuePair "yazi/plugins/${name}.yazi" { source = value; })
# `pluginName` is essential, it's needed to apply config in yazi's `init.lua` cfg.plugins);
ensureSuffix = pluginName:
if lib.hasSuffix ".yazi" pluginName then
"yazi/plugins/${pluginName}"
else
"yazi/plugins/${pluginName}.yazi";
mkPluginLink = pluginName: pluginPackageOrPath: { warnings = filter (s: s != "") (concatLists [
name = ensureSuffix pluginName; (mapAttrsToList (name: value:
value.source = pluginPackageOrPath; optionalString (hasSuffix ".yazi" name) ''
}; Flavors like `programs.yazi.flavors."${name}"` should no longer have the suffix ".yazi" in their attribute name.
The flavor will be linked to `$XDG_CONFIG_HOME/yazi/flavors/${name}.yazi`.
You probably want to rename it to `programs.yazi.flavors."${
removeSuffix ".yazi" name
}"`.
'') cfg.flavors)
(mapAttrsToList (name: value:
optionalString (hasSuffix ".yazi" name) ''
Plugins like `programs.yazi.plugins."${name}"` should no longer have the suffix ".yazi" in their attribute name.
The plugin will be linked to `$XDG_CONFIG_HOME/yazi/plugins/${name}.yazi`.
You probably want to rename it to `programs.yazi.plugins."${
removeSuffix ".yazi" name
}"`.
'') cfg.plugins)
]);
pluginLinks = mapAttrs' mkPluginLink cfg.plugins; assertions = let
in pluginLinks); mkAsserts = opt:
mapAttrsToList (name: value:
assertions = (mapAttrsToList (pluginName: pluginPackageOrPath: let
let isDir = pathIsDirectory "${value}";
isDir = pathIsDirectory "${pluginPackageOrPath}"; msgNotDir = optionalString (!isDir)
hasInitLua = pathExists "${pluginPackageOrPath}/init.lua" "The path or package should be a directory, not a single file.";
&& !(pathIsDirectory "${pluginPackageOrPath}/init.lua"); hasInitLua = pathExists "${value}/init.lua"
in { && !(pathIsDirectory "${value}/init.lua");
assertion = isDir && hasInitLua; msgNoInitLua = optionalString (!hasInitLua)
message = "The path or package must contain a file `init.lua`.";
"Value at `programs.yazi.plugins.${pluginName}` is not a valid yazi plugin." singularOpt = removeSuffix "s" opt;
+ (optionalString (!isDir) '' in {
assertion = isDir && hasInitLua;
The path or package should be a directory, not a single file.'') message = ''
+ (optionalString (!hasInitLua) '' Value at `programs.yazi.${opt}.${name}` is not a valid yazi ${singularOpt}.
${msgNotDir}
The path or package must contain a file `init.lua`.'') + '' ${msgNoInitLua}
Evaluated value: `${value}`
Evaluated value: `${pluginPackageOrPath}`''; '';
}) cfg.plugins); }) cfg.${opt};
in (mkAsserts "flavors") ++ (mkAsserts "plugins");
}; };
} }

View file

@ -71,10 +71,21 @@
}; };
initLua = ./init.lua; initLua = ./init.lua;
plugins = { plugins = {
"test" = ./plugin; testplugin = ./plugin;
"another-test" = ./plugin; ## Produces warning
#"plugin-with-suffix.yazi" = ./plugin;
## Fails assertion
#single-file-plugin = ./plugin/init.lua;
#empty-dir-plugin = ./empty;
};
flavors = {
testflavor = ./flavor;
## Produces warning
#"flavor-with-suffix.yazi" = ./flavor;
## Fails assertion
#single-file-flavor = ./flavor/init.lua;
#empty-dir-flavor = ./empty;
}; };
flavors = { "test.yazi" = ./flavor; };
}; };
test.stubs.yazi = { }; test.stubs.yazi = { };
@ -88,11 +99,9 @@
${./theme-expected.toml} ${./theme-expected.toml}
assertFileContent home-files/.config/yazi/init.lua \ assertFileContent home-files/.config/yazi/init.lua \
${./init.lua} ${./init.lua}
assertFileContent home-files/.config/yazi/plugins/test.yazi/init.lua \ assertFileContent home-files/.config/yazi/plugins/testplugin.yazi/init.lua \
${./plugin/init.lua} ${./plugin/init.lua}
assertFileContent home-files/.config/yazi/plugins/anotherTest.yazi/init.lua \ assertFileContent home-files/.config/yazi/flavors/testflavor.yazi/init.lua \
${./plugin/init.lua}
assertFileContent home-files/.config/yazi/flavors/test.yazi/init.lua \
${./flavor/init.lua} ${./flavor/init.lua}
''; '';
} }