inputs: { configuration, pkgs, lib ? pkgs.lib, check ? true, extraSpecialArgs ? {}, extraModules ? [], }: let inherit (builtins) map filter isString toString getAttr; inherit (pkgs) wrapNeovimUnstable vimPlugins; inherit (pkgs.vimUtils) buildVimPlugin; inherit (pkgs.neovimUtils) makeNeovimConfig; inherit (lib.strings) makeBinPath escapeShellArgs concatStringsSep; inherit (lib.lists) concatLists optional; inherit (lib.attrsets) recursiveUpdate; inherit (lib.asserts) assertMsg; # call the extedended library with `lib` and `inputs` as arguments # lib is used to provide the standard library functions to the extended library # but it can be overridden while this file is being called # inputs is used to pass inputs to the plugin autodiscovery function extendedLib = import ../lib/stdlib-extended.nix lib inputs; # import modules.nix with `check`, `pkgs` and `lib` as arguments # check can be disabled while calling this file is called # to avoid checking in all modules nvimModules = import ./modules.nix { inherit check pkgs; lib = extendedLib; }; # evaluate the extended library with the modules # optionally with any additional modules passed by the user module = extendedLib.evalModules { specialArgs = recursiveUpdate {modulesPath = toString ./.;} extraSpecialArgs; modules = concatLists [[configuration] nvimModules extraModules]; }; # alias to the internal configuration vimOptions = module.config.vim; # build a vim plugin with the given name and arguments # if the plugin is nvim-treesitter, warn the user to use buildTreesitterPlug # instead buildPlug = {pname, ...} @ args: assert assertMsg (pname != "nvim-treesitter") "Use buildTreesitterPlug for building nvim-treesitter."; buildVimPlugin (args // { version = "master"; src = getAttr ("plugin-" + pname) inputs; }); buildTreesitterPlug = grammars: vimPlugins.nvim-treesitter.withPlugins (_: grammars); buildConfigPlugins = plugins: map (plug: ( if (isString plug) then ( if (plug == "nvim-treesitter") then (buildTreesitterPlug vimOptions.treesitter.grammars) else if (plug == "flutter-tools-patched") then (buildPlug { pname = "flutter-tools"; patches = [../patches/flutter-tools.patch]; }) else (buildPlug {pname = plug;}) ) else plug )) (filter (f: f != null) plugins); # built (or "normalized") plugins that are modified builtStartPlugins = buildConfigPlugins vimOptions.startPlugins; builtOptPlugins = map (package: { plugin = package; optional = false; }) (buildConfigPlugins vimOptions.optPlugins); plugins = builtStartPlugins ++ builtOptPlugins; # additional Lua and Python3 packages, mapped to their respective functions # to conform to the format makeNeovimConfig expects. end user should # only ever need to pass a list of packages, which are modified # here extraLuaPackages = ps: map (x: ps.${x}) vimOptions.luaPackages; extraPython3Packages = ps: map (x: ps.${x}) vimOptions.python3Packages; extraWrapperArgs = concatStringsSep " " (optional (vimOptions.extraPackages != []) ''--prefix PATH : "${makeBinPath vimOptions.extraPackages}"''); # wrap user's desired neovim package with the desired neovim configuration # using wrapNeovimUnstable and makeNeovimConfig from nixpkgs. # the makeNeovimConfig function takes the following arguments: # - withPython (bool) # - extraPython3Packages (lambda) # - withNodeJs (bool) # - withRuby (bool) # - extraLuaPackages (lambda) # - plugins (list) # - customRC (string) # and returns the wrapped package neovimConfigured = makeNeovimConfig { inherit (vimOptions) viAlias vimAlias withRuby withNodeJs withPython3; inherit plugins extraLuaPackages extraPython3Packages; customRC = vimOptions.builtConfigRC; }; neovim-wrapped = wrapNeovimUnstable vimOptions.package (recursiveUpdate neovimConfigured { wrapperArgs = escapeShellArgs neovimConfigured.wrapperArgs + " " + extraWrapperArgs; }); in { inherit (module) options config; inherit (module._module.args) pkgs; # expose wrapped neovim-package neovim = neovim-wrapped; }