Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove anythingConcatLists #503

Merged
4 changes: 2 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
};

homeManagerModules = {
nvf = import ./flake/modules/home-manager.nix self.packages lib;
nvf = import ./flake/modules/home-manager.nix {inherit lib self;};
default = self.homeManagerModules.nvf;
neovim-flake =
lib.warn ''
Expand All @@ -42,7 +42,7 @@
};

nixosModules = {
nvf = import ./flake/modules/nixos.nix self.packages lib;
nvf = import ./flake/modules/nixos.nix {inherit lib self;};
default = self.nixosModules.nvf;
neovim-flake =
lib.warn ''
Expand Down
24 changes: 15 additions & 9 deletions flake/modules/home-manager.nix
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
# Home Manager module
packages: lib: {
{
self,
lib,
}: {
config,
pkgs,
...
}: let
inherit (self) packages inputs;
inherit (lib) maintainers;
inherit (lib.modules) mkIf mkAliasOptionModule;
inherit (lib.lists) optional;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything bool;
inherit (lib.nvim) neovimConfiguration;
inherit (lib.nvim.types) anythingConcatLists;
inherit (lib.types) anything bool submoduleWith;

cfg = config.programs.nvf;

neovimConfigured = neovimConfiguration {
inherit pkgs;
modules = [cfg.settings];
nvfModule = submoduleWith {
description = "Nvf module";
class = "nvf";
specialArgs = {
inherit pkgs lib inputs;
};
modules = import ../../modules/modules.nix {inherit pkgs lib;};
horriblename marked this conversation as resolved.
Show resolved Hide resolved
};
in {
imports = [
Expand Down Expand Up @@ -55,7 +61,7 @@ in {
};

settings = mkOption {
type = attrsOf anythingConcatLists;
type = nvfModule;
default = {};
description = "Attribute set of nvf preferences.";
example = literalExpression ''
Expand All @@ -78,7 +84,7 @@ in {
};

config = mkIf cfg.enable {
programs.nvf.finalPackage = neovimConfigured.neovim;
programs.nvf.finalPackage = cfg.settings.vim.build.finalPackage;

home = {
sessionVariables = mkIf cfg.defaultEditor {EDITOR = "nvim";};
Expand Down
24 changes: 15 additions & 9 deletions flake/modules/nixos.nix
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
# NixOS module
packages: lib: {
{
self,
lib,
}: {
config,
pkgs,
...
}: let
inherit (self) inputs packages;
inherit (lib) maintainers;
inherit (lib.modules) mkIf mkOverride mkAliasOptionModule;
inherit (lib.lists) optional;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything bool;
inherit (lib.nvim) neovimConfiguration;
inherit (lib.nvim.types) anythingConcatLists;
inherit (lib.types) anything bool submoduleWith;

cfg = config.programs.nvf;

neovimConfigured = neovimConfiguration {
inherit pkgs;
modules = [cfg.settings];
nvfModule = submoduleWith {
description = "Nvf module";
class = "nvf";
specialArgs = {
inherit pkgs lib inputs;
};
modules = import ../../modules/modules.nix {inherit pkgs lib;};
};
in {
imports = [
Expand Down Expand Up @@ -55,7 +61,7 @@ in {
};

settings = mkOption {
type = attrsOf anythingConcatLists;
type = nvfModule;
default = {};
description = "Attribute set of nvf preferences.";
example = literalExpression ''
Expand All @@ -78,7 +84,7 @@ in {
};

config = mkIf cfg.enable {
programs.nvf.finalPackage = neovimConfigured.neovim;
programs.nvf.finalPackage = cfg.settings.vim.build.finalPackage;

environment = {
variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "nvim");
Expand Down
55 changes: 3 additions & 52 deletions lib/types/custom.nix
Original file line number Diff line number Diff line change
@@ -1,57 +1,8 @@
{lib}: let
inherit (lib.options) showOption showFiles getFiles mergeOneOption mergeEqualOption;
inherit (lib.strings) isString isStringLike;
inherit (lib.types) anything attrsOf listOf mkOptionType;
inherit (lib.nvim.types) anythingConcatLists;
inherit (builtins) typeOf isAttrs any head concatLists stringLength match;
inherit (lib.options) mergeEqualOption;
inherit (lib.strings) isString stringLength match;
inherit (lib.types) listOf mkOptionType;
in {
# HACK: Does this break anything in our case?
# A modified version of the nixpkgs anything type that concatenates lists
# This isn't the default because the order in which the lists are concatenated depends on the order in which the modules are imported,
# which makes it non-deterministic
anythingConcatLists =
anything
// {
merge = loc: defs: let
getType = value:
if isAttrs value && isStringLike value
then "stringCoercibleSet"
else typeOf value;

# Throw an error if not all defs have the same type
checkType = getType (head defs).value;
commonType =
if any (def: getType def.value != checkType) defs
then throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}"
else checkType;

mergeFunctions = {
# Recursively merge attribute sets
set = (attrsOf anythingConcatLists).merge;

# Overridden behavior for lists, that concatenates lists
list = _: defs: concatLists (map (e: e.value) defs);

# This means it's a package, only accept a single definition
stringCoercibleSet = mergeOneOption;

# This works by passing the argument to the functions,
# and merging their returns values instead
lambda = loc: defs: arg:
anythingConcatLists.merge
(loc ++ ["<function body>"])
(map (def: {
inherit (def) file;
value = def.value arg;
})
defs);
};
in
# Merge the defs with the correct function from above, if available
# otherwise only allow equal values
(mergeFunctions.${commonType} or mergeEqualOption) loc defs;
};

mergelessListOf = elemType: let
super = listOf elemType;
in
Expand Down
2 changes: 1 addition & 1 deletion lib/types/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ in {
inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType;
inherit (typesLanguage) diagnostics mkGrammarOption;
inherit (customTypes) anythingConcatLists char hexColor mergelessListOf;
inherit (customTypes) char hexColor mergelessListOf;
}
105 changes: 9 additions & 96 deletions modules/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
extraModules ? [],
configuration ? {},
}: let
inherit (pkgs) vimPlugins;
inherit (lib.strings) isString toString;
inherit (lib.lists) filter map concatLists;
inherit (lib.strings) toString;
inherit (lib.lists) concatLists;

# import modules.nix with `check`, `pkgs` and `lib` as arguments
# check can be disabled while calling this file is called
Expand All @@ -21,7 +20,12 @@
# evaluate the extended library with the modules
# optionally with any additional modules passed by the user
module = lib.evalModules {
specialArgs = extraSpecialArgs // {modulesPath = toString ./.;};
specialArgs =
extraSpecialArgs
// {
inherit inputs;
modulesPath = toString ./.;
};
modules = concatLists [
nvimModules
modules
Expand All @@ -36,102 +40,11 @@
extraModules))
];
};

# alias to the internal configuration
vimOptions = module.config.vim;

noBuildPlug = {pname, ...} @ attrs: let
src = inputs."plugin-${attrs.pname}";
in
{
version = src.shortRev or src.shortDirtyRev or "dirty";
outPath = src;
passthru.vimPlugin = false;
}
// attrs;

# build a vim plugin with the given name and arguments
# if the plugin is nvim-treesitter, warn the user to use buildTreesitterPlug
# instead
buildPlug = attrs: let
src = inputs."plugin-${attrs.pname}";
in
pkgs.vimUtils.buildVimPlugin (
{
version = src.shortRev or src.shortDirtyRev or "dirty";
inherit src;
}
// attrs
);

buildTreesitterPlug = grammars: vimPlugins.nvim-treesitter.withPlugins (_: grammars);

pluginBuilders = {
nvim-treesitter = buildTreesitterPlug vimOptions.treesitter.grammars;
flutter-tools-patched = buildPlug {
pname = "flutter-tools";
patches = [../patches/flutter-tools.patch];
};
};

buildConfigPlugins = plugins:
map (
plug:
if (isString plug)
then pluginBuilders.${plug} or (noBuildPlug {pname = plug;})
else plug
) (filter (f: f != null) plugins);

# built (or "normalized") plugins that are modified
builtStartPlugins = buildConfigPlugins vimOptions.startPlugins;
builtOptPlugins = map (package: package // {optional = true;}) (buildConfigPlugins vimOptions.optPlugins);

# additional Lua and Python3 packages, mapped to their respective functions
# to conform to the format mnw 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;

# Wrap the user's desired (unwrapped) Neovim package with arguments that'll be used to
# generate a wrapped Neovim package.
neovim-wrapped = inputs.mnw.lib.wrap pkgs {
neovim = vimOptions.package;
plugins = builtStartPlugins ++ builtOptPlugins;
appName = "nvf";
extraBinPath = vimOptions.extraPackages;
initLua = vimOptions.builtLuaConfigRC;
luaFiles = vimOptions.extraLuaFiles;

inherit (vimOptions) viAlias vimAlias withRuby withNodeJs withPython3;
inherit extraLuaPackages extraPython3Packages;
};

dummyInit = pkgs.writeText "nvf-init.lua" vimOptions.builtLuaConfigRC;
# Additional helper scripts for printing and displaying nvf configuration
# in your commandline.
printConfig = pkgs.writers.writeDashBin "nvf-print-config" "cat ${dummyInit}";
printConfigPath = pkgs.writers.writeDashBin "nvf-print-config-path" "echo -n ${dummyInit}";
in {
inherit (module) options config;
inherit (module._module.args) pkgs;

# Expose wrapped neovim-package for userspace
# or module consumption.
neovim = pkgs.symlinkJoin {
name = "nvf-with-helpers";
paths = [neovim-wrapped printConfig printConfigPath];
postBuild = "echo Helpers added";

# Allow evaluating vimOptions, i.e., config.vim from the packages' passthru
# attribute. For example, packages.x86_64-linux.neovim.passthru.neovimConfig
# will return the configuration in full.
passthru.neovimConfig = vimOptions;

meta =
neovim-wrapped.meta
// {
description = "Wrapped Neovim package with helper scripts to print the config (path)";
};
};
neovim = module.config.vim.build.finalPackage;
}
1 change: 1 addition & 0 deletions modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
# using the configuration passed in `neovim` and `plugins` modules.
wrapper = map (p: ./wrapper + "/${p}") [
"build"
"environment"
"rc"
"warnings"
"lazy"
Expand Down
Loading
Loading