modules/performance: add combinePlugins.standalonePlugins option

This commit is contained in:
Stanislav Asunkin 2024-07-19 16:31:12 +03:00 committed by traxys
parent d6bebcefa3
commit e65c9590d0
3 changed files with 94 additions and 8 deletions

View file

@ -10,7 +10,8 @@ in
Whether to enable EXPERIMENTAL option to combine all plugins Whether to enable EXPERIMENTAL option to combine all plugins
into a single plugin pack. It can significantly reduce startup time, into a single plugin pack. It can significantly reduce startup time,
but all your plugins must have unique filenames and doc tags. but all your plugins must have unique filenames and doc tags.
Any collision will result in a build failure. Any collision will result in a build failure. To avoid collisions
you can add your plugin to the `standalonePlugins` option.
Only standard neovim runtime directories are linked to the combined plugin. Only standard neovim runtime directories are linked to the combined plugin.
If some of your plugins contain important files outside of standard If some of your plugins contain important files outside of standard
directories, add these paths to `pathsToLink` option. directories, add these paths to `pathsToLink` option.
@ -22,6 +23,12 @@ in
example = [ "/data" ]; example = [ "/data" ];
description = "List of paths to link into a combined plugin pack."; description = "List of paths to link into a combined plugin pack.";
}; };
standalonePlugins = lib.mkOption {
type = with types; listOf (either str package);
default = [ ];
example = [ "nvim-treesitter" ];
description = "List of plugins (names or packages) to exclude from plugin pack.";
};
}; };
}; };

View file

@ -98,13 +98,26 @@ in
in in
lib.unique (builtins.concatMap pluginWithItsDeps normalizedPlugins); lib.unique (builtins.concatMap pluginWithItsDeps normalizedPlugins);
# Remove dependencies from all plugins in a list
removeDependencies = ps: map (p: p // { plugin = removeAttrs p.plugin [ "dependencies" ]; }) ps;
# Separated start and opt plugins # Separated start and opt plugins
partitionedPlugins = builtins.partition (p: p.optional) allPlugins; partitionedPlugins = builtins.partition (p: p.optional) allPlugins;
startPlugins = partitionedPlugins.wrong; startPlugins = partitionedPlugins.wrong;
# Remove opt plugin dependencies since they are already available in start plugins # Remove opt plugin dependencies since they are already available in start plugins
optPlugins = map ( optPlugins = removeDependencies partitionedPlugins.right;
p: p // { plugin = builtins.removeAttrs p.plugin [ "dependencies" ]; }
) partitionedPlugins.right; # Test if plugin shouldn't be included in plugin pack
isStandalone =
p:
builtins.elem p.plugin config.performance.combinePlugins.standalonePlugins
|| builtins.elem (lib.getName p.plugin) config.performance.combinePlugins.standalonePlugins;
# Separated standalone and combined start plugins
partitionedStartPlugins = builtins.partition isStandalone startPlugins;
toCombinePlugins = partitionedStartPlugins.wrong;
# Remove standalone plugin dependencies since they are already available in start plugins
standaloneStartPlugins = removeDependencies partitionedStartPlugins.right;
# Combine start plugins into a single pack # Combine start plugins into a single pack
pluginPack = pluginPack =
@ -121,12 +134,12 @@ in
] ]
); );
}) })
) startPlugins; ) toCombinePlugins;
# Python3 dependencies # Python3 dependencies
python3Dependencies = python3Dependencies =
let let
deps = map (p: p.plugin.python3Dependencies or (_: [ ])) startPlugins; deps = map (p: p.plugin.python3Dependencies or (_: [ ])) toCombinePlugins;
in in
ps: builtins.concatMap (f: f ps) deps; ps: builtins.concatMap (f: f ps) deps;
@ -149,7 +162,7 @@ in
# Combined plugin configs # Combined plugin configs
combinedConfig = builtins.concatStringsSep "\n" ( combinedConfig = builtins.concatStringsSep "\n" (
builtins.concatMap (x: lib.optional (x.config != null && x.config != "") x.config) startPlugins builtins.concatMap (x: lib.optional (x.config != null && x.config != "") x.config) toCombinePlugins
); );
in in
normalize { normalize {
@ -158,7 +171,7 @@ in
}; };
# Combined plugins # Combined plugins
combinedPlugins = [ pluginPack ] ++ optPlugins; combinedPlugins = [ pluginPack ] ++ standaloneStartPlugins ++ optPlugins;
# Plugins to use in finalPackage # Plugins to use in finalPackage
plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins; plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins;

View file

@ -233,4 +233,70 @@ in
} }
]; ];
}; };
# Test that standalonePlugins option works
standalone-plugins.module =
{ config, ... }:
{
performance.combinePlugins = {
enable = true;
standalonePlugins = with pkgs.vimPlugins; [
# By plugin name
"nvim-treesitter"
# By package itself
nvim-lspconfig
# Its dependency, plenary-nvim, not in this list, so will be combined
telescope-nvim
# Dependency of other plugin
"nvim-cmp"
];
};
extraPlugins = with pkgs.vimPlugins; [
nvim-treesitter
nvim-lspconfig
telescope-nvim
# Only its dependency (nvim-cmp) won't be combined, but not the plugin itself
cmp-dictionary
# More plugins
gitsigns-nvim
luasnip
];
extraConfigLuaPost = ''
-- Plugins are loadable
require("nvim-treesitter")
require("lspconfig")
require("telescope")
require("plenary")
require("cmp_dictionary")
require("cmp")
require("gitsigns")
require("luasnip")
-- Verify if plugin is standalone or combined
local function is_standalone(name, dirname)
local paths = vim.api.nvim_get_runtime_file("lua/" .. name, true);
assert(#paths == 1, "more than one copy of " .. name .. " in runtime")
return paths[1]:match("^(.+)/lua/"):find(dirname or name, 1, true) ~= nil
end
-- Standalone plugins
assert(is_standalone("nvim-treesitter"), "nvim-treesitter is combined, expected standalone")
assert(is_standalone("lspconfig"), "nvim-lspconfig is combined, expected standalone")
assert(is_standalone("telescope"), "telescope-nvim is combined, expected standalone")
-- Add trailing slash to ensure that it doesn't match cmp_dictionary
assert(is_standalone("cmp/", "nvim-cmp"), "nvim-cmp is combined, expected standalone")
-- Combined plugins
assert(not is_standalone("plenary"), "plenary-nvim is standalone, expected combined")
assert(not is_standalone("cmp_dictionary", "cmp-dictionary"), "cmp-dictionary is standalone, expected combined")
assert(not is_standalone("gitsigns"), "gitsigns-nvim is standalone, expected combined")
assert(not is_standalone("luasnip"), "luasnip is standalone, expected combined")
'';
assertions = [
{
# plugin-pack, nvim-treesitter, nvim-lspconfig, telescope-nvim, nvim-cmp
assertion = pluginCount config.finalPackage "start" == 5;
message = "Wrong number of plugins in packpathDirs";
}
];
};
} }