From 51c4768f67b4345f09b4e37f930056b7b1e61787 Mon Sep 17 00:00:00 2001
From: Timo Kaufmann <timokau@zoho.com>
Date: Sun, 30 Dec 2018 20:27:52 +0100
Subject: [PATCH 1/3] neovim: fix indentation

---
 pkgs/applications/editors/neovim/wrapper.nix | 21 ++++++++++----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/pkgs/applications/editors/neovim/wrapper.nix b/pkgs/applications/editors/neovim/wrapper.nix
index 3dd3710da772..d69e68ac61fc 100644
--- a/pkgs/applications/editors/neovim/wrapper.nix
+++ b/pkgs/applications/editors/neovim/wrapper.nix
@@ -83,18 +83,17 @@ let
       ''
       + optionalString withPython ''
         makeWrapper ${pythonEnv}/bin/python $out/bin/nvim-python --unset PYTHONPATH
-    '' + optionalString withPython3 ''
+      '' + optionalString withPython3 ''
         makeWrapper ${python3Env}/bin/python3 $out/bin/nvim-python3 --unset PYTHONPATH
-    '' + optionalString withRuby ''
-      ln -s ${rubyEnv}/bin/neovim-ruby-host $out/bin/nvim-ruby
-    '' + optionalString vimAlias ''
-      ln -s $out/bin/nvim $out/bin/vim
-    '' + optionalString viAlias ''
-      ln -s $out/bin/nvim $out/bin/vi
-    '' + optionalString (configure != {}) ''
-    wrapProgram $out/bin/nvim --add-flags "-u ${vimUtils.vimrcFile configure}"
-    ''
-    ;
+      '' + optionalString withRuby ''
+        ln -s ${rubyEnv}/bin/neovim-ruby-host $out/bin/nvim-ruby
+      '' + optionalString vimAlias ''
+        ln -s $out/bin/nvim $out/bin/vim
+      '' + optionalString viAlias ''
+        ln -s $out/bin/nvim $out/bin/vi
+      '' + optionalString (configure != {}) ''
+        wrapProgram $out/bin/nvim --add-flags "-u ${vimUtils.vimrcFile configure}"
+      '';
 
     preferLocalBuild = true;
 

From ab22e8cc9c8f667c09f54f82fcb88f9732c54dfc Mon Sep 17 00:00:00 2001
From: Timo Kaufmann <timokau@zoho.com>
Date: Sun, 30 Dec 2018 20:37:44 +0100
Subject: [PATCH 2/3] neovim: generate remote plugin manifest

This makes sure the user doesn't have to call `UpdateRemotePlugins`
manually for plugins installed through nix. A minor patch to neovim is
necessary, but it should be harmless. See
https://github.com/neovim/neovim/issues/9413 for a discussion about
the patch.
---
 pkgs/applications/editors/neovim/default.nix  |  7 +++++
 .../neovim/system_rplugin_manifest.patch      | 29 +++++++++++++++++++
 pkgs/applications/editors/neovim/wrapper.nix  | 25 ++++++++++++++--
 pkgs/misc/vim-plugins/vim-utils.nix           |  8 +++++
 4 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 pkgs/applications/editors/neovim/system_rplugin_manifest.patch

diff --git a/pkgs/applications/editors/neovim/default.nix b/pkgs/applications/editors/neovim/default.nix
index a3580b1afa7a..27e274326470 100644
--- a/pkgs/applications/editors/neovim/default.nix
+++ b/pkgs/applications/editors/neovim/default.nix
@@ -20,6 +20,13 @@ let
       sha256 = "07ncvgp6xfhiwc6hd7qf7zk28n3yj47p26qj1ji29vqkwnk28y3s";
     };
 
+    patches = [
+      # introduce a system-wide rplugin.vim in addition to the user one
+      # necessary so that nix can handle `UpdateRemotePlugins` for the plugins
+      # it installs. See https://github.com/neovim/neovim/issues/9413.
+      ./system_rplugin_manifest.patch
+    ];
+
     enableParallelBuilding = true;
 
     buildInputs = [
diff --git a/pkgs/applications/editors/neovim/system_rplugin_manifest.patch b/pkgs/applications/editors/neovim/system_rplugin_manifest.patch
new file mode 100644
index 000000000000..f634d3ec056a
--- /dev/null
+++ b/pkgs/applications/editors/neovim/system_rplugin_manifest.patch
@@ -0,0 +1,29 @@
+diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim
+index 6266b312b..965fabf1e 100644
+--- a/runtime/autoload/remote/host.vim
++++ b/runtime/autoload/remote/host.vim
+@@ -71,7 +71,8 @@ function! remote#host#RegisterPlugin(host, path, specs) abort
+ 
+   for plugin in plugins
+     if plugin.path == a:path
+-      throw 'Plugin "'.a:path.'" is already registered'
++      " plugin already registered
++      return
+     endif
+   endfor
+ 
+diff --git a/runtime/plugin/rplugin.vim b/runtime/plugin/rplugin.vim
+index 122d8d47f..83fbf8b57 100644
+--- a/runtime/plugin/rplugin.vim
++++ b/runtime/plugin/rplugin.vim
+@@ -54,6 +54,10 @@ function! s:GetManifest() abort
+ endfunction
+ 
+ function! s:LoadRemotePlugins() abort
++  if exists('$NVIM_SYSTEM_RPLUGIN_MANIFEST')
++    let g:system_remote_plugins = fnamemodify($NVIM_SYSTEM_RPLUGIN_MANIFEST, ':p')
++    execute 'source' fnameescape(g:system_remote_plugins)
++  endif
+   let g:loaded_remote_plugins = s:GetManifest()
+   if filereadable(g:loaded_remote_plugins)
+     execute 'source' fnameescape(g:loaded_remote_plugins)
diff --git a/pkgs/applications/editors/neovim/wrapper.nix b/pkgs/applications/editors/neovim/wrapper.nix
index d69e68ac61fc..7d76bc1fd1a0 100644
--- a/pkgs/applications/editors/neovim/wrapper.nix
+++ b/pkgs/applications/editors/neovim/wrapper.nix
@@ -72,7 +72,6 @@ let
         --cmd \"${if withRuby then "let g:ruby_host_prog='$out/bin/nvim-ruby'" else "let g:loaded_ruby_provider=1"}\" " \
         --suffix PATH : ${binPath} \
         ${optionalString withRuby '' --set GEM_HOME ${rubyEnv}/${rubyEnv.ruby.gemPath}'' }
-
       ''
       + optionalString (!stdenv.isDarwin) ''
         # copy and patch the original neovim.desktop file
@@ -92,7 +91,29 @@ let
       '' + optionalString viAlias ''
         ln -s $out/bin/nvim $out/bin/vi
       '' + optionalString (configure != {}) ''
-        wrapProgram $out/bin/nvim --add-flags "-u ${vimUtils.vimrcFile configure}"
+        echo "Generating remote plugin manifest"
+        export NVIM_RPLUGIN_MANIFEST=$out/rplugin.vim
+        # Launch neovim with a vimrc file containing only the generated plugin
+        # code. Pass various flags to disable temp file generation
+        # (swap/viminfo) and redirect errors to stderr.
+        # Only display the log on error since it will contain a few normally
+        # irrelevant messages.
+        if ! $out/bin/nvim \
+          -u ${vimUtils.vimrcFile (configure // { customRC = ""; })} \
+          -i NONE -n \
+          -E -V1rplugins.log -s \
+          +UpdateRemotePlugins +quit! > outfile 2>&1; then
+          cat outfile
+          echo -e "\nGenerating rplugin.vim failed!"
+          exit 1
+        fi
+        unset NVIM_RPLUGIN_MANIFEST
+
+        # this relies on a patched neovim, see
+        # https://github.com/neovim/neovim/issues/9413
+        wrapProgram $out/bin/nvim \
+          --set NVIM_SYSTEM_RPLUGIN_MANIFEST $out/rplugin.vim \
+          --add-flags "-u ${vimUtils.vimrcFile configure}"
       '';
 
     preferLocalBuild = true;
diff --git a/pkgs/misc/vim-plugins/vim-utils.nix b/pkgs/misc/vim-plugins/vim-utils.nix
index cf5eeaec3e33..2a758aa98433 100644
--- a/pkgs/misc/vim-plugins/vim-utils.nix
+++ b/pkgs/misc/vim-plugins/vim-utils.nix
@@ -486,4 +486,12 @@ rec {
       });
     vimrcConfig.vam.pluginDictionaries = [ { names = [ "vim-trailing-whitespace" ]; } ];
   };
+
+  # system remote plugin manifest should be generated, deoplete should be usable
+  # without the user having to do `UpdateRemotePlugins`. To test, launch neovim
+  # and do `:call deoplete#enable()`. It will print an error if the remote
+  # plugin is not registered.
+  test_nvim_with_remote_plugin = neovim.override {
+    configure.pathogen.pluginNames = with vimPlugins; [ deoplete-nvim ];
+  };
 }

From 2bc0e00372b60eeb80797f193f6a963ce10a0516 Mon Sep 17 00:00:00 2001
From: Timo Kaufmann <timokau@zoho.com>
Date: Mon, 31 Dec 2018 12:34:46 +0100
Subject: [PATCH 3/3] vimUtils.buildVimPlugin: write vim errors to stderr

Previously vim would silently fail when help tags couldn't be generated.
We need to pass the "verbose" flag (with verbose level 1) to convince
vim to print errors to standard error.
---
 pkgs/misc/vim-plugins/build-vim-plugin.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkgs/misc/vim-plugins/build-vim-plugin.nix b/pkgs/misc/vim-plugins/build-vim-plugin.nix
index fe60ad21c752..b797f49df9e0 100644
--- a/pkgs/misc/vim-plugins/build-vim-plugin.nix
+++ b/pkgs/misc/vim-plugins/build-vim-plugin.nix
@@ -37,7 +37,7 @@ rec {
         # build help tags
         if [ -d "$target/doc" ]; then
           echo "Building help tags"
-          if ! ${vim}/bin/vim -N -u NONE -i NONE -n -E -s -c "helptags $target/doc" +quit!; then
+          if ! ${vim}/bin/vim -N -u NONE -i NONE -n -E -s -V1 -c "helptags $target/doc" +quit!; then
             echo "Failed to build help tags!"
             exit 1
           fi