treewide: refactor custom lib, merge lists in hm/nixos module (#323)

* treewide: refactor custom lib, merge lists in hm/nixos module

* lib/types(custom): clarify anythingConcatLists code

---------

Co-authored-by: raf <raf@notashelf.dev>
This commit is contained in:
diniamo 2024-07-12 00:49:44 +02:00 committed by GitHub
parent 0c444830f6
commit 901363d1ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 307 additions and 256 deletions

View file

@ -1,260 +1,240 @@
inputs: let isMaximal: {
modulesWithInputs = import ./modules inputs; config.vim = {
viAlias = true;
neovimConfiguration = { vimAlias = true;
modules ? [], debugMode = {
pkgs, enable = false;
lib ? pkgs.lib, level = 16;
check ? true, logFile = "/tmp/nvim.log";
extraSpecialArgs ? {},
extraModules ? [],
...
}:
modulesWithInputs {
inherit pkgs lib check extraSpecialArgs extraModules;
configuration.imports = modules;
}; };
mainConfig = isMaximal: { spellcheck = {
config.vim = { enable = isMaximal;
viAlias = true; };
vimAlias = true;
debugMode = {
enable = false;
level = 16;
logFile = "/tmp/nvim.log";
};
spellcheck = { lsp = {
formatOnSave = true;
lspkind.enable = false;
lightbulb.enable = true;
lspsaga.enable = false;
nvimCodeActionMenu.enable = isMaximal;
trouble.enable = true;
lspSignature.enable = true;
lsplines.enable = isMaximal;
nvim-docs-view.enable = isMaximal;
};
debugger = {
nvim-dap = {
enable = true;
ui.enable = true;
};
};
languages = {
enableLSP = true;
enableFormat = true;
enableTreesitter = true;
enableExtraDiagnostics = true;
# Nim LSP is broken on Darwin and therefore
# should be disabled by default. Users may still enable
# `vim.languages.vim` to enable it, this does not restrict
# that.
# See: <https://github.com/PMunch/nimlsp/issues/178#issue-2128106096>
nim.enable = false;
nix.enable = true;
markdown.enable = isMaximal;
html.enable = isMaximal;
css.enable = isMaximal;
sql.enable = isMaximal;
java.enable = isMaximal;
ts.enable = isMaximal;
svelte.enable = isMaximal;
go.enable = isMaximal;
elixir.enable = isMaximal;
zig.enable = isMaximal;
ocaml.enable = isMaximal;
python.enable = isMaximal;
dart.enable = isMaximal;
bash.enable = isMaximal;
tailwind.enable = isMaximal;
typst.enable = isMaximal;
clang = {
enable = isMaximal; enable = isMaximal;
lsp.server = "clangd";
}; };
lsp = { rust = {
formatOnSave = true; enable = isMaximal;
lspkind.enable = false; crates.enable = isMaximal;
lightbulb.enable = true;
lspsaga.enable = false;
nvimCodeActionMenu.enable = isMaximal;
trouble.enable = true;
lspSignature.enable = true;
lsplines.enable = isMaximal;
nvim-docs-view.enable = isMaximal;
}; };
};
debugger = { visuals = {
nvim-dap = { enable = true;
enable = true; nvimWebDevicons.enable = true;
ui.enable = true; scrollBar.enable = isMaximal;
}; smoothScroll.enable = true;
}; cellularAutomaton.enable = false;
fidget-nvim.enable = true;
highlight-undo.enable = true;
languages = { indentBlankline = {
enableLSP = true;
enableFormat = true;
enableTreesitter = true;
enableExtraDiagnostics = true;
# Nim LSP is broken on Darwin and therefore
# should be disabled by default. Users may still enable
# `vim.languages.vim` to enable it, this does not restrict
# that.
# See: <https://github.com/PMunch/nimlsp/issues/178#issue-2128106096>
nim.enable = false;
nix.enable = true;
markdown.enable = isMaximal;
html.enable = isMaximal;
css.enable = isMaximal;
sql.enable = isMaximal;
java.enable = isMaximal;
ts.enable = isMaximal;
svelte.enable = isMaximal;
go.enable = isMaximal;
elixir.enable = isMaximal;
zig.enable = isMaximal;
ocaml.enable = isMaximal;
python.enable = isMaximal;
dart.enable = isMaximal;
bash.enable = isMaximal;
tailwind.enable = isMaximal;
typst.enable = isMaximal;
clang = {
enable = isMaximal;
lsp.server = "clangd";
};
rust = {
enable = isMaximal;
crates.enable = isMaximal;
};
};
visuals = {
enable = true; enable = true;
nvimWebDevicons.enable = true; fillChar = null;
scrollBar.enable = isMaximal; eolChar = null;
smoothScroll.enable = true; scope = {
cellularAutomaton.enable = false; enabled = true;
fidget-nvim.enable = true;
highlight-undo.enable = true;
indentBlankline = {
enable = true;
fillChar = null;
eolChar = null;
scope = {
enabled = true;
};
};
cursorline = {
enable = true;
lineTimeout = 0;
}; };
}; };
statusline = { cursorline = {
lualine = {
enable = true;
theme = "catppuccin";
};
};
theme = {
enable = true; enable = true;
name = "catppuccin"; lineTimeout = 0;
style = "mocha";
transparent = false;
}; };
};
autopairs.enable = true; statusline = {
lualine = {
autocomplete = {
enable = true; enable = true;
type = "nvim-cmp"; theme = "catppuccin";
}; };
};
filetree = { theme = {
nvimTree = { enable = true;
enable = true; name = "catppuccin";
}; style = "mocha";
}; transparent = false;
};
tabline = { autopairs.enable = true;
nvimBufferline.enable = true;
};
treesitter.context.enable = true; autocomplete = {
enable = true;
type = "nvim-cmp";
};
binds = { filetree = {
whichKey.enable = true; nvimTree = {
cheatsheet.enable = true;
};
telescope.enable = true;
git = {
enable = true; enable = true;
gitsigns.enable = true; };
gitsigns.codeActions.enable = false; # throws an annoying debug message };
tabline = {
nvimBufferline.enable = true;
};
treesitter.context.enable = true;
binds = {
whichKey.enable = true;
cheatsheet.enable = true;
};
telescope.enable = true;
git = {
enable = true;
gitsigns.enable = true;
gitsigns.codeActions.enable = false; # throws an annoying debug message
};
minimap = {
minimap-vim.enable = false;
codewindow.enable = isMaximal; # lighter, faster, and uses lua for configuration
};
dashboard = {
dashboard-nvim.enable = false;
alpha.enable = isMaximal;
};
notify = {
nvim-notify.enable = true;
};
projects = {
project-nvim.enable = isMaximal;
};
utility = {
ccc.enable = isMaximal;
vim-wakatime.enable = false;
icon-picker.enable = isMaximal;
surround.enable = isMaximal;
diffview-nvim.enable = true;
motion = {
hop.enable = true;
leap.enable = true;
}; };
minimap = { images = {
minimap-vim.enable = false; image-nvim.enable = false;
codewindow.enable = isMaximal; # lighter, faster, and uses lua for configuration
}; };
};
dashboard = { notes = {
dashboard-nvim.enable = false; obsidian.enable = false; # FIXME: neovim fails to build if obsidian is enabled
alpha.enable = isMaximal; orgmode.enable = false;
mind-nvim.enable = isMaximal;
todo-comments.enable = true;
};
terminal = {
toggleterm = {
enable = true;
lazygit.enable = true;
}; };
};
notify = { ui = {
nvim-notify.enable = true; borders.enable = true;
noice.enable = true;
colorizer.enable = true;
modes-nvim.enable = false; # the theme looks terrible with catppuccin
illuminate.enable = true;
breadcrumbs = {
enable = isMaximal;
navbuddy.enable = isMaximal;
}; };
smartcolumn = {
projects = { enable = true;
project-nvim.enable = isMaximal; setupOpts.custom_colorcolumn = {
}; # this is a freeform module, it's `buftype = int;` for configuring column position
nix = "110";
utility = { ruby = "120";
ccc.enable = isMaximal; java = "130";
vim-wakatime.enable = false; go = ["90" "130"];
icon-picker.enable = isMaximal;
surround.enable = isMaximal;
diffview-nvim.enable = true;
motion = {
hop.enable = true;
leap.enable = true;
};
images = {
image-nvim.enable = false;
}; };
}; };
};
notes = { assistant = {
obsidian.enable = false; # FIXME: neovim fails to build if obsidian is enabled chatgpt.enable = false;
orgmode.enable = false; copilot = {
mind-nvim.enable = isMaximal; enable = false;
todo-comments.enable = true; cmp.enable = isMaximal;
}; };
};
terminal = { session = {
toggleterm = { nvim-session-manager.enable = false;
enable = true; };
lazygit.enable = true;
};
};
ui = { gestures = {
borders.enable = true; gesture-nvim.enable = false;
noice.enable = true; };
colorizer.enable = true;
modes-nvim.enable = false; # the theme looks terrible with catppuccin
illuminate.enable = true;
breadcrumbs = {
enable = isMaximal;
navbuddy.enable = isMaximal;
};
smartcolumn = {
enable = true;
setupOpts.custom_colorcolumn = {
# this is a freeform module, it's `buftype = int;` for configuring column position
nix = "110";
ruby = "120";
java = "130";
go = ["90" "130"];
};
};
};
assistant = { comments = {
chatgpt.enable = false; comment-nvim.enable = true;
copilot = { };
enable = false;
cmp.enable = isMaximal;
};
};
session = { presence = {
nvim-session-manager.enable = false; neocord.enable = false;
};
gestures = {
gesture-nvim.enable = false;
};
comments = {
comment-nvim.enable = true;
};
presence = {
neocord.enable = false;
};
}; };
}; };
in {
inherit neovimConfiguration mainConfig;
} }

View file

@ -1,7 +1,7 @@
{ {
inputs, inputs,
pkgs, pkgs,
lib ? import ../lib/stdlib-extended.nix pkgs.lib inputs, lib,
manpageUrls ? pkgs.path + "/doc/manpage-urls.json", manpageUrls ? pkgs.path + "/doc/manpage-urls.json",
... ...
}: let }: let

View file

@ -1,12 +1,18 @@
{ {
description = "A neovim flake with a modular configuration"; description = "A neovim flake with a modular configuration";
outputs = { outputs = {
nixpkgs,
flake-parts, flake-parts,
self, self,
... ...
} @ inputs: } @ inputs: let
flake-parts.lib.mkFlake {inherit inputs;} { # call the extedended library with `inputs`
# inputs is used to get the original standard library, and to pass inputs to the plugin autodiscovery function
lib = import ./lib/stdlib-extended.nix inputs;
in
flake-parts.lib.mkFlake {
inherit inputs;
specialArgs = {inherit lib;};
} {
# provide overridable systems # provide overridable systems
# https://github.com/nix-systems/nix-systems # https://github.com/nix-systems/nix-systems
systems = import inputs.systems; systems = import inputs.systems;
@ -17,36 +23,33 @@
./flake/packages.nix ./flake/packages.nix
]; ];
_module.args = {inherit (nixpkgs) lib;};
flake = { flake = {
lib = { lib = {
inherit (import ./lib/stdlib-extended.nix nixpkgs.lib inputs) nvim; inherit (lib) nvim neovimConfiguration;
inherit (import ./configuration.nix inputs) neovimConfiguration;
}; };
homeManagerModules = { homeManagerModules = {
neovim-flake = neovim-flake =
nixpkgs.lib.warn '' lib.warn ''
homeManagerModules.neovim-flake has been deprecated. homeManagerModules.neovim-flake has been deprecated.
Plese use the homeManagerModules.nvf instead Plese use the homeManagerModules.nvf instead
'' ''
self.homeManagerModules.nvf; self.homeManagerModules.nvf;
nvf = import ./flake/modules/home-manager.nix self.packages inputs; nvf = import ./flake/modules/home-manager.nix self.packages lib;
default = self.homeManagerModules.nvf; default = self.homeManagerModules.nvf;
}; };
nixosModules = { nixosModules = {
neovim-flake = neovim-flake =
nixpkgs.lib.warn '' lib.warn ''
nixosModules.neovim-flake has been deprecated. nixosModules.neovim-flake has been deprecated.
Please use the nixosModules.nvf instead Please use the nixosModules.nvf instead
'' ''
self.nixosModules.nvf; self.nixosModules.nvf;
nvf = import ./flake/modules/nixos.nix self.packages inputs; nvf = import ./flake/modules/nixos.nix self.packages lib;
default = self.nixosModules.nvf; default = self.nixosModules.nvf;
}; };

View file

@ -1,8 +1,7 @@
# Home Manager module # Home Manager module
packages: inputs: { packages: lib: {
config, config,
pkgs, pkgs,
lib ? pkgs.lib,
... ...
}: let }: let
inherit (lib) maintainers; inherit (lib) maintainers;
@ -10,9 +9,10 @@ packages: inputs: {
inherit (lib.lists) optional; inherit (lib.lists) optional;
inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything bool; inherit (lib.types) attrsOf anything bool;
inherit (lib.nvim) neovimConfiguration;
inherit (lib.nvim.types) anythingConcatLists;
cfg = config.programs.nvf; cfg = config.programs.nvf;
inherit (import ../../configuration.nix inputs) neovimConfiguration;
neovimConfigured = neovimConfiguration { neovimConfigured = neovimConfiguration {
inherit pkgs; inherit pkgs;
@ -55,7 +55,7 @@ in {
}; };
settings = mkOption { settings = mkOption {
type = attrsOf anything; type = attrsOf anythingConcatLists;
default = {}; default = {};
description = "Attribute set of nvf preferences."; description = "Attribute set of nvf preferences.";
example = literalExpression '' example = literalExpression ''

View file

@ -1,8 +1,7 @@
# NixOS module # NixOS module
packages: inputs: { packages: lib: {
config, config,
pkgs, pkgs,
lib ? pkgs.lib,
... ...
}: let }: let
inherit (lib) maintainers; inherit (lib) maintainers;
@ -10,9 +9,10 @@ packages: inputs: {
inherit (lib.lists) optional; inherit (lib.lists) optional;
inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything bool; inherit (lib.types) attrsOf anything bool;
inherit (lib.nvim) neovimConfiguration;
inherit (lib.nvim.types) anythingConcatLists;
cfg = config.programs.nvf; cfg = config.programs.nvf;
inherit (import ../../configuration.nix inputs) neovimConfiguration;
neovimConfigured = neovimConfiguration { neovimConfigured = neovimConfiguration {
inherit pkgs; inherit pkgs;
@ -55,7 +55,7 @@ in {
}; };
settings = mkOption { settings = mkOption {
type = attrsOf anything; type = attrsOf anythingConcatLists;
default = {}; default = {};
description = "Attribute set of nvf preferences."; description = "Attribute set of nvf preferences.";
example = literalExpression '' example = literalExpression ''

View file

@ -1,14 +1,14 @@
{ {
inputs,
pkgs, pkgs,
lib,
... ...
}: let }: let
inherit (import ../configuration.nix inputs) neovimConfiguration mainConfig; inherit (lib.nvim) neovimConfiguration;
buildPkg = pkgs: modules: (neovimConfiguration {inherit pkgs modules;}).neovim; buildPkg = pkgs: modules: (neovimConfiguration {inherit pkgs modules;}).neovim;
nixConfig = mainConfig false; nixConfig = import ../configuration.nix false;
maximalConfig = mainConfig true; maximalConfig = import ../configuration.nix true;
in { in {
flake.overlays.default = _final: prev: { flake.overlays.default = _final: prev: {
inherit neovimConfiguration; inherit neovimConfiguration;

View file

@ -2,9 +2,10 @@
perSystem = { perSystem = {
config, config,
pkgs, pkgs,
lib,
... ...
}: let }: let
docs = import ../docs {inherit pkgs inputs;}; docs = import ../docs {inherit pkgs inputs lib;};
in { in {
packages = { packages = {
# Documentation # Documentation

18
lib/configuration.nix Normal file
View file

@ -0,0 +1,18 @@
{
inputs,
lib,
}: let
modulesWithInputs = import ../modules inputs;
in
{
modules ? [],
pkgs,
check ? true,
extraSpecialArgs ? {},
extraModules ? [],
...
}:
modulesWithInputs {
inherit pkgs lib check extraSpecialArgs extraModules;
configuration.imports = modules;
}

View file

@ -12,4 +12,5 @@
lists = import ./lists.nix {inherit lib;}; lists = import ./lists.nix {inherit lib;};
lua = import ./lua.nix {inherit lib;}; lua = import ./lua.nix {inherit lib;};
vim = import ./vim.nix; vim = import ./vim.nix;
neovimConfiguration = import ./configuration.nix {inherit inputs lib;};
} }

View file

@ -1,7 +1,7 @@
# Convenience function that returns the given Nixpkgs standard library # Convenience function that returns the given Nixpkgs standard library
# extended with our functions using `lib.extend`. # extended with our functions using `lib.extend`.
nixpkgsLib: inputs: inputs:
nixpkgsLib.extend (self: super: { inputs.nixpkgs.lib.extend (self: super: {
# WARNING: New functions should not be added here, but to files # WARNING: New functions should not be added here, but to files
# imported by `./default.nix` under their own categories. If your # imported by `./default.nix` under their own categories. If your
# function does not fit to any of the existing categories, create # function does not fit to any of the existing categories, create

53
lib/types/custom.nix Normal file
View file

@ -0,0 +1,53 @@
{lib}: let
inherit (lib) isStringLike showOption showFiles getFiles mergeOneOption mergeEqualOption;
inherit (lib.types) anything attrsOf;
inherit (lib.nvim.types) anythingConcatLists;
inherit (builtins) typeOf isAttrs any head concatLists;
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;
};
}

View file

@ -6,8 +6,10 @@
typesDag = import ./dag.nix {inherit lib;}; typesDag = import ./dag.nix {inherit lib;};
typesPlugin = import ./plugins.nix {inherit inputs lib;}; typesPlugin = import ./plugins.nix {inherit inputs lib;};
typesLanguage = import ./languages.nix {inherit lib;}; typesLanguage = import ./languages.nix {inherit lib;};
typesCustom = import ./custom.nix {inherit lib;};
in { in {
inherit (typesDag) dagOf; inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType; inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType;
inherit (typesLanguage) diagnostics mkGrammarOption; inherit (typesLanguage) diagnostics mkGrammarOption;
inherit (typesCustom) anythingConcatLists;
} }

View file

@ -1,7 +1,7 @@
inputs: { inputs: {
configuration, configuration,
pkgs, pkgs,
lib ? pkgs.lib, lib,
check ? true, check ? true,
extraSpecialArgs ? {}, extraSpecialArgs ? {},
extraModules ? [], extraModules ? [],
@ -15,23 +15,16 @@ inputs: {
inherit (lib.attrsets) recursiveUpdate; inherit (lib.attrsets) recursiveUpdate;
inherit (lib.asserts) assertMsg; 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 # import modules.nix with `check`, `pkgs` and `lib` as arguments
# check can be disabled while calling this file is called # check can be disabled while calling this file is called
# to avoid checking in all modules # to avoid checking in all modules
nvimModules = import ./modules.nix { nvimModules = import ./modules.nix {
inherit pkgs check; inherit pkgs check lib;
lib = extendedLib;
}; };
# evaluate the extended library with the modules # evaluate the extended library with the modules
# optionally with any additional modules passed by the user # optionally with any additional modules passed by the user
module = extendedLib.evalModules { module = lib.evalModules {
specialArgs = recursiveUpdate {modulesPath = toString ./.;} extraSpecialArgs; specialArgs = recursiveUpdate {modulesPath = toString ./.;} extraSpecialArgs;
modules = concatLists [[configuration] nvimModules extraModules]; modules = concatLists [[configuration] nvimModules extraModules];
}; };