biglybt: 3.5.0.0 -> 3.6.0.0
[NixPkgs.git] / pkgs / applications / editors / neovim / utils.nix
blob865c5219328180e33753c323b1df99cd0869d22b
1 { lib
2 , callPackage
3 , vimUtils
4 , nodejs
5 , neovim-unwrapped
6 , bundlerEnv
7 , ruby
8 , lua
9 , python3Packages
10 , writeText
11 , wrapNeovimUnstable
12 , runCommand
14 let
15   inherit (vimUtils) toVimPlugin;
17    /* returns everything needed for the caller to wrap its own neovim:
18    - the generated content of the future init.vim
19    - the arguments to wrap neovim with
20    The caller is responsible for writing the init.vim and adding it to the wrapped
21    arguments (["-u" writeText "init.vim" GENERATEDRC)]).
22    This makes it possible to write the config anywhere: on a per-project basis
23    .nvimrc or in $XDG_CONFIG_HOME/nvim/init.vim to avoid sideeffects.
24    Indeed, note that wrapping with `-u init.vim` has sideeffects like .nvimrc wont be loaded
25    anymore, $MYVIMRC wont be set etc
26    */
27   makeNeovimConfig =
28     { withPython3 ? true
29     /* the function you would have passed to python3.withPackages */
30     , extraPython3Packages ? (_: [ ])
31     , withNodeJs ? false
32     , withRuby ? true
33     /* the function you would have passed to lua.withPackages */
34     , extraLuaPackages ? (_: [ ])
36     # expects a list of plugin configuration
37     # expects { plugin=far-vim; config = "let g:far#source='rg'"; optional = false; }
38     , plugins ? []
39     # custom viml config appended after plugin-specific config
40     , customRC ? ""
42     # for forward compability, when adding new environments, haskell etc.
43     , ...
44     }@args:
45     let
46       rubyEnv = bundlerEnv {
47         name = "neovim-ruby-env";
48         gemdir = ./ruby_provider;
49         postBuild = ''
50           ln -sf ${ruby}/bin/* $out/bin
51         '';
52       };
54       # transform all plugins into an attrset
55       # { optional = bool; plugin = package; }
56       pluginsNormalized = let
57         defaultPlugin = {
58           plugin = null;
59           config = null;
60           optional = false;
61         };
62       in
63         map (x: defaultPlugin // (if (x ? plugin) then x else { plugin = x; })) plugins;
65       pluginRC = lib.foldl (acc: p: if p.config != null then acc ++ [p.config] else acc) []  pluginsNormalized;
67       pluginsPartitioned = lib.partition (x: x.optional == true) pluginsNormalized;
68       requiredPlugins = vimUtils.requiredPluginsForPackage myVimPackage;
69       getDeps = attrname: map (plugin: plugin.${attrname} or (_: [ ]));
70       myVimPackage = {
71             start = map (x: x.plugin) pluginsPartitioned.wrong;
72             opt = map (x: x.plugin) pluginsPartitioned.right;
73       };
75       pluginPython3Packages = getDeps "python3Dependencies" requiredPlugins;
76       python3Env = python3Packages.python.withPackages (ps:
77         [ ps.pynvim ]
78         ++ (extraPython3Packages ps)
79         ++ (lib.concatMap (f: f ps) pluginPython3Packages));
81       luaEnv = neovim-unwrapped.lua.withPackages(extraLuaPackages);
83       # as expected by packdir
84       packpathDirs.myNeovimPackages = myVimPackage;
85       ## Here we calculate all of the arguments to the 1st call of `makeWrapper`
86       # We start with the executable itself NOTE we call this variable "initial"
87       # because if configure != {} we need to call makeWrapper twice, in order to
88       # avoid double wrapping, see comment near finalMakeWrapperArgs
89       makeWrapperArgs =
90         let
91           binPath = lib.makeBinPath (lib.optionals withRuby [ rubyEnv ] ++ lib.optionals withNodeJs [ nodejs ]);
92         in
93         [
94           "--inherit-argv0"
95         ] ++ lib.optionals withRuby [
96           "--set" "GEM_HOME" "${rubyEnv}/${rubyEnv.ruby.gemPath}"
97         ] ++ lib.optionals (binPath != "") [
98           "--suffix" "PATH" ":" binPath
99         ] ++ lib.optionals (luaEnv != null) [
100           "--prefix" "LUA_PATH" ";" (neovim-unwrapped.lua.pkgs.luaLib.genLuaPathAbsStr luaEnv)
101           "--prefix" "LUA_CPATH" ";" (neovim-unwrapped.lua.pkgs.luaLib.genLuaCPathAbsStr luaEnv)
102         ];
104       manifestRc = vimUtils.vimrcContent ({ customRC = ""; }) ;
105       # we call vimrcContent without 'packages' to avoid the init.vim generation
106       neovimRcContent = vimUtils.vimrcContent ({
107         beforePlugins = "";
108         customRC = lib.concatStringsSep "\n" (pluginRC ++ [customRC]);
109         packages = null;
110       });
111     in
113     builtins.removeAttrs args ["plugins"] // {
114       wrapperArgs = makeWrapperArgs;
115       inherit packpathDirs;
116       inherit neovimRcContent;
117       inherit manifestRc;
118       inherit python3Env;
119       inherit luaEnv;
120       inherit withNodeJs;
121     } // lib.optionalAttrs withRuby {
122       inherit rubyEnv;
123     };
126   # to keep backwards compatibility for people using neovim.override
127   legacyWrapper = neovim: {
128     extraMakeWrapperArgs ? ""
129     /* the function you would have passed to python.withPackages */
130     , extraPythonPackages ? (_: [])
131     /* the function you would have passed to python.withPackages */
132     , withPython3 ? true,  extraPython3Packages ? (_: [])
133     /* the function you would have passed to lua.withPackages */
134     , extraLuaPackages ? (_: [])
135     , withNodeJs ? false
136     , withRuby ? true
137     , vimAlias ? false
138     , viAlias ? false
139     , configure ? {}
140     , extraName ? ""
141   }:
142     let
144       # we convert from the old configure.format to
145       plugins = if builtins.hasAttr "plug" configure then
146           throw "The neovim legacy wrapper doesn't support configure.plug anymore, please setup your plugins via 'configure.packages' instead"
147         else
148           lib.flatten (lib.mapAttrsToList genPlugin (configure.packages or {}));
149       genPlugin = packageName: {start ? [], opt ? []}:
150         start ++ (map (p: { plugin = p; optional = true; }) opt);
152       res = makeNeovimConfig {
153         inherit withPython3;
154         inherit extraPython3Packages;
155         inherit extraLuaPackages;
156         inherit withNodeJs withRuby viAlias vimAlias;
157         customRC = configure.customRC or "";
158         inherit plugins;
159         inherit extraName;
160       };
161     in
162     wrapNeovimUnstable neovim (res // {
163       wrapperArgs = lib.escapeShellArgs res.wrapperArgs + " " + extraMakeWrapperArgs;
164       wrapRc = (configure != {});
165   });
167   /* Generate vim.g.<LANG>_host_prog lua rc to setup host providers
169   Mapping a boolean argument to a key that tells us whether to add
170       vim.g.<LANG>_host_prog=$out/bin/nvim-<LANG>
171   Or this:
172       let g:loaded_${prog}_provider=0
173   While the latter tells nvim that this provider is not available */
174   generateProviderRc = {
175       withPython3 ? true
176     , withNodeJs ? false
177     , withRuby ? true
178     # perl is problematic https://github.com/NixOS/nixpkgs/issues/132368
179     , withPerl ? false
181     # so that we can pass the full neovim config while ignoring it
182     , ...
183     }: let
184       hostprog_check_table = {
185         node = withNodeJs;
186         python = false;
187         python3 = withPython3;
188         ruby = withRuby;
189         perl = withPerl;
190       };
192       genProviderCommand = prog: withProg:
193         if withProg then
194           "vim.g.${prog}_host_prog='${placeholder "out"}/bin/nvim-${prog}'"
195         else
196           "vim.g.loaded_${prog}_provider=0";
198       hostProviderLua = lib.mapAttrsToList genProviderCommand hostprog_check_table;
199     in
200         lib.concatStringsSep ";" hostProviderLua;
202   buildNeovimPlugin = callPackage ./build-neovim-plugin.nix {
203     inherit (vimUtils) toVimPlugin;
204     inherit lua;
205   };
207   grammarToPlugin = grammar:
208     let
209       name = lib.pipe grammar [
210         lib.getName
212         # added in buildGrammar
213         (lib.removeSuffix "-grammar")
215         # grammars from tree-sitter.builtGrammars
216         (lib.removePrefix "tree-sitter-")
217         (lib.replaceStrings [ "-" ] [ "_" ])
218       ];
219     in
221     toVimPlugin (runCommand "vimplugin-treesitter-grammar-${name}"
222       {
223         meta = {
224           platforms = lib.platforms.all;
225         } // grammar.meta;
226       }
227       ''
228         mkdir -p $out/parser
229         ln -s ${grammar}/parser $out/parser/${name}.so
230       '');
234   inherit makeNeovimConfig;
235   inherit generateProviderRc;
236   inherit legacyWrapper;
237   inherit grammarToPlugin;
239   inherit buildNeovimPlugin;
240   buildNeovimPluginFrom2Nix = lib.warn "buildNeovimPluginFrom2Nix was renamed to buildNeovimPlugin" buildNeovimPlugin;