From 325834721ce34b1e71ef363bb3577382971be8fd Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Sun, 7 Jul 2024 18:50:30 +0300 Subject: [PATCH 01/13] modules/output: avoid using global `with lib;` --- modules/top-level/output.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index bd62d2174f..c227c66782 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -5,7 +5,10 @@ helpers, ... }: -with lib; +let + inherit (lib) types mkOption; + inherit (lib) optional optionalString optionalAttrs; +in { options = { viAlias = mkOption { @@ -97,7 +100,7 @@ with lib; # Necessary to make sure the runtime path is set properly in NixOS 22.05, # or more generally before the commit: # cda1f8ae468 - neovim: pass packpath via the wrapper - // optionalAttrs (functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) { + // optionalAttrs (lib.functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) { configure.packages = { nixvim = { start = map (x: x.plugin) normalizedPlugins; @@ -115,7 +118,9 @@ with lib; init = helpers.writeLua "init.lua" customRC; extraWrapperArgs = builtins.concatStringsSep " " ( - (optional (config.extraPackages != [ ]) ''--prefix PATH : "${makeBinPath config.extraPackages}"'') + (optional ( + config.extraPackages != [ ] + ) ''--prefix PATH : "${lib.makeBinPath config.extraPackages}"'') ++ (optional config.wrapRc ''--add-flags -u --add-flags "${init}"'') ); From 388c522fcafd4131c004ccd2f5a36290c79dc1fc Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Sun, 7 Jul 2024 20:22:39 +0300 Subject: [PATCH 02/13] modules/performance: add an option to combine plugins to a single plugin pack --- modules/default.nix | 1 + modules/performance.nix | 54 +++++++++ modules/top-level/output.nix | 45 +++++++- .../modules/performance/combine-plugins.nix | 105 ++++++++++++++++++ 4 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 modules/performance.nix create mode 100644 tests/test-sources/modules/performance/combine-plugins.nix diff --git a/modules/default.nix b/modules/default.nix index 7b2c2c18b1..739a30db84 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -19,6 +19,7 @@ ./lua-loader.nix ./opts.nix ./output.nix + ./performance.nix ./plugins.nix ]; } diff --git a/modules/performance.nix b/modules/performance.nix new file mode 100644 index 0000000000..9709b3f0df --- /dev/null +++ b/modules/performance.nix @@ -0,0 +1,54 @@ +{ lib, ... }: +let + inherit (lib) types; +in +{ + options.performance = { + combinePlugins = { + enable = lib.mkEnableOption "combinePlugins" // { + description = '' + Whether to enable EXPERIMENTAL option to combine all plugins + into a single plugin pack. It can significantly reduce startup time, + but all your plugins must have unique filenames and doc tags. + Any collision will result in a build failure. + Only standard neovim runtime directories are linked to the combined plugin. + If some of your plugins contain important files outside of standard + directories, add these paths to `pathsToLink` option. + ''; + }; + pathsToLink = lib.mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "/data" ]; + description = "List of paths to link into a combined plugin pack."; + }; + }; + }; + + config.performance = { + # Set option value with default priority so that values are appended by default + combinePlugins.pathsToLink = [ + # :h rtp + "/autoload" + "/colors" + "/compiler" + "/doc" + "/ftplugin" + "/indent" + "/keymap" + "/lang" + "/lua" + "/pack" + "/parser" + "/plugin" + "/queries" + "/rplugin" + "/spell" + "/syntax" + "/tutor" + "/after" + # ftdetect + "/ftdetect" + ]; + }; +} diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index c227c66782..06b8d90b97 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -74,15 +74,54 @@ in config = let + # Plugin list extended with dependencies + allPlugins = + let + pluginWithItsDeps = p: [ p ] ++ builtins.concatMap pluginWithItsDeps p.dependencies or [ ]; + in + lib.unique (builtins.concatMap pluginWithItsDeps config.extraPlugins); + + # All plugins with doc tags removed + allPluginsOverridden = map ( + plugin: + plugin.overrideAttrs (prev: { + nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ]; + configurePhase = builtins.concatStringsSep "\n" ( + builtins.filter (s: s != ":") [ + prev.configurePhase or ":" + "rm -vf doc/tags" + ] + ); + }) + ) allPlugins; + + # Combine all plugins into a single pack + pluginPack = pkgs.vimUtils.toVimPlugin ( + pkgs.buildEnv { + name = "plugin-pack"; + paths = allPluginsOverridden; + inherit (config.performance.combinePlugins) pathsToLink; + # Remove empty directories and activate vimGenDocHook + postBuild = '' + find $out -type d -empty -delete + runHook preFixup + ''; + } + ); + + # Combined plugins + combinedPlugins = [ pluginPack ]; + + # Plugins to use in finalPackage + plugins = if config.performance.combinePlugins.enable then combinedPlugins else config.extraPlugins; + defaultPlugin = { plugin = null; config = ""; optional = false; }; - normalizedPlugins = map ( - x: defaultPlugin // (if x ? plugin then x else { plugin = x; }) - ) config.extraPlugins; + normalizedPlugins = map (x: defaultPlugin // (if x ? plugin then x else { plugin = x; })) plugins; neovimConfig = pkgs.neovimUtils.makeNeovimConfig ( { diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix new file mode 100644 index 0000000000..8a084923c4 --- /dev/null +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -0,0 +1,105 @@ +{ pkgs, ... }: +{ + # Test basic functionality + default.module = + { config, ... }: + { + performance.combinePlugins.enable = true; + extraPlugins = with pkgs.vimPlugins; [ + nvim-lspconfig + nvim-treesitter + ]; + extraConfigLuaPost = '' + -- Plugins are loadable + require("lspconfig") + require("nvim-treesitter") + + -- No separate plugin entries in nvim_list_runtime_paths + assert(not vim.iter(vim.api.nvim_list_runtime_paths()):any(function(entry) + return entry:find("treesitter") or entry:find("lspconfig") + end), "separate plugins are found in runtime") + + -- Help tags are generated + assert(vim.fn.getcompletion("lspconfig", "help")[1], "no help tags for nvim-lspconfig") + assert(vim.fn.getcompletion("nvim-treesitter", "help")[1], "no help tags for nvim-treesitter") + ''; + assertions = [ + { + assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + message = "More than one plugin is defined in packpathDirs, expected one plugin pack."; + } + ]; + }; + + # Test disabled option + disabled.module = + { config, ... }: + { + performance.combinePlugins.enable = false; + extraPlugins = with pkgs.vimPlugins; [ + nvim-lspconfig + nvim-treesitter + ]; + assertions = [ + { + assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start >= 2; + message = "Only one plugin is defined in packpathDirs, expected at least two."; + } + ]; + }; + + # Test that plugin dependencies are handled + dependencies.module = + { config, ... }: + { + performance.combinePlugins.enable = true; + extraPlugins = with pkgs.vimPlugins; [ + # Depends on nvim-cmp + cmp-dictionary + # Depends on telescope-nvim which itself depends on plenary-nvim + telescope-undo-nvim + ]; + extraConfigLuaPost = '' + -- Plugins and its dependencies are loadable + require("cmp_dictionary") + require("cmp") + require("telescope-undo") + require("telescope") + require("plenary") + ''; + assertions = [ + { + assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + message = "More than one plugin is defined in packpathDirs."; + } + ]; + }; + + # Test that pathsToLink option works + paths-to-link.module = + { config, ... }: + { + performance.combinePlugins = { + enable = true; + # fzf native library is in build directory + pathsToLink = [ "/build" ]; + }; + extraPlugins = [ pkgs.vimPlugins.telescope-fzf-native-nvim ]; + extraConfigLuaPost = '' + -- Native library is in runtimepath + assert( + vim.api.nvim_get_runtime_file("build/libfzf.so", false)[1], + "build/libfzf.so is not found in runtimepath" + ) + + -- Native library is loadable + require("fzf_lib") + ''; + assertions = [ + { + assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + message = "More than one plugin is defined in packpathDirs."; + } + ]; + }; +} From e50320c04f51c5965d5f6bae0c4287452eed0363 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Sun, 14 Jul 2024 11:38:41 +0300 Subject: [PATCH 03/13] modules/performance: handle python3 dependencies when combining plugins --- modules/top-level/output.nix | 10 +++++++ .../modules/performance/combine-plugins.nix | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 06b8d90b97..93e0aed1b6 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -95,6 +95,13 @@ in }) ) allPlugins; + # Python3 dependencies from all plugins + python3Dependencies = + let + deps = map (p: p.python3Dependencies or (_: [ ])) allPluginsOverrided; + in + ps: builtins.concatMap (f: f ps) deps; + # Combine all plugins into a single pack pluginPack = pkgs.vimUtils.toVimPlugin ( pkgs.buildEnv { @@ -106,6 +113,9 @@ in find $out -type d -empty -delete runHook preFixup ''; + passthru = { + inherit python3Dependencies; + }; } ); diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index 8a084923c4..c9bec0d68c 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -102,4 +102,31 @@ } ]; }; + + # Test that plugin python3 dependencies are handled + python-dependencies.module = + { config, ... }: + { + performance.combinePlugins.enable = true; + extraPlugins = with pkgs.vimPlugins; [ + # No python3 dependencies + plenary-nvim + # Duplicate python3 dependencies + (nvim-lspconfig.overrideAttrs { passthru.python3Dependencies = ps: [ ps.pyyaml ]; }) + (nvim-treesitter.overrideAttrs { passthru.python3Dependencies = ps: [ ps.pyyaml ]; }) + # Another python3 dependency + (nvim-cmp.overrideAttrs { passthru.python3Dependencies = ps: [ ps.requests ]; }) + ]; + extraConfigLuaPost = '' + -- Python modules are importable + vim.cmd.py3("import yaml") + vim.cmd.py3("import requests") + ''; + assertions = [ + { + assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + message = "More than one plugin is defined in packpathDirs."; + } + ]; + }; } From 9129c9bbb88efdb3c5fe758e9e8c071bad93c1db Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:10:58 +0300 Subject: [PATCH 04/13] modules/performance: handle optional plugins when combining plugins --- modules/top-level/output.nix | 119 ++++++++++-------- .../modules/performance/combine-plugins.nix | 62 +++++++++ 2 files changed, 131 insertions(+), 50 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 93e0aed1b6..0e1bd0247c 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -74,64 +74,83 @@ in config = 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 allPlugins = let - pluginWithItsDeps = p: [ p ] ++ builtins.concatMap pluginWithItsDeps p.dependencies or [ ]; + pluginWithItsDeps = + p: [ p ] ++ builtins.concatMap pluginWithItsDeps (normalizePluginList p.plugin.dependencies or [ ]); in - lib.unique (builtins.concatMap pluginWithItsDeps config.extraPlugins); - - # All plugins with doc tags removed - allPluginsOverridden = map ( - plugin: - plugin.overrideAttrs (prev: { - nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ]; - configurePhase = builtins.concatStringsSep "\n" ( - builtins.filter (s: s != ":") [ - prev.configurePhase or ":" - "rm -vf doc/tags" - ] - ); - }) - ) allPlugins; - - # Python3 dependencies from all plugins - python3Dependencies = + lib.unique (builtins.concatMap pluginWithItsDeps normalizedPlugins); + + # Separated start and opt plugins + 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 - deps = map (p: p.python3Dependencies or (_: [ ])) allPluginsOverrided; + # Plugins with doc tags removed + overriddenPlugins = map ( + plugin: + plugin.plugin.overrideAttrs (prev: { + nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ]; + configurePhase = builtins.concatStringsSep "\n" ( + builtins.filter (s: s != ":") [ + prev.configurePhase or ":" + "rm -vf doc/tags" + ] + ); + }) + ) startPlugins; + + # Python3 dependencies + python3Dependencies = + let + deps = map (p: p.plugin.python3Dependencies or (_: [ ])) startPlugins; + in + ps: builtins.concatMap (f: f ps) deps; in - ps: builtins.concatMap (f: f ps) deps; - - # Combine all plugins into a single pack - pluginPack = pkgs.vimUtils.toVimPlugin ( - pkgs.buildEnv { - name = "plugin-pack"; - paths = allPluginsOverridden; - inherit (config.performance.combinePlugins) pathsToLink; - # Remove empty directories and activate vimGenDocHook - postBuild = '' - find $out -type d -empty -delete - runHook preFixup - ''; - passthru = { - inherit python3Dependencies; - }; - } - ); + pkgs.vimUtils.toVimPlugin ( + pkgs.buildEnv { + name = "plugin-pack"; + paths = overriddenPlugins; + inherit (config.performance.combinePlugins) pathsToLink; + # Remove empty directories and activate vimGenDocHook + postBuild = '' + find $out -type d -empty -delete + runHook preFixup + ''; + passthru = { + inherit python3Dependencies; + }; + } + ); # Combined plugins - combinedPlugins = [ pluginPack ]; + combinedPlugins = [ (normalize pluginPack) ] ++ optPlugins; # Plugins to use in finalPackage - plugins = if config.performance.combinePlugins.enable then combinedPlugins else config.extraPlugins; - - defaultPlugin = { - plugin = null; - config = ""; - optional = false; - }; - - normalizedPlugins = map (x: defaultPlugin // (if x ? plugin then x else { plugin = x; })) plugins; + plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins; neovimConfig = pkgs.neovimUtils.makeNeovimConfig ( { @@ -144,7 +163,7 @@ in withNodeJs ; # inherit customRC; - plugins = normalizedPlugins; + inherit plugins; } # Necessary to make sure the runtime path is set properly in NixOS 22.05, # or more generally before the commit: @@ -152,7 +171,7 @@ in // optionalAttrs (lib.functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) { configure.packages = { nixvim = { - start = map (x: x.plugin) normalizedPlugins; + start = map (x: x.plugin) plugins; opt = [ ]; }; }; diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index c9bec0d68c..f04b61c595 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -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"; + } + ]; + }; } From 77ee33a1df56aab687a9f9bd223a98b8034f2566 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Sun, 14 Jul 2024 17:46:01 +0300 Subject: [PATCH 05/13] modules/performance: handle plugin configs when combining plugins --- modules/top-level/output.nix | 45 +++++++---- .../modules/performance/combine-plugins.nix | 80 ++++++++++++++----- 2 files changed, 89 insertions(+), 36 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 0e1bd0247c..b3bd121ead 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -80,7 +80,7 @@ in let defaultPlugin = { plugin = null; - config = ""; + config = null; optional = false; }; in @@ -129,25 +129,36 @@ in deps = map (p: p.plugin.python3Dependencies or (_: [ ])) startPlugins; in ps: builtins.concatMap (f: f ps) deps; + + # Combined plugin + combinedPlugin = pkgs.vimUtils.toVimPlugin ( + pkgs.buildEnv { + name = "plugin-pack"; + paths = overriddenPlugins; + inherit (config.performance.combinePlugins) pathsToLink; + # Remove empty directories and activate vimGenDocHook + postBuild = '' + find $out -type d -empty -delete + runHook preFixup + ''; + passthru = { + inherit python3Dependencies; + }; + } + ); + + # Combined plugin configs + combinedConfig = builtins.concatStringsSep "\n" ( + builtins.concatMap (x: lib.optional (x.config != null && x.config != "") x.config) startPlugins + ); in - pkgs.vimUtils.toVimPlugin ( - pkgs.buildEnv { - name = "plugin-pack"; - paths = overriddenPlugins; - inherit (config.performance.combinePlugins) pathsToLink; - # Remove empty directories and activate vimGenDocHook - postBuild = '' - find $out -type d -empty -delete - runHook preFixup - ''; - passthru = { - inherit python3Dependencies; - }; - } - ); + normalize { + plugin = combinedPlugin; + config = combinedConfig; + }; # Combined plugins - combinedPlugins = [ (normalize pluginPack) ] ++ optPlugins; + combinedPlugins = [ pluginPack ] ++ optPlugins; # Plugins to use in finalPackage plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins; diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index f04b61c595..b102827fd8 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -1,4 +1,7 @@ { pkgs, ... }: +let + pluginCount = pkg: type: builtins.length pkg.packpathDirs.myNeovimPackages.${type}; +in { # Test basic functionality default.module = @@ -25,7 +28,7 @@ ''; assertions = [ { - assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + assertion = pluginCount config.finalPackage "start" == 1; message = "More than one plugin is defined in packpathDirs, expected one plugin pack."; } ]; @@ -42,7 +45,7 @@ ]; assertions = [ { - assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start >= 2; + assertion = pluginCount config.finalPackage "start" >= 2; message = "Only one plugin is defined in packpathDirs, expected at least two."; } ]; @@ -69,7 +72,7 @@ ''; assertions = [ { - assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + assertion = pluginCount config.finalPackage "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -97,7 +100,7 @@ ''; assertions = [ { - assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + assertion = pluginCount config.finalPackage "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -124,7 +127,7 @@ ''; assertions = [ { - assertion = builtins.length config.finalPackage.packpathDirs.myNeovimPackages.start == 1; + assertion = pluginCount config.finalPackage "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -176,19 +179,58 @@ "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"; - } - ]; + assertions = [ + { + assertion = pluginCount config.finalPackage "start" == 1; + message = "More than one start plugin is defined in packpathDirs"; + } + { + assertion = pluginCount config.finalPackage "opt" == 2; + message = "Less than two opt plugins are defined in packpathDirs"; + } + ]; + }; + + # Test that plugin configs are handled + configs.module = + { config, ... }: + { + performance.combinePlugins.enable = true; + extraPlugins = with pkgs.vimPlugins; [ + # A plugin without config + plenary-nvim + # Plugins with configs + { + plugin = nvim-treesitter; + config = "let g:treesitter_config = 1"; + } + { + plugin = nvim-lspconfig; + config = "let g:lspconfig_config = 1"; + } + # Optional plugin with config + { + plugin = telescope-nvim; + optional = true; + config = "let g:telescope_config = 1"; + } + ]; + extraConfigLuaPost = '' + -- Plugins are loadable + require("plenary") + require("nvim-treesitter") + require("lspconfig") + + -- Configs are evaluated + assert(vim.g.treesitter_config == 1, "nvim-treesitter config isn't evaluated") + assert(vim.g.lspconfig_config == 1, "nvim-lspconfig config isn't evaluated") + assert(vim.g.telescope_config == 1, "telescope-nvim config isn't evaluated") + ''; + assertions = [ + { + assertion = pluginCount config.finalPackage "start" == 1; + message = "More than one start plugin is defined in packpathDirs"; + } + ]; }; } From ad21cef85e9478e14241aedec8ebffbb6ee309f3 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:31:12 +0300 Subject: [PATCH 06/13] modules/performance: add `combinePlugins.standalonePlugins` option --- modules/performance.nix | 9 ++- modules/top-level/output.nix | 27 ++++++-- .../modules/performance/combine-plugins.nix | 66 +++++++++++++++++++ 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/modules/performance.nix b/modules/performance.nix index 9709b3f0df..59233583a0 100644 --- a/modules/performance.nix +++ b/modules/performance.nix @@ -10,7 +10,8 @@ in Whether to enable EXPERIMENTAL option to combine all plugins into a single plugin pack. It can significantly reduce startup time, 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. If some of your plugins contain important files outside of standard directories, add these paths to `pathsToLink` option. @@ -22,6 +23,12 @@ in example = [ "/data" ]; 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."; + }; }; }; diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index b3bd121ead..024e348c73 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -98,13 +98,26 @@ in in 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 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; + optPlugins = removeDependencies 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 pluginPack = @@ -121,12 +134,12 @@ in ] ); }) - ) startPlugins; + ) toCombinePlugins; # Python3 dependencies python3Dependencies = let - deps = map (p: p.plugin.python3Dependencies or (_: [ ])) startPlugins; + deps = map (p: p.plugin.python3Dependencies or (_: [ ])) toCombinePlugins; in ps: builtins.concatMap (f: f ps) deps; @@ -149,7 +162,7 @@ in # Combined plugin configs 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 normalize { @@ -158,7 +171,7 @@ in }; # Combined plugins - combinedPlugins = [ pluginPack ] ++ optPlugins; + combinedPlugins = [ pluginPack ] ++ standaloneStartPlugins ++ optPlugins; # Plugins to use in finalPackage plugins = if config.performance.combinePlugins.enable then combinedPlugins else normalizedPlugins; diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index b102827fd8..e2289ee3b3 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -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"; + } + ]; + }; } From 4792e62f07459547b51417af7cf498023d18fa69 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:35:17 +0300 Subject: [PATCH 07/13] modules/performance: don't combine `filesPlugin` into plugin pack It's expected that user may want to override some runtime files in its own config directory. Do not combine it into plugin pack to avoid collisions. --- modules/top-level/files/default.nix | 3 + .../modules/performance/combine-plugins.nix | 95 +++++++++++++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/modules/top-level/files/default.nix b/modules/top-level/files/default.nix index c8a3d24840..c9ec06f828 100644 --- a/modules/top-level/files/default.nix +++ b/modules/top-level/files/default.nix @@ -93,5 +93,8 @@ in ] ) extraFiles} ''; + + # Never combine user files with the rest of the plugins + performance.combinePlugins.standalonePlugins = [ config.filesPlugin ]; }; } diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index e2289ee3b3..d59c79642c 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -1,6 +1,11 @@ { pkgs, ... }: let - pluginCount = pkg: type: builtins.length pkg.packpathDirs.myNeovimPackages.${type}; + inherit (pkgs) lib; + + # Count plugins of given type excluding 'filesPlugin' + pluginCount = + pkg: filesPlugin: type: + builtins.length (builtins.filter (p: p != filesPlugin) pkg.packpathDirs.myNeovimPackages.${type}); in { # Test basic functionality @@ -28,7 +33,7 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one plugin is defined in packpathDirs, expected one plugin pack."; } ]; @@ -45,7 +50,7 @@ in ]; assertions = [ { - assertion = pluginCount config.finalPackage "start" >= 2; + assertion = pluginCount config.finalPackage config.filesPlugin "start" >= 2; message = "Only one plugin is defined in packpathDirs, expected at least two."; } ]; @@ -72,7 +77,7 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -100,7 +105,7 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -127,7 +132,7 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one plugin is defined in packpathDirs."; } ]; @@ -181,11 +186,11 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one start plugin is defined in packpathDirs"; } { - assertion = pluginCount config.finalPackage "opt" == 2; + assertion = pluginCount config.finalPackage config.filesPlugin "opt" == 2; message = "Less than two opt plugins are defined in packpathDirs"; } ]; @@ -228,7 +233,77 @@ in ''; assertions = [ { - assertion = pluginCount config.finalPackage "start" == 1; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; + message = "More than one start plugin is defined in packpathDirs"; + } + ]; + }; + + # Test that config.filesPlugin is not combined + files-plugin.module = + { config, ... }: + { + performance.combinePlugins.enable = true; + extraPlugins = with pkgs.vimPlugins; [ + nvim-treesitter + vim-nix + ]; + # Ensure that filesPlugin is added extraPlugins + wrapRc = true; + # Extra user files colliding with plugins + extraFiles = { + "ftplugin/nix.vim".text = "let b:test = 1"; + "queries/nix/highlights.scm".text = '' + ;; extends + (comment) @comment + ''; + }; + # Another form of user files + files = { + "ftdetect/nix.vim" = { + autoCmd = [ + { + event = [ + "BufRead" + "BufNewFile" + ]; + pattern = "*.nix"; + command = "setf nix"; + } + ]; + }; + }; + extraConfigLuaPost = '' + local function get_paths(name) + local paths = vim.api.nvim_get_runtime_file(name, true); + return vim.tbl_filter(function(v) + -- Skip paths from neovim runtime + return not v:find("/nvim/runtime/") + end, paths) + end + + -- Both plugin and user version are available + assert(#get_paths("ftplugin/nix.vim") == 2, "only one version of ftplugin/nix.vim") + assert(#get_paths("ftdetect/nix.vim") == 2, "only one version of ftdetect/nix.vim") + assert(#get_paths("queries/nix/highlights.scm") == 2, "only one version of queries/nix/highlights.scm") + + -- First found file is from filesPlugin + assert( + get_paths("ftplugin/nix.vim")[1]:find("${lib.getName config.filesPlugin}", 1, true), + "first found ftplugin/nix.vim isn't in filesPlugin runtime path" + ) + assert( + get_paths("queries/nix/highlights.scm")[1]:find("${lib.getName config.filesPlugin}", 1, true), + "first found queries/nix/highlights.scm isn't in filesPlugin runtime path" + ) + assert( + get_paths("queries/nix/highlights.scm")[1]:find("${lib.getName config.filesPlugin}", 1, true), + "first found queries/nix/highlights.scm isn't in filesPlugin runtime path" + ) + ''; + assertions = [ + { + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 1; message = "More than one start plugin is defined in packpathDirs"; } ]; @@ -294,7 +369,7 @@ in assertions = [ { # plugin-pack, nvim-treesitter, nvim-lspconfig, telescope-nvim, nvim-cmp - assertion = pluginCount config.finalPackage "start" == 5; + assertion = pluginCount config.finalPackage config.filesPlugin "start" == 5; message = "Wrong number of plugins in packpathDirs"; } ]; From 8e8932ad4852548f0150a7c595f86290e289a798 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:35:02 +0300 Subject: [PATCH 08/13] plugins/treesitter: add workaround for `performance.combinePlugins` --- plugins/languages/treesitter/treesitter.nix | 5 +++ .../languages/treesitter/combine-plugins.nix | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/test-sources/plugins/languages/treesitter/combine-plugins.nix diff --git a/plugins/languages/treesitter/treesitter.nix b/plugins/languages/treesitter/treesitter.nix index 497d98bc07..01257f01a4 100644 --- a/plugins/languages/treesitter/treesitter.nix +++ b/plugins/languages/treesitter/treesitter.nix @@ -328,5 +328,10 @@ helpers.neovim-plugin.mkNeovimPlugin config { foldmethod = mkDefault "expr"; foldexpr = mkDefault "nvim_treesitter#foldexpr()"; }; + + # Since https://github.com/NixOS/nixpkgs/pull/321550 upstream queries are added + # to grammar plugins. Exclude nvim-treesitter itself from combining to avoid + # collisions with grammar's queries + performance.combinePlugins.standalonePlugins = [ cfg.package ]; }; } diff --git a/tests/test-sources/plugins/languages/treesitter/combine-plugins.nix b/tests/test-sources/plugins/languages/treesitter/combine-plugins.nix new file mode 100644 index 0000000000..074c95ad86 --- /dev/null +++ b/tests/test-sources/plugins/languages/treesitter/combine-plugins.nix @@ -0,0 +1,37 @@ +{ pkgs, ... }: +{ + combine-plugins = { + performance.combinePlugins.enable = true; + + plugins.treesitter = { + enable = true; + + # Exclude nixvim injections for test to pass + nixvimInjections = false; + }; + + extraConfigLuaPost = '' + -- Ensure that queries from nvim-treesitter are first in rtp + local queries_path = "${pkgs.vimPlugins.nvim-treesitter}/queries" + for name, type in vim.fs.dir(queries_path, {depth = 10}) do + if type == "file" then + -- Resolve all symlinks and compare nvim-treesitter's path with + -- whatever we've got from runtime + local nvim_treesitter_path = assert(vim.uv.fs_realpath(vim.fs.joinpath(queries_path, name))) + local rtp_path = assert( + vim.uv.fs_realpath(vim.api.nvim_get_runtime_file("queries/" .. name, false)[1]), + name .. " not found in runtime" + ) + assert( + nvim_treesitter_path == rtp_path, + string.format( + "%s from rtp (%s) is not the same as from nvim-treesitter (%s)", + name, + rtp_path, nvim_treesitter_path + ) + ) + end + end + ''; + }; +} From d2a1e63255a7513d102d1999429745055b5b20fd Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:24:56 +0300 Subject: [PATCH 09/13] plugins/telescope/fzf-native: add compatibility with `combinePlugins` --- plugins/telescope/extensions/fzf-native.nix | 5 +++++ tests/test-sources/plugins/telescope/fzf-native.nix | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/plugins/telescope/extensions/fzf-native.nix b/plugins/telescope/extensions/fzf-native.nix index 8742c639b7..d159b223f8 100644 --- a/plugins/telescope/extensions/fzf-native.nix +++ b/plugins/telescope/extensions/fzf-native.nix @@ -52,4 +52,9 @@ override_file_sorter = false; case_mode = "ignore_case"; }; + + extraConfig = cfg: { + # Native library is in build/libfzf.so + performance.combinePlugins.pathsToLink = [ "/build" ]; + }; } diff --git a/tests/test-sources/plugins/telescope/fzf-native.nix b/tests/test-sources/plugins/telescope/fzf-native.nix index 7cf63acd80..6a1b2c8707 100644 --- a/tests/test-sources/plugins/telescope/fzf-native.nix +++ b/tests/test-sources/plugins/telescope/fzf-native.nix @@ -22,4 +22,13 @@ }; }; }; + + combine-plugins = { + plugins.telescope = { + enable = true; + extensions.fzf-native.enable = true; + }; + + performance.combinePlugins.enable = true; + }; } From 9a8f1961ec062bf77ce30201f1cf98df1ca9367e Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:38:32 +0300 Subject: [PATCH 10/13] plugins/telescope/fzy-native: add compatibility with `combinePlugins` --- plugins/telescope/extensions/fzy-native.nix | 5 +++++ tests/test-sources/plugins/telescope/fzy-native.nix | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/plugins/telescope/extensions/fzy-native.nix b/plugins/telescope/extensions/fzy-native.nix index 602d8bb2f8..744d1a767a 100644 --- a/plugins/telescope/extensions/fzy-native.nix +++ b/plugins/telescope/extensions/fzy-native.nix @@ -38,4 +38,9 @@ override_file_sorter = true; override_generic_sorter = false; }; + + extraConfig = cfg: { + # fzy-native itself is in deps directory + performance.combinePlugins.pathsToLink = [ "/deps/fzy-lua-native" ]; + }; } diff --git a/tests/test-sources/plugins/telescope/fzy-native.nix b/tests/test-sources/plugins/telescope/fzy-native.nix index f6f3474768..42112ea3e3 100644 --- a/tests/test-sources/plugins/telescope/fzy-native.nix +++ b/tests/test-sources/plugins/telescope/fzy-native.nix @@ -20,4 +20,13 @@ }; }; }; + + combine-plugins = { + plugins.telescope = { + enable = true; + extensions.fzy-native.enable = true; + }; + + performance.combinePlugins.enable = true; + }; } From f8c7b7c88d7d2c7e39ced645bfbb87430a21d61d Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:25:15 +0300 Subject: [PATCH 11/13] plugins/telescope: add compatibility with `combinePlugins` --- plugins/telescope/default.nix | 3 +++ tests/test-sources/plugins/telescope/default.nix | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/plugins/telescope/default.nix b/plugins/telescope/default.nix index f0322c6340..706a9320b0 100644 --- a/plugins/telescope/default.nix +++ b/plugins/telescope/default.nix @@ -112,6 +112,9 @@ helpers.neovim-plugin.mkNeovimPlugin config { require('telescope').load_extension(extension) end ''; + + # planets picker requires files in data/memes/planets + performance.combinePlugins.pathsToLink = [ "/data/memes/planets" ]; }; settingsOptions = { diff --git a/tests/test-sources/plugins/telescope/default.nix b/tests/test-sources/plugins/telescope/default.nix index 8354ea174f..15d2760795 100644 --- a/tests/test-sources/plugins/telescope/default.nix +++ b/tests/test-sources/plugins/telescope/default.nix @@ -17,4 +17,19 @@ highlightTheme = "gruvbox"; }; }; + + combine-plugins.module = + { config, ... }: + { + plugins.telescope.enable = true; + + performance.combinePlugins.enable = true; + + extraConfigLuaPost = # lua + '' + -- I don't know how run telescope properly in test environment, + -- so just check that files exist + assert(vim.api.nvim_get_runtime_file("data/memes/planets/earth", false)[1], "telescope planets aren't found in runtime") + ''; + }; } From fa30bc6b37bf0a2e4ebebad18d8c436f9d4eabf8 Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:45:12 +0300 Subject: [PATCH 12/13] modules/performance: add plenary filetypes directory to default pathsToLink plenary.nvim is often pulled as a dependency of other plugins. It has filetype definitions in `data/plenary/filetypes` directory. Even though I don't think there are plugins using it instead of vim.filetype, but it should be no harm to add this directory by default. --- modules/performance.nix | 2 ++ .../modules/performance/combine-plugins.nix | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/modules/performance.nix b/modules/performance.nix index 59233583a0..db0953d452 100644 --- a/modules/performance.nix +++ b/modules/performance.nix @@ -56,6 +56,8 @@ in "/after" # ftdetect "/ftdetect" + # plenary.nvim + "/data/plenary/filetypes" ]; }; } diff --git a/tests/test-sources/modules/performance/combine-plugins.nix b/tests/test-sources/modules/performance/combine-plugins.nix index d59c79642c..6290bdfe0a 100644 --- a/tests/test-sources/modules/performance/combine-plugins.nix +++ b/tests/test-sources/modules/performance/combine-plugins.nix @@ -374,4 +374,14 @@ in } ]; }; + + # Test if plenary.filetype is working + plenary-nvim = { + performance.combinePlugins.enable = true; + extraPlugins = [ pkgs.vimPlugins.plenary-nvim ]; + extraConfigLuaPost = '' + -- Plenary filetype detection is usable + assert(require("plenary.filetype").detect(".bashrc") == "sh", "plenary.filetype is not working") + ''; + }; } From 435713d84b37ed64b6e8713eab1202be104f9f1b Mon Sep 17 00:00:00 2001 From: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Date: Fri, 19 Jul 2024 23:08:05 +0300 Subject: [PATCH 13/13] modules/performance: refactor after code review --- modules/top-level/output.nix | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 024e348c73..6f70876099 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -102,10 +102,10 @@ in removeDependencies = ps: map (p: p // { plugin = removeAttrs p.plugin [ "dependencies" ]; }) ps; # Separated start and opt plugins - partitionedPlugins = builtins.partition (p: p.optional) allPlugins; - startPlugins = partitionedPlugins.wrong; + partitionedOptStartPlugins = builtins.partition (p: p.optional) allPlugins; + startPlugins = partitionedOptStartPlugins.wrong; # Remove opt plugin dependencies since they are already available in start plugins - optPlugins = removeDependencies partitionedPlugins.right; + optPlugins = removeDependencies partitionedOptStartPlugins.right; # Test if plugin shouldn't be included in plugin pack isStandalone = @@ -114,25 +114,24 @@ in || builtins.elem (lib.getName p.plugin) config.performance.combinePlugins.standalonePlugins; # Separated standalone and combined start plugins - partitionedStartPlugins = builtins.partition isStandalone startPlugins; - toCombinePlugins = partitionedStartPlugins.wrong; + partitionedStandaloneStartPlugins = builtins.partition isStandalone startPlugins; + toCombinePlugins = partitionedStandaloneStartPlugins.wrong; # Remove standalone plugin dependencies since they are already available in start plugins - standaloneStartPlugins = removeDependencies partitionedStartPlugins.right; + standaloneStartPlugins = removeDependencies partitionedStandaloneStartPlugins.right; # Combine start plugins into a single pack pluginPack = let - # Plugins with doc tags removed + # Every plugin has its own generated help tags (doc/tags) + # Remove them to avoid collisions, new help tags + # will be generate for the entire pack later on overriddenPlugins = map ( plugin: plugin.plugin.overrideAttrs (prev: { nativeBuildInputs = lib.remove pkgs.vimUtils.vimGenDocHook prev.nativeBuildInputs or [ ]; - configurePhase = builtins.concatStringsSep "\n" ( - builtins.filter (s: s != ":") [ - prev.configurePhase or ":" - "rm -vf doc/tags" - ] - ); + configurePhase = '' + ${prev.configurePhase or ""} + rm -vf doc/tags''; }) ) toCombinePlugins;