about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthieu Coudron <teto@users.noreply.github.com>2021-05-26 18:35:36 +0200
committerGitHub <noreply@github.com>2021-05-26 18:35:36 +0200
commitbffd12a4c7d15ac3fbed965e222e9b5e86c72021 (patch)
treef7e1bcc908917aff5ac4d4a05c13b528ebf5b6e0
parent4aa2e32246c6b9d765191baba60969a27d484ccf (diff)
parent4a860879ea76c2be86a696cb885cc51bfe8f61fa (diff)
downloadnixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar.gz
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar.bz2
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar.lz
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar.xz
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.tar.zst
nixlib-bffd12a4c7d15ac3fbed965e222e9b5e86c72021.zip
Merge pull request #120445 from teto/vim-plugins-dict
neovimUtils: pass plugin config with plugin
-rw-r--r--pkgs/applications/editors/neovim/utils.nix40
-rw-r--r--pkgs/applications/editors/neovim/wrapper.nix27
-rw-r--r--pkgs/misc/vim-plugins/vim-utils.nix15
-rw-r--r--pkgs/test/vim/default.nix33
4 files changed, 94 insertions, 21 deletions
diff --git a/pkgs/applications/editors/neovim/utils.nix b/pkgs/applications/editors/neovim/utils.nix
index 3e6e88dd2288..a7d8f00c664f 100644
--- a/pkgs/applications/editors/neovim/utils.nix
+++ b/pkgs/applications/editors/neovim/utils.nix
@@ -29,6 +29,11 @@ let
     , withNodeJs ? false
     , withRuby ? true
 
+    # expects a list of plugin configuration
+    # expects { plugin=far-vim; config = "let g:far#source='rg'"; optional = false; }
+    , plugins ? []
+    # forwarded to configure.customRC
+    , customRC ? ""
     # same values as in vimUtils.vimrcContent
     , configure ? { }
 
@@ -44,7 +49,33 @@ let
         '';
       };
 
-      requiredPlugins = vimUtils.requiredPlugins configure;
+      # transform all plugins into an attrset
+      pluginsNormalized = map (x: if x ? plugin then { optional = false; } // x else { plugin = x; optional = false;}) plugins;
+
+
+      configurePatched = configure // {
+        packages.nix = {
+          start = lib.filter (f: f != null)
+            (map (x: if x.optional == false then x.plugin else null)
+              pluginsNormalized);
+          opt = lib.filter (f: f != null)
+            (map (x: if x.optional == true then x.plugin else null)
+              pluginsNormalized);
+        };
+        customRC = pluginRc + customRC;
+      };
+
+      # A function to get the configuration string (if any) from an element of 'plugins'
+      pluginConfig = p:
+        if (p.config or "") != "" then ''
+          " ${p.plugin.pname or p.plugin.name} {{{
+          ${p.config}
+          " }}}
+        '' else "";
+
+      pluginRc = lib.concatMapStrings pluginConfig pluginsNormalized;
+
+      requiredPlugins = vimUtils.requiredPlugins configurePatched;
       getDeps = attrname: map (plugin: plugin.${attrname} or (_: [ ]));
 
       pluginPython3Packages = getDeps "python3Dependencies" requiredPlugins;
@@ -89,12 +120,13 @@ let
           "--suffix" "PATH" ":" binPath
         ];
 
-      manifestRc = vimUtils.vimrcContent (configure // { customRC = ""; });
-      neovimRcContent = vimUtils.vimrcContent configure;
+
+      manifestRc = vimUtils.vimrcContent (configurePatched // { customRC = ""; }) ;
+      neovimRcContent = vimUtils.vimrcContent configurePatched;
     in
     assert withPython2 -> throw "Python2 support has been removed from neovim, please remove withPython2 and extraPython2Packages.";
 
-    args // {
+    builtins.removeAttrs args ["plugins"] // {
       wrapperArgs = makeWrapperArgs;
       inherit neovimRcContent;
       inherit manifestRc;
diff --git a/pkgs/applications/editors/neovim/wrapper.nix b/pkgs/applications/editors/neovim/wrapper.nix
index db30832d2398..4defc2d43278 100644
--- a/pkgs/applications/editors/neovim/wrapper.nix
+++ b/pkgs/applications/editors/neovim/wrapper.nix
@@ -11,8 +11,9 @@ neovim:
 
 let
   wrapper = {
-      # should contain all args but the binary
-      wrapperArgs ? ""
+      extraName ? ""
+    # should contain all args but the binary. Can be either a string or list
+    , wrapperArgs ? []
     , manifestRc ? null
     , withPython2 ? false
     , withPython3 ? true,  python3Env ? null
@@ -20,10 +21,18 @@ let
     , rubyEnv ? null
     , vimAlias ? false
     , viAlias ? false
+
+    # additional argument not generated by makeNeovimConfig
+    # it will append "-u <customRc>" to the wrapped arguments
+    # set to false if you want to control where to save the generated config
+    # (e.g., in ~/.config/init.vim or project/.nvimrc)
+    , wrapRc ? true
     , ...
-  }:
+  }@args:
   let
 
+    wrapperArgsStr = if isString wrapperArgs then wrapperArgs else lib.escapeShellArgs wrapperArgs;
+
   # If configure != {}, we can't generate the rplugin.vim file with e.g
   # NVIM_SYSTEM_RPLUGIN_MANIFEST *and* NVIM_RPLUGIN_MANIFEST env vars set in
   # the wrapper. That's why only when configure != {} (tested both here and
@@ -31,13 +40,15 @@ let
   # wrapper with most arguments we need, excluding those that cause problems to
   # generate rplugin.vim, but still required for the final wrapper.
   finalMakeWrapperArgs =
-    [ "${neovim}/bin/nvim" "${placeholder "out"}/bin/nvim" ] ++
-      [ "--set" "NVIM_SYSTEM_RPLUGIN_MANIFEST" "${placeholder "out"}/rplugin.vim" ];
+    [ "${neovim}/bin/nvim" "${placeholder "out"}/bin/nvim" ]
+    ++ [ "--set" "NVIM_SYSTEM_RPLUGIN_MANIFEST" "${placeholder "out"}/rplugin.vim" ]
+    ++ optionals wrapRc [ "--add-flags" "-u ${writeText "init.vim" args.neovimRcContent}" ]
+    ;
   in
   assert withPython2 -> throw "Python2 support has been removed from the neovim wrapper, please remove withPython2 and python2Env.";
 
   symlinkJoin {
-      name = "neovim-${lib.getVersion neovim}";
+      name = "neovim-${lib.getVersion neovim}${extraName}";
       # Remove the symlinks created by symlinkJoin which we need to perform
       # extra actions upon
       postBuild = lib.optionalString stdenv.isLinux ''
@@ -66,7 +77,7 @@ let
       in ''
         echo "Generating remote plugin manifest"
         export NVIM_RPLUGIN_MANIFEST=$out/rplugin.vim
-        makeWrapper ${lib.escapeShellArgs manifestWrapperArgs} ${wrapperArgs}
+        makeWrapper ${lib.escapeShellArgs manifestWrapperArgs} ${wrapperArgsStr}
 
         # Some plugins assume that the home directory is accessible for
         # initializing caches, temporary files, etc. Even if the plugin isn't
@@ -96,7 +107,7 @@ let
       '')
       + ''
         rm $out/bin/nvim
-        makeWrapper ${lib.escapeShellArgs finalMakeWrapperArgs} ${wrapperArgs}
+        makeWrapper ${lib.escapeShellArgs finalMakeWrapperArgs} ${wrapperArgsStr}
       '';
 
     paths = [ neovim ];
diff --git a/pkgs/misc/vim-plugins/vim-utils.nix b/pkgs/misc/vim-plugins/vim-utils.nix
index c55e8aa0a011..52bf4341fa5b 100644
--- a/pkgs/misc/vim-plugins/vim-utils.nix
+++ b/pkgs/misc/vim-plugins/vim-utils.nix
@@ -232,8 +232,7 @@ let
     let
       /* pathogen mostly can set &rtp at startup time. Its used very commonly.
       */
-      pathogenImpl = lib.optionalString (pathogen != null)
-      (let
+      pathogenImpl = let
         knownPlugins = pathogen.knownPlugins or vimPlugins;
 
         plugins = findDependenciesRecursively (map (pluginToDrv knownPlugins) pathogen.pluginNames);
@@ -244,15 +243,15 @@ let
         };
       in
       ''
-        let &rtp.=(empty(&rtp)?"":',')."${vimPlugins.pathogen.rtp}"
+        let &rtp.=(empty(&rtp)?"":',')."${vimPlugins.vim-pathogen.rtp}"
         execute pathogen#infect('${pluginsEnv}/{}')
 
         filetype indent plugin on | syn on
-      '');
+      '';
 
       /* vim-plug is an extremely popular vim plugin manager.
       */
-      plugImpl = lib.optionalString (plug != null)
+      plugImpl =
       (''
         source ${vimPlugins.vim-plug.rtp}/plug.vim
         call plug#begin('/dev/null')
@@ -340,10 +339,12 @@ let
 
       entries = [
         beforePlugins
-        vamImpl pathogenImpl plugImpl
+        vamImpl
         (nativeImpl packages)
         customRC
-      ];
+      ]
+      ++ lib.optional (pathogen != null) pathogenImpl
+      ++ lib.optional (plug != null) plugImpl;
 
     in
       lib.concatStringsSep "\n" (lib.filter (x: x != null && x != "") entries);
diff --git a/pkgs/test/vim/default.nix b/pkgs/test/vim/default.nix
index 4ca004a60c34..c75836aa9a80 100644
--- a/pkgs/test/vim/default.nix
+++ b/pkgs/test/vim/default.nix
@@ -1,14 +1,43 @@
-{ vimUtils, vim_configurable, neovim, vimPlugins
-, lib, fetchFromGitHub,
+{ vimUtils, vim_configurable, writeText, neovim, vimPlugins
+, lib, fetchFromGitHub, neovimUtils, wrapNeovimUnstable
+, neovim-unwrapped
 }:
 let
   inherit (vimUtils) buildVimPluginFrom2Nix;
 
   packages.myVimPackage.start = with vimPlugins; [ vim-nix ];
+
+  plugins = with vimPlugins; [
+    {
+      plugin = vim-obsession;
+      config = ''
+        map <Leader>$ <Cmd>Obsession<CR>
+      '';
+    }
+  ];
+
+  nvimConfNix = neovimUtils.makeNeovimConfig {
+    inherit plugins;
+    customRC = ''
+      " just a comment
+    '';
+  };
+
+  wrapNeovim = suffix: config:
+    wrapNeovimUnstable neovim-unwrapped (config // {
+      extraName = suffix;
+      wrapRc = true;
+    });
 in
 {
   vim_empty_config = vimUtils.vimrcFile { beforePlugins = ""; customRC = ""; };
 
+  ### neovim tests
+  ##################
+  nvim_with_plugins = wrapNeovim "-with-plugins" nvimConfNix;
+
+  ### vim tests
+  ##################
   vim_with_vim2nix = vim_configurable.customize {
     name = "vim"; vimrcConfig.vam.pluginDictionaries = [ "vim-addon-vim2nix" ];
   };