modules/performance: add ability to byte-compile plugin lua dependencies

This commit adds byte compiling of plugin lua dependencies
(specifically propagatedBuildInputs). It's enabled by
`performance.byteCompileLua.luaLib` option.
This commit is contained in:
Stanislav Asunkin 2025-05-09 11:48:06 +03:00
parent 404e56066f
commit 2c6182351f
4 changed files with 108 additions and 1 deletions

View file

@ -0,0 +1,28 @@
/*
Byte compiling of lua dependencies of normalized plugin list
Inputs: List of normalized plugins
Outputs: List of normalized plugins with all the propagatedBuildInputs byte-compiled
*/
{ lib, pkgs }:
let
builders = lib.nixvim.builders.withPkgs pkgs;
inherit (import ./utils.nix lib) mapNormalizedPlugins;
# Byte-compile only lua dependencies
byteCompileDeps =
drv:
drv.overrideAttrs (
prev:
lib.optionalAttrs (prev ? propagatedBuildInputs) {
propagatedBuildInputs = map byteCompile prev.propagatedBuildInputs;
}
);
# Byte-compile derivation (but only if it's a lua module) and its dependencies
byteCompile =
drv:
byteCompileDeps (
if pkgs.luaPackages.luaLib.hasLuaModule drv then builders.byteCompileLuaDrv drv else drv
);
in
mapNormalizedPlugins byteCompileDeps

View file

@ -34,6 +34,9 @@ in
shouldCompilePlugins = byteCompileCfg.enable && byteCompileCfg.plugins;
byteCompilePlugins = import ./byte-compile-plugins.nix { inherit lib pkgs; };
shouldCompileLuaLib = byteCompileCfg.enable && byteCompileCfg.luaLib;
byteCompileLuaLib = import ./byte-compile-lua-lib.nix { inherit lib pkgs; };
shouldCombinePlugins = config.performance.combinePlugins.enable;
combinePlugins = import ./combine-plugins.nix {
inherit lib pkgs;
@ -47,6 +50,7 @@ in
lib.pipe config.extraPlugins (
[ normalizePlugins ]
++ lib.optionals shouldCompilePlugins [ byteCompilePlugins ]
++ lib.optionals shouldCompileLuaLib [ byteCompileLuaLib ]
++ lib.optionals shouldCombinePlugins [ combinePlugins ]
);
};

View file

@ -35,4 +35,7 @@ lib.fix (self: {
# Remove dependencies from all plugins in a list
removeDeps = map (p: p // { plugin = removeAttrs p.plugin [ "dependencies" ]; });
# Apply a map function to each 'plugin' attr of the normalized plugin list
mapNormalizedPlugins = f: map (p: p // { plugin = f p.plugin; });
})

View file

@ -299,7 +299,8 @@ in
'';
};
lua-lib = {
# performance.byteCompileLua.luaLib for extraLuaPackages
lua-lib-extra-lua-packages = {
performance.byteCompileLua = {
enable = true;
luaLib = true;
@ -321,6 +322,77 @@ in
test_lualib_file(argparse("test").parse, true)
'';
};
# performance.byteCompileLua.luaLib for propagatedBuildInputs
lua-lib-propagated-build-inputs =
{
config,
lib,
pkgs,
...
}:
{
performance.byteCompileLua = {
enable = true;
luaLib = true;
};
extraPlugins =
let
inherit (config.package) lua;
setDeps =
drv: deps:
# 'toLuaModule' is used here for updating 'requiredLuaModules' attr
lua.pkgs.luaLib.toLuaModule (
drv.overrideAttrs {
propagatedBuildInputs = [ lua ] ++ deps;
}
);
# Add the 'argparse' dependency to the 'say' module
say = setDeps lua.pkgs.say [ lua.pkgs.argparse ];
in
[
# 'lz-n' depends on 'say' which itself depends on 'argparse'
(setDeps pkgs.vimPlugins.lz-n [ say ])
# 'nvim-cmp' depends on 'argparse'
(setDeps pkgs.vimPlugins.nvim-cmp [ lua.pkgs.argparse ])
];
extraConfigLuaPost = ''
${isByteCompiledFun}
-- Plugins themselves are importable
require("lz.n")
require("cmp")
-- Lua modules are importable and byte compiled
local say = require("say")
test_lualib_file(say.set, true)
local argparse = require("argparse")
test_lualib_file(argparse("test").parse, true)
'';
assertions =
let
requiredLuaModules = lib.pipe config.extraPlugins [
(builtins.catAttrs "requiredLuaModules")
builtins.concatLists
lib.unique
];
in
[
# Ensure that propagatedBuildInputs are byte-compiled recursively
# by checking that every library is present only once
{
assertion = lib.allUnique (map lib.getName requiredLuaModules);
message = ''
Expected requiredLuaModules of all propagatedBuildInputs to have unique names.
Got the following derivations: ${builtins.concatStringsSep ", " requiredLuaModules}.
One possible reason is that not all dependencies are overridden the same way.
'';
}
];
};
}
//
# Two equal tests, one with combinePlugins.enable = true