modules/performance: handle optional plugins when combining plugins

This commit is contained in:
Stanislav Asunkin 2024-07-14 16:10:58 +03:00 committed by traxys
parent f900dcd6aa
commit 27201addd7
2 changed files with 129 additions and 48 deletions

View file

@ -74,17 +74,45 @@ in
config = config =
let let
# Plugin normalization
normalize =
p:
let
defaultPlugin = {
plugin = null;
config = "";
optional = false;
};
in
defaultPlugin // (if p ? plugin then p else { plugin = p; });
normalizePluginList = plugins: map normalize plugins;
# Normalized plugin list
normalizedPlugins = normalizePluginList config.extraPlugins;
# Plugin list extended with dependencies # Plugin list extended with dependencies
allPlugins = allPlugins =
let let
pluginWithItsDeps = p: [ p ] ++ builtins.concatMap pluginWithItsDeps p.dependencies or [ ]; pluginWithItsDeps =
p: [ p ] ++ builtins.concatMap pluginWithItsDeps (normalizePluginList p.plugin.dependencies or [ ]);
in in
lib.unique (builtins.concatMap pluginWithItsDeps config.extraPlugins); lib.unique (builtins.concatMap pluginWithItsDeps normalizedPlugins);
# All plugins with doc tags removed # Separated start and opt plugins
allPluginsOverridden = map ( partitionedPlugins = builtins.partition (p: p.optional) allPlugins;
startPlugins = partitionedPlugins.wrong;
# Remove opt plugin dependencies since they are already available in start plugins
optPlugins = map (
p: p // { plugin = builtins.removeAttrs p.plugin [ "dependencies" ]; }
) partitionedPlugins.right;
# Combine start plugins into a single pack
pluginPack =
let
# Plugins with doc tags removed
overriddenPlugins = map (
plugin: plugin:
plugin.overrideAttrs (prev: { plugin.plugin.overrideAttrs (prev: {
nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ]; nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ];
configurePhase = builtins.concatStringsSep "\n" ( configurePhase = builtins.concatStringsSep "\n" (
builtins.filter (s: s != ":") [ builtins.filter (s: s != ":") [
@ -93,20 +121,19 @@ in
] ]
); );
}) })
) allPlugins; ) startPlugins;
# Python3 dependencies from all plugins # Python3 dependencies
python3Dependencies = python3Dependencies =
let let
deps = map (p: p.python3Dependencies or (_: [ ])) allPluginsOverrided; deps = map (p: p.plugin.python3Dependencies or (_: [ ])) startPlugins;
in in
ps: builtins.concatMap (f: f ps) deps; ps: builtins.concatMap (f: f ps) deps;
in
# Combine all plugins into a single pack pkgs.vimUtils.toVimPlugin (
pluginPack = pkgs.vimUtils.toVimPlugin (
pkgs.buildEnv { pkgs.buildEnv {
name = "plugin-pack"; name = "plugin-pack";
paths = allPluginsOverridden; paths = overriddenPlugins;
inherit (config.performance.combinePlugins) pathsToLink; inherit (config.performance.combinePlugins) pathsToLink;
# Remove empty directories and activate vimGenDocHook # Remove empty directories and activate vimGenDocHook
postBuild = '' postBuild = ''
@ -120,18 +147,10 @@ in
); );
# Combined plugins # Combined plugins
combinedPlugins = [ pluginPack ]; combinedPlugins = [ (normalize pluginPack) ] ++ optPlugins;
# Plugins to use in finalPackage # Plugins to use in finalPackage
plugins = if config.performance.combinePlugins.enable then combinedPlugins else config.extraPlugins; plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins;
defaultPlugin = {
plugin = null;
config = "";
optional = false;
};
normalizedPlugins = map (x: defaultPlugin // (if x ? plugin then x else { plugin = x; })) plugins;
neovimConfig = pkgs.neovimUtils.makeNeovimConfig ( neovimConfig = pkgs.neovimUtils.makeNeovimConfig (
{ {
@ -144,7 +163,7 @@ in
withNodeJs withNodeJs
; ;
# inherit customRC; # inherit customRC;
plugins = normalizedPlugins; inherit plugins;
} }
# Necessary to make sure the runtime path is set properly in NixOS 22.05, # Necessary to make sure the runtime path is set properly in NixOS 22.05,
# or more generally before the commit: # or more generally before the commit:
@ -152,7 +171,7 @@ in
// optionalAttrs (lib.functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) { // optionalAttrs (lib.functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) {
configure.packages = { configure.packages = {
nixvim = { nixvim = {
start = map (x: x.plugin) normalizedPlugins; start = map (x: x.plugin) plugins;
opt = [ ]; opt = [ ];
}; };
}; };

View file

@ -129,4 +129,66 @@
} }
]; ];
}; };
# Test that optional plugins are handled
optional-plugins.module =
{ config, ... }:
{
performance.combinePlugins.enable = true;
extraPlugins = with pkgs.vimPlugins; [
# Start plugins
plenary-nvim
nvim-lspconfig
# Optional plugin
{
plugin = nvim-treesitter;
optional = true;
}
# Optional plugin with dependency on plenary-nvim
# Dependencies should not be duplicated
{
plugin = telescope-nvim;
optional = true;
}
];
extraConfigLuaPost = ''
-- Start plugins are loadable
require("plenary")
require("lspconfig")
-- Opt plugins are not loadable
local ok = pcall(require, "nvim-treesitter")
assert(not ok, "nvim-treesitter plugin is loadable")
ok = pcall(require, "telescope")
assert(not ok, "telescope-nvim plugin is loadable")
-- Load plugins
vim.cmd.packadd("nvim-treesitter")
vim.cmd.packadd("telescope.nvim")
-- Now opt plugins are loadable
require("nvim-treesitter")
require("telescope")
-- Only one copy of plenary-nvim should be available
assert(
#vim.api.nvim_get_runtime_file("lua/plenary/init.lua", true) == 1,
"plenary-nvim is duplicated"
)
'';
assertions =
let
packages = config.finalPackage.packpathDirs.myNeovimPackages;
in
[
{
assertion = builtins.length packages.start == 1;
message = "More than one start plugin is defined in packpathDirs";
}
{
assertion = builtins.length packages.opt == 2;
message = "Less than two opt plugins are defined in packpathDirs";
}
];
};
} }