refactor: move lib out of modules

This commit is contained in:
NotAShelf 2023-02-06 21:57:35 +03:00
parent 206e17bbe4
commit 89be2b9d37
No known key found for this signature in database
GPG key ID: 5B5C8895F28445F1
8 changed files with 334 additions and 0 deletions

9
lib/booleans.nix Normal file
View file

@ -0,0 +1,9 @@
# From home-manager: https://github.com/nix-community/home-manager/blob/master/modules/lib/booleans.nix
{lib}: {
# Converts a boolean to a yes/no string. This is used in lots of
# configuration formats.
yesNo = value:
if value
then "yes"
else "no";
}

107
lib/dag.nix Normal file
View file

@ -0,0 +1,107 @@
# From home-manager: https://github.com/nix-community/home-manager/blob/master/modules/lib/dag.nix
# A generalization of Nixpkgs's `strings-with-deps.nix`.
#
# The main differences from the Nixpkgs version are
#
# - not specific to strings, i.e., any payload is OK,
#
# - the addition of the function `entryBefore` indicating a "wanted
# by" relationship.
{lib}: let
inherit (lib) all filterAttrs nvim mapAttrs toposort;
in {
empty = {};
isEntry = e: e ? data && e ? after && e ? before;
isDag = dag:
builtins.isAttrs dag && all nvim.dag.isEntry (builtins.attrValues dag);
/*
Takes an attribute set containing entries built by entryAnywhere,
entryAfter, and entryBefore to a topologically sorted list of
entries.
Internally this function uses the `toposort` function in
`<nixpkgs/lib/lists.nix>` and its value is accordingly.
Specifically, the result on success is
{ result = [ { name = ?; data = ?; } ] }
For example
nix-repl> topoSort {
a = entryAnywhere "1";
b = entryAfter [ "a" "c" ] "2";
c = entryBefore [ "d" ] "3";
d = entryBefore [ "e" ] "4";
e = entryAnywhere "5";
} == {
result = [
{ data = "1"; name = "a"; }
{ data = "3"; name = "c"; }
{ data = "2"; name = "b"; }
{ data = "4"; name = "d"; }
{ data = "5"; name = "e"; }
];
}
true
And the result on error is
{
cycle = [ { after = ?; name = ?; data = ? } ];
loops = [ { after = ?; name = ?; data = ? } ];
}
For example
nix-repl> topoSort {
a = entryAnywhere "1";
b = entryAfter [ "a" "c" ] "2";
c = entryAfter [ "d" ] "3";
d = entryAfter [ "b" ] "4";
e = entryAnywhere "5";
} == {
cycle = [
{ after = [ "a" "c" ]; data = "2"; name = "b"; }
{ after = [ "d" ]; data = "3"; name = "c"; }
{ after = [ "b" ]; data = "4"; name = "d"; }
];
loops = [
{ after = [ "a" "c" ]; data = "2"; name = "b"; }
];
}
true
*/
topoSort = dag: let
dagBefore = dag: name:
builtins.attrNames
(filterAttrs (n: v: builtins.elem name v.before) dag);
normalizedDag =
mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
})
dag;
before = a: b: builtins.elem a.name b.after;
sorted = toposort before (builtins.attrValues normalizedDag);
in
if sorted ? result
then {
result = map (v: {inherit (v) name data;}) sorted.result;
}
else sorted;
# Applies a function to each element of the given DAG.
map = f: mapAttrs (n: v: v // {data = f n v.data;});
entryBetween = before: after: data: {inherit data before after;};
# Create a DAG entry with no particular dependency information.
entryAnywhere = nvim.dag.entryBetween [] [];
entryAfter = nvim.dag.entryBetween [];
entryBefore = before: nvim.dag.entryBetween before [];
}

5
lib/default.nix Normal file
View file

@ -0,0 +1,5 @@
{lib}: {
dag = import ./dag.nix {inherit lib;};
booleans = import ./booleans.nix {inherit lib;};
types = import ./types.nix {inherit lib;};
}

44
lib/hm-module.nix Normal file
View file

@ -0,0 +1,44 @@
# Home Manager module
{
config,
pkgs,
lib ? pkgs.lib,
...
}: let
cfg = config.programs.neovim-flake;
set = pkgs.neovim-maximal {mainConfig = cfg.settings;};
in
with lib; {
meta.maintainers = [maintainers.notashelf];
options.programs.neovim-flake = {
enable = mkEnableOption "A NeoVim IDE with a focus on configurability and extensibility.";
settings = mkOption {
type = types.attrsOf types.anything;
default = {};
example = literalExpression ''
{
vim.viAlias = false;
vim.vimAlias = true;
vim.lsp = {
enable = true;
formatOnSave = true;
lightbulb.enable = true;
lspsaga.enable = false;
nvimCodeActionMenu.enable = true;
trouble.enable = true;
lspSignature.enable = true;
rust.enable = false;
nix = true;
};
}
'';
description = "Attribute set of neoflake preferences.";
};
};
config = mkIf cfg.enable {
home.packages = [set.neovim];
};
}

13
lib/stdlib-extended.nix Normal file
View file

@ -0,0 +1,13 @@
# From home-manager: https://github.com/nix-community/home-manager/blob/master/modules/lib/stdlib-extended.nix
# Just a convenience function that returns the given Nixpkgs standard
# library extended with the HM library.
nixpkgsLib: let
mkNvimLib = import ./.;
in
nixpkgsLib.extend (self: super: {
nvim = mkNvimLib {lib = self;};
# For forward compatibility.
literalExpression = super.literalExpression or super.literalExample;
literalDocBook = super.literalDocBook or super.literalExample;
})

68
lib/types-dag.nix Normal file
View file

@ -0,0 +1,68 @@
# From home-manager: https://github.com/nix-community/home-manager/blob/master/modules/lib/types-dag.nix
# Used for ordering config text.
{lib}: let
inherit
(lib)
defaultFunctor
nvim
mkIf
mkOrder
mkOption
mkOptionType
types
;
dagEntryOf = elemType: let
submoduleType = types.submodule ({name, ...}: {
options = {
data = mkOption {type = elemType;};
after = mkOption {type = with types; listOf str;};
before = mkOption {type = with types; listOf str;};
};
config = mkIf (elemType.name == "submodule") {
data._module.args.dagName = name;
};
});
maybeConvert = def:
if nvim.dag.isEntry def.value
then def.value
else
nvim.dag.entryAnywhere (
if def ? priority
then mkOrder def.priority def.value
else def.value
);
in
mkOptionType {
name = "dagEntryOf";
description = "DAG entry of ${elemType.description}";
# leave the checking to the submodule type
merge = loc: defs:
submoduleType.merge loc (map (def: {
inherit (def) file;
value = maybeConvert def;
})
defs);
};
in rec {
# A directed acyclic graph of some inner type.
#
# Note, if the element type is a submodule then the `name` argument
# will always be set to the string "data" since it picks up the
# internal structure of the DAG values. To give access to the
# "actual" attribute name a new submodule argument is provided with
# the name `dagName`.
dagOf = elemType: let
attrEquivalent = types.attrsOf (dagEntryOf elemType);
in
mkOptionType rec {
name = "dagOf";
description = "DAG of ${elemType.description}";
inherit (attrEquivalent) check merge emptyValue;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
getSubModules = elemType.getSubModules;
substSubModules = m: dagOf (elemType.substSubModules m);
functor = (defaultFunctor name) // {wrapped = elemType;};
nestedTypes.elemType = elemType;
};
}

81
lib/types-plugin.nix Normal file
View file

@ -0,0 +1,81 @@
{lib}:
with lib; let
# Plugin must be same as input name from flake.nix
availablePlugins = [
# TODO: sort by category
"nvim-treesitter-context"
"gitsigns-nvim"
"plenary-nvim"
"nvim-lspconfig"
"nvim-treesitter"
"lspsaga"
"lspkind"
"nvim-lightbulb"
"lsp-signature"
"nvim-tree-lua"
"nvim-bufferline-lua"
"lualine"
"nvim-compe"
"nvim-autopairs"
"nvim-ts-autotag"
"nvim-web-devicons"
"tokyonight"
"bufdelete-nvim"
"nvim-cmp"
"cmp-nvim-lsp"
"cmp-buffer"
"cmp-vsnip"
"cmp-path"
"cmp-treesitter"
"crates-nvim"
"vim-vsnip"
"nvim-code-action-menu"
"trouble"
"null-ls"
"which-key"
"indent-blankline"
"nvim-cursorline"
"sqls-nvim"
"glow-nvim"
"telescope"
"rust-tools"
"onedark"
"catppuccin"
"minimap-vim"
"dashboard-nvim"
"alpha-nvim"
"scrollbar-nvim"
"codewindow-nvim"
"nvim-notify"
"cinnamon-nvim"
"cheatsheet-nvim"
"colorizer"
"venn-nvim"
"cellular-automaton"
"presence-nvim"
"icon-picker-nvim"
"dressing-nvim"
"orgmode-nvim"
"obsidian-nvim"
"vim-markdown"
"tabular"
"toggleterm-nvim"
"noice-nvim"
"nui-nvim"
"copilot-lua"
"tabnine-nvim"
"nvim-session-manager"
"gesture-nvim"
];
# You can either use the name of the plugin or a package.
pluginsType = with types; listOf (nullOr (either (enum availablePlugins) package));
in {
pluginsOpt = {
description,
default ? [],
}:
mkOption {
inherit description default;
type = pluginsType;
};
}

7
lib/types.nix Normal file
View file

@ -0,0 +1,7 @@
{lib}: let
typesDag = import ./types-dag.nix {inherit lib;};
typesPlugin = import ./types-plugin.nix {inherit lib;};
in {
inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt;
}