{ config, lib, pkgs, ... }: let inherit (builtins) filter attrValues; cfg = config.build.neovim; in { imports = [ (lib.mkRenamedOptionModule [ "build" "neovim" "package" ] [ "build" "neovim" "toplevel" ]) ]; options.build.neovim = with lib; with types; { luaConfig = mkOption { type = lines; readOnly = true; internal = true; description = '' Neovim editor lua configuration. ''; }; plugins = mkOption { type = listOf package; readOnly = true; internal = true; }; toplevel = mkOption { type = types.package; internal = true; description = '' Neovim editor derivation with plugins and configurations. ''; }; }; config.build.neovim = { luaConfig = with lib; with nix2lua; toLua (spaceBetween (flatten [ # Global Opts (flip mapAttrsToList config.vim.g (k: set "vim.g.${k}")) # Opts (flip mapAttrsToList config.vim.opt (k: set "vim.opt.${k}")) # Plugins (map (v: v.genConfig) (filter (v: v.enable) (attrValues config.plugin))) # Cmd (optional (config.vim.cmd != "") (call "vim.cmd" config.vim.cmd)) # Autocommands (flip mapAttrsToList config.vim.augroup (k: v: v.genConfig)) # Keymaps (flip map config.vim.keymap.set ({ mode, lhs, rhs, ... } @ vars: let m = if builtins.isList mode then head mode else mode; in if config.vim.keymap._validate."${m}"."${lhs}" == rhs then vars.genConfig else abort "This case should never happen." )) ])); plugins = map (v: v.package) (filter (v: v.enable) (attrValues config.plugin)); toplevel = pkgs.wrapNeovim pkgs.neovim-unwrapped { viAlias = false; vimAlias = false; withPython3 = false; withNodeJs = false; withRuby = false; configure = { customRC = '' lua << EOF ${cfg.luaConfig} EOF ''; packages.myVimPackages = { start = cfg.plugins; }; }; }; }; }