init wrapper-module config

This commit is contained in:
Daniel Winkler 2026-01-30 14:22:39 +11:00
commit 91755583fd
46 changed files with 4277 additions and 0 deletions

View file

@ -0,0 +1,51 @@
{
config,
lib,
...
}:
{
options.cats = lib.mkOption {
type = lib.types.attrsOf lib.types.bool;
description = ''
Category toggles used to enable/disable specs by name.
Keys map directly to specs (e.g., `python` controls `specs.python`).
Set a category to `false` to skip its dependency/plugin specs.
Available categories:
- clickhouse: Clickhouse client and tools
- customPlugins: local plugin specs
- external: external tools and integrations
- general: core Neovim plugins/features
- gitPlugins: git-related plugins
- julia: Julia tooling and packages
- lua: Lua tooling and LSPs
- markdown: markdown tooling and plugins
- nix: Nix tooling and plugins
- optional: optional tools and utilities
- python: Python tooling and plugins
- r: R tooling and plugins
- test: test-only tooling (disabled by default)
- treesitterParsers: Treesitter parsers
- utils: general utilities
'';
};
config.cats = {
clickhouse = lib.mkDefault false;
customPlugins = lib.mkDefault true;
external = lib.mkDefault true;
general = lib.mkDefault true;
gitPlugins = lib.mkDefault true;
julia = lib.mkDefault false;
lua = lib.mkDefault false;
markdown = lib.mkDefault false;
nix = lib.mkDefault false;
optional = lib.mkDefault false;
python = lib.mkDefault false;
r = lib.mkDefault false;
test = lib.mkDefault false;
treesitterParsers = lib.mkDefault true;
utils = lib.mkDefault true;
};
}

View file

@ -0,0 +1,35 @@
{
config,
lib,
...
}:
{
# Point to the directory containing init.lua, plugin/, lua/, etc.
config.settings.config_directory = ../../..;
# Default colorscheme and background
config.settings.colorscheme = "kanagawa";
config.settings.background = "dark";
# Enable RC wrapping (allows neovim to find the config)
config.settings.wrapRc = true;
# Lua packages available to neovim (for :lua require())
config.settings.nvim_lua_env = lp:
lib.optionals (config.cats.general or false) [ lp.tiktoken_core ];
# Binary name for the wrapper
config.binName = "n";
# Prevent neovim from loading system-wide config
config.settings.block_normal_config = true;
# Don't symlink the config (we wrap it instead)
config.settings.dont_link = false;
# Create additional aliases for the binary
config.settings.aliases = [ "vim" ];
# Enable wrapper handling of spec runtimeDeps (template pattern).
config.settings.autowrapRuntimeDeps = true;
}

View file

@ -0,0 +1,27 @@
{
config,
pkgs,
lib,
...
}:
{
# Environment variables set for the wrapper.
# These are available when running neovim.
config.env = lib.mkMerge [
(lib.mkIf (config.cats.r or false) {
R_LIBS_USER = "./.Rlibs";
})
(lib.mkIf (config.cats.python or false) {
UV_PYTHON_DOWNLOADS = "never";
UV_PYTHON = pkgs.python.interpreter;
})
(lib.mkIf (config.cats.test or false) {
TESTVAR = "It worked!";
})
];
# Environment variables with defaults (can be overridden by user)
config.envDefault = lib.mkIf (config.cats.test or false) {
TESTVAR2 = "It worked again!";
};
}

View file

@ -0,0 +1,57 @@
{
config,
pkgs,
lib,
...
}:
{
config.hosts = lib.mkMerge [
{
node.nvim-host.enable = true;
perl.nvim-host.enable = true;
ruby.nvim-host.enable = true;
g = {
nvim-host.enable = true;
nvim-host.package = "${pkgs.neovide}/bin/neovide";
nvim-host.argv0 = "neovide";
nvim-host.flags."--neovim-bin" = "${placeholder "out"}/bin/${config.binName}";
};
m = {
nvim-host.enable = false;
nvim-host.package = "${pkgs.uv}/bin/uv";
nvim-host.argv0 = "uv";
nvim-host.addFlag = [
"run"
"marimo"
"edit"
];
};
}
(lib.mkIf (config.cats.julia or true) {
jl = {
nvim-host.enable = true;
nvim-host.package = "${pkgs.julia-bin}/bin/julia";
nvim-host.argv0 = "julia";
nvim-host.addFlag = [
"--project=@."
];
};
})
(lib.mkIf (config.cats.python or true) {
python3.nvim-host.enable = true;
})
(lib.mkIf (config.cats.r or true) {
r = {
nvim-host.enable = true;
nvim-host.package = "${pkgs.rWrapper}/bin/R";
nvim-host.argv0 = "R";
nvim-host.addFlag = [
"--no-save"
"--no-restore"
];
};
})
];
}

View file

@ -0,0 +1,39 @@
{
config,
lib,
...
}:
{
options.settings.lang_packages = lib.mkOption {
type = lib.types.submodule {
options = {
python = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = "Additional Python-related packages appended to the python spec (overlay defaults remain).";
};
r = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = "Additional R-related packages appended to the r spec (overlay defaults remain).";
};
julia = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Additional Julia packages (names) passed to julia-bin.withPackages.";
};
};
};
default = { };
description = ''
Language-specific package overrides appended to each language spec's extraPackages.
Intended for flake.nix overrides via wrapper.config.wrap.
'';
};
config.settings.lang_packages = {
python = lib.mkDefault [ ];
r = lib.mkDefault [ ];
julia = lib.mkDefault [ ];
};
}

View file

@ -0,0 +1,35 @@
{
config,
lib,
...
}:
let
collect_runtime_packages = runtime_deps_type:
config.specCollect
(acc: spec:
let
is_enabled = if spec ? enable then spec.enable else true;
has_runtime_deps = (spec.runtimeDeps or false) == runtime_deps_type;
packages = spec.extraPackages or [ ];
in
acc ++ lib.optionals (is_enabled && has_runtime_deps) packages
)
[ ];
prefix_packages = collect_runtime_packages "prefix";
suffix_packages = collect_runtime_packages "suffix";
to_path_specs = packages: [
{
data = [
"PATH"
":"
"${lib.makeBinPath packages}"
];
}
];
in
{
config.prefixVar = lib.optionals (prefix_packages != [ ]) (to_path_specs prefix_packages);
config.suffixVar = lib.optionals (suffix_packages != [ ]) (to_path_specs suffix_packages);
}

View file

@ -0,0 +1,51 @@
{ config, lib, ... }:
{
# This module implements category-based enabling of specs.
# It runs early (order 200) so other specMaps can see the enable flags.
#
# How it works:
# 1. For each spec, extract its name (removing -lazy suffix if present)
# 2. Check if there's a corresponding cats.<name> toggle
# 3. Set spec.value.enable based on the cats toggle (default: true)
# 4. This allows specs to be conditionally included based on config.cats settings
#
# Example: If config.cats.python = false, then specs.python.enable = false
config.specMaps = lib.mkOrder 200 [
{
name = "CATS_ENABLE";
data =
list:
map (
v:
if v.type == "spec" || v.type == "parent" then
let
# Extract spec name, handling lazy specs (remove -lazy suffix)
specName =
if v.name == null then
null
else if lib.hasSuffix "-lazy" v.name then
lib.removeSuffix "-lazy" v.name
else
v.name;
# Check if this spec has a corresponding cat toggle
catEnabled =
if specName != null && builtins.hasAttr specName config.cats then
config.cats.${specName}
else
true; # Default to enabled if no cat toggle exists
in
v
// {
value = v.value // {
# Use explicit enable if set, otherwise use cat toggle
enable = if v.value ? enable then v.value.enable else catEnabled;
};
}
else
v
) list;
}
];
}

View file

@ -0,0 +1,188 @@
{
config,
pkgs,
lib,
wlib,
...
}: {
# ============================================================================
# SPEC MODULE DEFAULTS
# ============================================================================
# Define default options available to all specs
config.specMods = {parentSpec ? null, ...}: {
options.extraPackages = lib.mkOption {
type = lib.types.listOf wlib.types.stringable;
default = [];
description = "a extraPackages spec field to put packages to suffix to the PATH";
};
};
# ============================================================================
# EXTERNAL TOOLS SPEC
# ============================================================================
# Core system tools and utilities
config.specs.external = {
data = lib.mkDefault null;
before = ["INIT_MAIN"];
config = ''
vim.o.shell = "${pkgs.zsh}/bin/zsh"
'';
runtimeDeps = "prefix";
extraPackages = with pkgs; [
perl
ruby
shfmt
sqlfluff
tree-sitter
];
};
# ============================================================================
# OPTIONAL TOOLS SPEC
# ============================================================================
config.specs.optional = lib.mkIf (config.cats.optional or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
before = ["INIT_MAIN"];
extraPackages = with pkgs; [
bat
broot
devenv
dust
fd
fzf
gawk
gh
git
hunspell
hunspellDicts.de-at
hunspellDicts.en-us
ispell
jq
just
lazygit
man
ncdu
pigz
poppler
ripgrep
tokei
wget
yq
zathura
];
};
# ============================================================================
# MARKDOWN SPEC
# ============================================================================
config.specs.markdown = lib.mkIf (config.cats.markdown or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = with pkgs; [
python313Packages.pylatexenc
quarto
zk
];
};
# ============================================================================
# NIX SPEC
# ============================================================================
config.specs.nix = lib.mkIf (config.cats.nix or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = with pkgs; [
alejandra
nix-doc
nixd
];
};
# ============================================================================
# LUA SPEC
# ============================================================================
config.specs.lua = lib.mkIf (config.cats.lua or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = with pkgs; [
lua-language-server
];
};
# ============================================================================
# PYTHON SPEC
# ============================================================================
config.specs.python = lib.mkIf (config.cats.python or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = let
python_packages_fn =
if pkgs ? basePythonPackages
then ps: pkgs.basePythonPackages ps ++ config.settings.lang_packages.python
else _: config.settings.lang_packages.python;
python_with_packages = pkgs.python3.withPackages python_packages_fn;
in
with pkgs; [
python_with_packages
nodejs
ruff
basedpyright
uv
];
};
# ============================================================================
# R SPEC
# ============================================================================
config.specs.r = lib.mkIf (config.cats.r or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = let
r_packages = (pkgs.baseRPackages or []) ++ config.settings.lang_packages.r;
in
with pkgs; [
(rWrapper.override {packages = r_packages;})
radianWrapper
(quarto.override {extraRPackages = r_packages;})
air-formatter
yaml-language-server
updateR
];
};
# ============================================================================
# JULIA SPEC
# ============================================================================
config.specs.julia = lib.mkIf (config.cats.julia or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = let
julia_with_packages =
pkgs.julia-bin.withPackages config.settings.lang_packages.julia;
in [julia_with_packages];
};
# ============================================================================
# CLICKHOUSE SPEC
# ============================================================================
config.specs.clickhouse = lib.mkIf (config.cats.clickhouse or true) {
data = lib.mkDefault null;
runtimeDeps = "prefix";
extraPackages = with pkgs; [
clickhouse-lts
];
};
config.extraPackages = config.specCollect (acc: v: acc ++ (v.extraPackages or [])) [];
}

View file

@ -0,0 +1,183 @@
{
config,
pkgs,
lib,
...
}:
{
config.specs.gitPlugins = {
data = [ ];
};
config.specs.r = {
data = [
config.nvim-lib.neovimPlugins.r
];
};
config.specs.markdown-lazy = {
lazy = true;
data = [
config.nvim-lib.neovimPlugins.cmp-pandoc-references
];
};
config.specs.r-lazy = {
lazy = true;
data = [
config.nvim-lib.neovimPlugins.cmp-r
];
};
config.specs.general = {
data = with pkgs.vimPlugins; [
lze
lzextras
plenary-nvim
neogit
{
data = mini-nvim;
pname = "mini.nvim";
}
{
data = cyberdream-nvim;
pname = "cyberdream";
}
{
data = onedark-nvim;
pname = "onedark";
}
{
data = tokyonight-nvim;
pname = "tokyonight";
}
{
data = kanagawa-nvim;
pname = "kanagawa";
}
{
data = gruvbox-nvim;
pname = "gruvbox";
}
{
data = nord-nvim;
pname = "nord";
}
{
data = dracula-nvim;
pname = "dracula";
}
{
data = vscode-nvim;
pname = "vscode";
}
{
data = nightfox-nvim;
pname = "nightfox";
}
{
data = catppuccin-nvim;
pname = "catppuccin";
}
];
};
config.specs.lua = {
data = with pkgs.vimPlugins; [
luvit-meta
{
data = lazydev-nvim;
pname = "lazydev";
}
];
};
config.specs.markdown = {
data = with pkgs.vimPlugins; [
quarto-nvim
render-markdown-nvim
{
data = otter-nvim;
pname = "otter";
}
{
data = zk-nvim;
pname = "zk";
}
];
};
config.specs.utils = {
data = with pkgs.vimPlugins; [
blink-cmp
nvim-lspconfig
nvim-treesitter-context
nvim-treesitter-textobjects
{
data = pkgs.codecompanion-nvim;
pname = "codecompanion";
}
];
};
config.specs.treesitterParsers = {
data = with pkgs.vimPlugins.nvim-treesitter-parsers; [
bash
c
cpp
csv
diff
dockerfile
git_config
git_rebase
gitattributes
gitcommit
gitignore
html
javascript
json
julia
latex
lua
luadoc
make
markdown
markdown_inline
nix
python
query
r
rnoweb
regex
sql
toml
vim
vimdoc
xml
yaml
zig
];
};
config.specs.utils-lazy = {
lazy = true;
data = with pkgs.vimPlugins; [
blink-compat
blink-copilot
cmp-cmdline
colorful-menu-nvim
conform-nvim
copilot-lua
nvim-dap
nvim-dap-ui
nvim-dap-virtual-text
nvim-lint
vim-slime
];
};
config.specs.gitPlugins-lazy = {
lazy = true;
data = [ ];
};
}