lib: add RFC-145 nixdoc comments to extended library functions

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I41c4b2cb70512699a044578fa88eb8266a6a6964
This commit is contained in:
raf 2026-05-20 17:02:36 +03:00
commit a17f043605
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
7 changed files with 506 additions and 19 deletions

View file

@ -1,5 +1,26 @@
{lib}: let
inherit (builtins) listToAttrs;
in {
/**
Map over a list and convert the result to an attribute set.
# Type
```
mapListToAttrs :: (a -> { name :: String; value :: b }) -> [a] -> AttrSet
```
# Arguments
- `f`: Function mapping each list element to a `{ name; value }` pair.
- `list`: The list to map over.
# Example
```nix
mapListToAttrs (x: { name = x; value = x; }) ["a" "b"]
=> { a = "a"; b = "b"; }
```
*/
mapListToAttrs = f: list: listToAttrs (map f list);
}

View file

@ -5,6 +5,28 @@
inherit (lib.attrsets) isAttrs mapAttrs;
binds = rec {
/**
Create a silent Lua keybinding wrapped in `mkIf` to guard against null keys.
# Type
```
mkLuaBinding :: String | Null -> String -> String -> AttrSet
```
# Arguments
- `key`: The key sequence to bind, or `null` to disable.
- `action`: Lua expression to execute on keypress.
- `desc`: Human-readable description of the binding.
# Example
```nix
mkLuaBinding "<leader>f" "require('telescope').find_files" "Find files"
=> { "<leader>f" = { action = "require('telescope').find_files"; desc = "Find files"; lua = true; silent = true; }; }
```
*/
mkLuaBinding = key: action: desc:
mkIf (key != null) {
"${key}" = {
@ -14,6 +36,28 @@
};
};
/**
Create a silent expression-mode Lua keybinding wrapped in `mkIf`.
# Type
```
mkExprBinding :: String | Null -> String -> String -> AttrSet
```
# Arguments
- `key`: The key sequence to bind, or `null` to disable.
- `action`: Lua expression evaluated as a Vim expression.
- `desc`: Human-readable description of the binding.
# Example
```nix
mkExprBinding "<C-n>" "v:count == 0 ? 'j' : 'gj'" "Smart down"
=> { "<C-n>" = { action = "v:count == 0 ? 'j' : 'gj'"; desc = "Smart down"; lua = true; silent = true; expr = true; }; }
```
*/
mkExprBinding = key: action: desc:
mkIf (key != null) {
"${key}" = {
@ -24,6 +68,28 @@
};
};
/**
Create a silent (non-Lua) keybinding wrapped in `mkIf` to guard against null keys.
# Type
```
mkBinding :: String | Null -> String -> String -> AttrSet
```
# Arguments
- `key`: The key sequence to bind, or `null` to disable.
- `action`: Vimscript command or mapping string to execute.
- `desc`: Human-readable description of the binding.
# Example
```nix
mkBinding "<leader>w" ":w<CR>" "Save file"
=> { "<leader>w" = { action = ":w<CR>"; desc = "Save file"; silent = true; }; }
```
*/
mkBinding = key: action: desc:
mkIf (key != null) {
"${key}" = {
@ -32,17 +98,58 @@
};
};
/**
Build a nullable string NixOS option suitable for storing a keybinding value.
# Type
```
mkMappingOption :: String -> String | Null -> Option
```
# Arguments
- `description`: Documentation string for the option.
- `default`: Default key value, or `null` for no binding.
# Example
```nix
mkMappingOption "Toggle file tree" "<leader>e"
=> mkOption { type = nullOr str; default = "<leader>e"; description = "Toggle file tree"; }
```
*/
mkMappingOption = description: default:
mkOption {
type = nullOr str;
inherit default description;
};
# Utility function that takes two attrsets:
# { someKey = "some_value" } and
# { someKey = { description = "Some Description"; }; }
# and merges them into
# { someKey = { value = "some_value"; description = "Some Description"; }; }
/**
Merge actual mapping values with their description metadata.
Takes two attribute sets: one mapping keys to values and another mapping
keys to `{ description }` records. Produces an attribute set mapping
keys to `{ value; description }` records. Nesting is handled recursively.
# Type
```
addDescriptionsToMappings :: AttrSet -> AttrSet -> AttrSet
```
# Arguments
- `actualMappings`: Attribute set of key value pairs.
- `mappingDefinitions`: Attribute set of key `{ description }` pairs.
# Example
```nix
addDescriptionsToMappings { someKey = "some_value"; } { someKey = { description = "Some Description"; }; }
=> { someKey = { value = "some_value"; description = "Some Description"; }; }
```
*/
addDescriptionsToMappings = actualMappings: mappingDefinitions:
mapAttrs (name: value: let
isNested = isAttrs value;
@ -57,17 +164,126 @@
returnedValue)
actualMappings;
/**
Create a non-Lua keybinding from a structured binding record produced by `mkMappingOption`.
# Type
```
mkSetBinding :: { value :: String | Null; description :: String } -> String -> AttrSet
```
# Arguments
- `binding`: Binding record with `value` (key) and `description` fields.
- `action`: Vimscript command or mapping string to execute.
# Example
```nix
mkSetBinding { value = "<leader>w"; description = "Save file"; } ":w<CR>"
=> mkBinding "<leader>w" ":w<CR>" "Save file"
```
*/
mkSetBinding = binding: action:
mkBinding binding.value action binding.description;
/**
Create an expression-mode Lua keybinding from a structured binding record.
# Type
```
mkSetExprBinding :: { value :: String | Null; description :: String } -> String -> AttrSet
```
# Arguments
- `binding`: Binding record with `value` (key) and `description` fields.
- `action`: Lua expression evaluated as a Vim expression.
# Example
```nix
mkSetExprBinding { value = "<C-n>"; description = "Smart down"; } "v:count == 0 ? 'j' : 'gj'"
=> mkExprBinding "<C-n>" "v:count == 0 ? 'j' : 'gj'" "Smart down"
```
*/
mkSetExprBinding = binding: action:
mkExprBinding binding.value action binding.description;
/**
Create a silent Lua keybinding from a structured binding record.
# Type
```
mkSetLuaBinding :: { value :: String | Null; description :: String } -> String -> AttrSet
```
# Arguments
- `binding`: Binding record with `value` (key) and `description` fields.
- `action`: Lua expression to execute on keypress.
# Example
```nix
mkSetLuaBinding { value = "<leader>f"; description = "Find files"; } "require('telescope').find_files"
=> mkLuaBinding "<leader>f" "require('telescope').find_files" "Find files"
```
*/
mkSetLuaBinding = binding: action:
mkLuaBinding binding.value action binding.description;
/**
Apply `mkDefault` to every value in an attribute set.
Useful for lowering the priority of a set of option defaults so they can
be overridden by user configuration.
# Type
```
pushDownDefault :: AttrSet -> AttrSet
```
# Arguments
- `attr`: Attribute set whose values should be wrapped with `mkDefault`.
# Example
```nix
pushDownDefault { a = true; b = "hello"; }
=> { a = mkDefault true; b = mkDefault "hello"; }
```
*/
pushDownDefault = attr: mapAttrs (_: mkDefault) attr;
/**
Build a keymap record by merging extra options with mode, key, and action fields.
# Type
```
mkKeymap :: String -> String -> String -> AttrSet -> AttrSet
```
# Arguments
- `mode`: Vim mode string (e.g. `"n"`, `"v"`, `"i"`).
- `key`: Key sequence to bind.
- `action`: Action to execute on keypress.
- `opt`: Extra options merged into the resulting record.
# Example
```nix
mkKeymap "n" "<leader>w" ":w<CR>" { silent = true; }
=> { mode = "n"; key = "<leader>w"; action = ":w<CR>"; silent = true; }
```
*/
mkKeymap = mode: key: action: opt: opt // {inherit mode key action;};
};
in

View file

@ -5,6 +5,27 @@
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.lists) flatten;
in {
/**
Build a boolean NixOS option with the given default value and description.
# Type
```
mkBool :: Bool -> String -> Option
```
# Arguments
- `value`: Default boolean value for the option.
- `description`: Documentation string for the option.
# Example
```nix
mkBool true "Enable feature X"
=> mkOption { type = bool; default = true; description = "Enable feature X"; }
```
*/
mkBool = value: description:
mkOption {
type = bool;

View file

@ -19,7 +19,7 @@ in {
isDag = dag:
isAttrs dag && all isEntry (attrValues dag);
/*
/**
Takes an attribute set containing entries built by entryAnywhere,
entryAfter, and entryBefore to a topologically sorted list of
entries.
@ -100,12 +100,98 @@ in {
# Applies a function to each element of the given DAG.
map = f: mapAttrs (n: v: v // {data = f n v.data;});
/**
Create a DAG entry with explicit before and after dependency lists.
# Type
```
entryBetween :: [String] -> [String] -> a -> DagEntry a
```
# Arguments
- `before`: List of entry names this entry must come before.
- `after`: List of entry names this entry must come after.
- `data`: Payload for this DAG entry.
# Example
```nix
entryBetween [ "c" ] [ "a" ] "payload"
=> { data = "payload"; before = [ "c" ]; after = [ "a" ]; }
```
*/
entryBetween = before: after: data: {inherit data before after;};
# Create a DAG entry with no particular dependency information.
/**
Create a DAG entry with no ordering constraints.
The entry may be placed anywhere in the topological sort result.
# Type
```
entryAnywhere :: a -> DagEntry a
```
# Arguments
- `data`: Payload for this DAG entry.
# Example
```nix
entryAnywhere "lua code here"
=> { data = "lua code here"; before = []; after = []; }
```
*/
entryAnywhere = entryBetween [] [];
/**
Create a DAG entry that must come after the listed entries.
# Type
```
entryAfter :: [String] -> a -> DagEntry a
```
# Arguments
- `after`: List of entry names this entry must follow.
- `data`: Payload for this DAG entry.
# Example
```nix
entryAfter [ "init" ] "setup code"
=> { data = "setup code"; before = []; after = [ "init" ]; }
```
*/
entryAfter = entryBetween [];
/**
Create a DAG entry that must come before the listed entries.
# Type
```
entryBefore :: [String] -> a -> DagEntry a
```
# Arguments
- `before`: List of entry names this entry must precede.
- `data`: Payload for this DAG entry.
# Example
```nix
entryBefore [ "teardown" ] "cleanup code"
=> { data = "cleanup code"; before = [ "teardown" ]; after = []; }
```
*/
entryBefore = before: entryBetween before [];
# Given a list of entries, this function places them in order within the DAG.

View file

@ -6,6 +6,32 @@
inherit (lib.nvim.types) luaInline;
in {
# TODO: remove
/**
Convert a list of diagnostic provider entries to a DAG-compatible attribute set.
Accepts either plain strings (provider type names) or attrsets with `type`
and `package` fields, and produces named entries suitable for merging into
a null-ls/none-ls DAG.
# Type
```
diagnosticsToLua :: { lang :: String; config :: [String | { type :: String; package :: Derivation }]; diagnosticsProviders :: AttrSet } -> AttrSet
```
# Arguments
- `lang`: Language identifier used to prefix generated entry names.
- `config`: List of provider names (strings) or `{ type; package }` records.
- `diagnosticsProviders`: Attribute set mapping provider type names to `{ package; nullConfig }` records.
# Example
```nix
diagnosticsToLua { lang = "python"; config = [ "flake8" ]; diagnosticsProviders = { flake8 = { package = pkgs.python3Packages.flake8; nullConfig = pkg: "..."; }; }; }
=> { "python-diagnostics-flake8" = "..."; }
```
*/
diagnosticsToLua = {
lang,
config,
@ -27,6 +53,26 @@ in {
})
config;
/**
Build a boolean NixOS option that enables a language feature for all enabled languages.
# Type
```
mkEnable :: String -> Option
```
# Arguments
- `desc`: Short description of the feature being enabled (interpolated into the option description).
# Example
```nix
mkEnable "LSP support"
=> mkOption { default = false; type = bool; description = "Turn on LSP support for enabled languages by default"; }
```
*/
mkEnable = desc:
mkOption {
default = false;
@ -34,6 +80,28 @@ in {
description = "Turn on ${desc} for enabled languages by default";
};
/**
A freeform submodule type for LSP server options.
Provides a structured set of well-known LSP configuration fields
(`enable`, `capabilities`, `on_attach`, `filetypes`, `cmd`, `root_markers`)
while allowing arbitrary extra fields via `freeformType`.
# Type
```
lspOptions :: SubmoduleType
```
# Example
```nix
vim.languages.rust.lsp.options = {
enable = true;
root_markers = [ "Cargo.toml" ];
};
```
*/
lspOptions = submodule {
freeformType = attrsOf anything;
options = {

View file

@ -1,33 +1,34 @@
{lib}: let
inherit (lib.lists) elem all;
in {
/*
Checks if all values are present in the list.
/**
Checks if all values are present in the list.
Type:
# Type
```
listContainsValues :: { list :: [a], values :: [a] } -> Bool
```
Arguments:
list - A list of elements.
values - A list of values to check for presence in the list.
# Arguments
Returns:
True if all values are present in the list, otherwise False.
- `list`: A list of elements.
- `values`: A list of values to check for presence in the list.
# Example
Example:
```nix
listContainsValues { list = [1 2 3]; values = [2 3]; }
=> True
=> true
listContainsValues { list = [1 2 3]; values = [2 4]; }
=> False
=> false
```
*/
listContainsValues = {
list,
values,
}: let
# Check if all values are present in the list
containsValue = value: elem value list;
in
all containsValue values;

View file

@ -1,7 +1,57 @@
# Helpers for converting values to lua
{lib}: let
/**
Test whether an object is a `luaInline` value (i.e. has `_type == "lua-inline"`).
# Type
```
isLuaInline :: Any -> Bool
```
# Arguments
- `object`: Any Nix value.
# Example
```nix
isLuaInline (lib.mkLuaInline "vim.fn.getcwd()")
=> true
isLuaInline "just a string"
=> false
```
*/
isLuaInline = object: (object._type or null) == "lua-inline";
/**
Recursively convert a Nix value to its Lua representation as a string.
Handles all primitive Nix types as well as lists, attribute sets,
derivations (rendered as their store path string), and `luaInline` values
(rendered verbatim). Null attributes are stripped from sets.
# Type
```
toLuaObject :: Any -> String
```
# Arguments
- `args`: Any Nix value to convert.
# Example
```nix
toLuaObject { a = 1; b = true; c = null; }
=> ''{["a"] = 1,\n["b"] = true}''
toLuaObject [ "x" "y" ]
=> ''{"x",\n"y"}''
```
*/
toLuaObject = args:
{
int = toString args;
@ -42,6 +92,30 @@
in
{
inherit isLuaInline toLuaObject;
/**
Convert a list of Lua expression strings into a Lua table string.
Each element is wrapped with `mkLuaInline` before conversion so that
strings are treated as raw Lua rather than quoted string literals.
# Type
```
luaTable :: [String] -> String
```
# Arguments
- `x`: List of Lua expression strings.
# Example
```nix
luaTable [ "vim.fn.getcwd()" "vim.fn.expand('%')" ]
=> ''{vim.fn.getcwd(),\nvim.fn.expand('%')}''
```
*/
luaTable = x: (toLuaObject (map lib.mkLuaInline x));
}
// lib.genAttrs [