From e9c99811d4b8684814608c7bff89dd5bb4d20cda Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sun, 3 May 2026 16:35:56 +1000 Subject: [PATCH 01/28] feat(devshell): add language tools conditionally based on cats - Extract mkWrapperConfig to share cats/settings between package and devshell - Add python, R, julia, and markdown packages to devShells when their cats are enabled - Reuse same package construction logic as specs/deps.nix for consistency - Keep lang_packages overridable via lib.mkDefault for downstream flakes --- flake.nix | 120 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 32 deletions(-) diff --git a/flake.nix b/flake.nix index cce0107..6dc8545 100644 --- a/flake.nix +++ b/flake.nix @@ -36,45 +36,58 @@ wrappers, ... } @ inputs: let + mkWrapperConfig = pkgs: { + cats = { + clickhouse = false; + gitPlugins = true; + julia = false; + lua = true; + markdown = false; + nix = true; + optional = false; + python = false; + r = false; + }; + settings = { + lang_packages = { + python = with pkgs.python3Packages; [ + duckdb + polars + ]; + r = with pkgs.rpkgs.rPackages; [ + arrow + broom + data_table + janitor + styler + ]; + julia = ["DataFramesMeta" "QuackIO"]; + }; + colorscheme = "cyberdream"; + background = "dark"; + wrapRc = true; + }; + binName = "vv"; + }; + wrapperSettings = pkgs: let + cfg = mkWrapperConfig pkgs; def = pkgs.lib.mkDefault; in wrapper.config.wrap { inherit pkgs; - cats = { - clickhouse = def false; - gitPlugins = def true; - julia = def false; - lua = def true; - markdown = def false; - nix = def true; - optional = def false; - python = def false; - r = def false; - }; - + cats = pkgs.lib.mapAttrs (_: v: def v) cfg.cats; settings = { lang_packages = { - python = with pkgs.python3Packages; [ - duckdb - polars - ]; - - r = with pkgs.rpkgs.rPackages; [ - arrow - broom - data_table - janitor - styler - ]; - - julia = ["DataFramesMeta" "QuackIO"]; + python = def cfg.settings.lang_packages.python; + r = def cfg.settings.lang_packages.r; + julia = def cfg.settings.lang_packages.julia; }; - colorscheme = def "cyberdream"; - background = def "dark"; - wrapRc = def true; + colorscheme = def cfg.settings.colorscheme; + background = def cfg.settings.background; + wrapRc = def cfg.settings.wrapRc; }; - binName = def "vv"; + binName = def cfg.binName; }; systems = [ @@ -146,12 +159,55 @@ devShells = forAllSystems ( system: let pkgs = mkPkgs system; + cfg = mkWrapperConfig pkgs; nvimPkg = wrapperSettings pkgs; + + pythonPackages = let + python_packages_fn = + if pkgs ? basePythonPackages + then ps: pkgs.basePythonPackages ps ++ cfg.settings.lang_packages.python + else _: cfg.settings.lang_packages.python; + in + with pkgs; [ + (python3.withPackages python_packages_fn) + nodejs + ruff + basedpyright + uv + ]; + + rPackages = let + r_packages = (pkgs.baseRPackages or []) ++ cfg.settings.lang_packages.r; + in + with pkgs; [ + (rWrapper.override {packages = r_packages;}) + radianWrapper + (quarto.override {extraRPackages = r_packages;}) + air-formatter + yaml-language-server + updateR + ]; + + juliaPackages = let + julia_with_packages = pkgs.julia-bin.withPackages cfg.settings.lang_packages.julia; + in [julia_with_packages]; + + markdownPackages = with pkgs; [ + python313Packages.pylatexenc + quarto + zk + ]; + + shellPackages = [nvimPkg] + ++ pkgs.lib.optionals cfg.cats.python pythonPackages + ++ pkgs.lib.optionals cfg.cats.r rPackages + ++ pkgs.lib.optionals cfg.cats.julia juliaPackages + ++ pkgs.lib.optionals cfg.cats.markdown markdownPackages; in { default = pkgs.mkShell { name = "vShell"; - packages = [nvimPkg]; - nativeBuildInputs = with pkgs; [] ++ (pkgs.lib.optionals self.wrappers.default.cats.optional [devenv]); + packages = shellPackages; + nativeBuildInputs = with pkgs; [] ++ (pkgs.lib.optionals cfg.cats.optional [devenv]); inputsFrom = []; shellHook = ""; }; From ed24f176bc7bdb3a042d8fbca9a5e9a1fa165209 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sun, 3 May 2026 16:58:11 +1000 Subject: [PATCH 02/28] feat(r): add R languageserver for Neovim LSP - Add languageserver to settings.lang_packages.r - Enable r_language_server in LSP config (plugin/25_lsp.lua) --- flake.nix | 1 + plugin/25_lsp.lua | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/flake.nix b/flake.nix index 6dc8545..f7db07c 100644 --- a/flake.nix +++ b/flake.nix @@ -59,6 +59,7 @@ broom data_table janitor + languageserver styler ]; julia = ["DataFramesMeta" "QuackIO"]; diff --git a/plugin/25_lsp.lua b/plugin/25_lsp.lua index 8c67295..9591da3 100644 --- a/plugin/25_lsp.lua +++ b/plugin/25_lsp.lua @@ -15,17 +15,17 @@ now_if_args(function() marksman = { filetypes = { "markdown", "markdown_inline", "codecompanion" }, }, - -- r_language_server = { - -- filetypes = { 'r', 'rmd', 'rmarkdown' }, - -- settings = { - -- ['r_language_server'] = { - -- lsp = { - -- rich_documentation = true, - -- enable = true, - -- }, - -- }, - -- } - -- }, + r_language_server = { + filetypes = { 'r', 'rmd', 'rmarkdown' }, + settings = { + ['r_language_server'] = { + lsp = { + rich_documentation = true, + enable = true, + }, + }, + } + }, julials = { settings = { julia = { From 4884bf685f157da4f4d60f8e40febeac0b9bf0e9 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 7 May 2026 10:48:37 +1000 Subject: [PATCH 03/28] up --- flake.lock | 19 ++++++++++--------- flake.nix | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index 78a5bd8..32a6765 100644 --- a/flake.lock +++ b/flake.lock @@ -22,11 +22,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1776169885, - "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", + "lastModified": 1777954456, + "narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", + "rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1", "type": "github" }, "original": { @@ -55,15 +55,16 @@ "plugins-r": { "flake": false, "locked": { - "lastModified": 1776340770, - "narHash": "sha256-o/8UZIc/Bq9dWTjA+MpSR5uMUpE7KHTErk+TwWID8Ww=", + "lastModified": 1776905071, + "narHash": "sha256-dXox6qEs1VDE7vPNDoN8bY4g06uj1IEs6uki72w8lpA=", "owner": "R-nvim", "repo": "R.nvim", - "rev": "b9cfffeb9b4e484aa9e13f01c0eb80230aada455", + "rev": "582f2af11290ac067e49018db38e12a511325556", "type": "github" }, "original": { "owner": "R-nvim", + "ref": "v0.99.4", "repo": "R.nvim", "type": "github" } @@ -101,11 +102,11 @@ ] }, "locked": { - "lastModified": 1776375800, - "narHash": "sha256-/SSAR77Brr9fbapsh1cb2K47JXCbvwS1GjM4yyDxle8=", + "lastModified": 1777991014, + "narHash": "sha256-0DS24OW9d9iz+w0LCz6KpS2IpE2z2gHxeBdMZg9xpDY=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "f11469ca69068bac13d9e163b2bd268cc06dff57", + "rev": "dc5184095ad488e937ec308b52c9c0b218959d8b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index f7db07c..8482605 100644 --- a/flake.nix +++ b/flake.nix @@ -20,7 +20,7 @@ }; "plugins-r" = { - url = "github:R-nvim/R.nvim"; + url = "github:R-nvim/R.nvim/v0.99.4"; flake = false; }; From 07d2156dfb4620e8e18b4d1244a17b7fde4f91da Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Tue, 12 May 2026 15:58:31 +1000 Subject: [PATCH 04/28] fixed R.nvim --- .commandcode/taste/taste.md | 8 ++++++++ flake.nix | 13 ++++++++++--- modules/module/settings/cats.nix | 2 +- modules/module/settings/env.nix | 7 ++++++- modules/module/specs/plugins.nix | 8 +++++++- overlays/r.nix | 28 +++++++++++++++++++++++++++- plugin/21_datascience.lua | 6 ++++++ 7 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 .commandcode/taste/taste.md diff --git a/.commandcode/taste/taste.md b/.commandcode/taste/taste.md new file mode 100644 index 0000000..4b588b2 --- /dev/null +++ b/.commandcode/taste/taste.md @@ -0,0 +1,8 @@ +# nix +- For R.nvim in the Nix wrapper, both RNVIM_COMPLDIR (C server compilation) and a writable R_LIBS_USER directory (nvimcom R package installation) must be configured — fixing only one leaves permission errors in the other. Confidence: 0.65 +- For R.nvim writable directories (RNVIM_COMPLDIR, R_LIBS_USER, TMPDIR), prefer project-local paths (e.g., $PWD/.Rlibs) over global cache paths — the cache approach may let the build succeed but still fail at runtime. Confidence: 0.70 + +# Taste (Continuously Learned by [CommandCode][cmd]) + +[cmd]: https://commandcode.ai/ + diff --git a/flake.nix b/flake.nix index 8482605..be28255 100644 --- a/flake.nix +++ b/flake.nix @@ -46,7 +46,7 @@ nix = true; optional = false; python = false; - r = false; + r = true; }; settings = { lang_packages = { @@ -199,7 +199,8 @@ zk ]; - shellPackages = [nvimPkg] + shellPackages = + [nvimPkg] ++ pkgs.lib.optionals cfg.cats.python pythonPackages ++ pkgs.lib.optionals cfg.cats.r rPackages ++ pkgs.lib.optionals cfg.cats.julia juliaPackages @@ -210,7 +211,13 @@ packages = shellPackages; nativeBuildInputs = with pkgs; [] ++ (pkgs.lib.optionals cfg.cats.optional [devenv]); inputsFrom = []; - shellHook = ""; + shellHook = '' + echo 'I am a NixShell' + export R_HOME=$(R RHOME) + export R_LIBS_SITE=$(strings "$(command -v R)" | grep -oP '/nix/store/[^:]+/library' | sort -u | paste -sd: -) + export R_LIBS_USER="$PWD/.r-libs" + mkdir -p "$R_LIBS_USER" + ''; }; } ); diff --git a/modules/module/settings/cats.nix b/modules/module/settings/cats.nix index 22b3638..3da043e 100644 --- a/modules/module/settings/cats.nix +++ b/modules/module/settings/cats.nix @@ -43,7 +43,7 @@ nix = lib.mkDefault true; optional = lib.mkDefault false; python = lib.mkDefault false; - r = lib.mkDefault false; + r = lib.mkDefault true; test = lib.mkDefault false; treesitterParsers = lib.mkDefault true; utils = lib.mkDefault true; diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index 2ae4b9c..0749ede 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -11,12 +11,17 @@ UV_PYTHON_DOWNLOADS = "never"; UV_PYTHON = pkgs.python.interpreter; }) + (lib.mkIf (config.cats.r or false) { + RNVIM_COMPLDIR = "$PWD/.r-compl"; + R_LIBS_USER = "${pkgs.nvimcom}:$PWD/.Rlibs"; + TMPDIR = "$PWD/.r-tmp"; + }) ]; # Environment variables with defaults (can be overridden by user) config.envDefault = lib.mkMerge [ (lib.mkIf (config.cats.r or false) { - R_LIBS_USER = "./.Rlibs"; + R_LIBS_USER = "${pkgs.nvimcom}:$PWD/.Rlibs"; }) ]; } diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index ded8195..eb9d499 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -11,7 +11,13 @@ config.specs.r = { data = with pkgs.vimPlugins; [ - config.nvim-lib.neovimPlugins.r + (config.nvim-lib.neovimPlugins.r.overrideAttrs (old: { + postInstall = (old.postInstall or "") + '' + mkdir -p $out/rnvimserver + cp ${pkgs.nvimcom}/bin/rnvimserver $out/rnvimserver/rnvimserver + chmod +x $out/rnvimserver/rnvimserver + ''; + })) quarto-nvim { data = otter-nvim; diff --git a/overlays/r.nix b/overlays/r.nix index 2fb71c8..22c42fa 100644 --- a/overlays/r.nix +++ b/overlays/r.nix @@ -33,12 +33,38 @@ overlays = [inputs.fran.overlays.default]; }; # rixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system}; + # Pre-build nvimcom from R.nvim plugin source so R.nvim never tries to + # compile it at runtime into the read-only nix store. + nvimcom = final.stdenv.mkDerivation { + pname = "nvimcom"; + version = "0.9.92"; + src = inputs.plugins-r; + nativeBuildInputs = [ + (rpkgs.rWrapper.override { packages = []; }) + ]; + buildPhase = '' + mkdir -p $out/bin + R CMD INSTALL -l $out nvimcom + cd rnvimserver + $CC -pthread -O2 -Wall \ + complete.c resolve.c hover.c definition.c signature.c \ + rhelp.c chunk.c roxygen.c data_structures.c logging.c \ + rnvimserver.c obbr.c tcp.c utilities.c ../nvimcom/src/common.c \ + -o $out/bin/rnvimserver + cd .. + mkdir -p $out/nvimcom/bin + cp $out/bin/rnvimserver $out/nvimcom/bin/rnvimserver + chmod +x $out/bin/rnvimserver $out/nvimcom/bin/rnvimserver + ''; + installPhase = "true"; + }; + # Standard R packages used by default in rWrapper and quarto reqPkgs = with rpkgs.rPackages; [ # languageserver ]; in { - inherit rpkgs; + inherit rpkgs nvimcom; baseRPackages = reqPkgs; # R wrapper with standard packages diff --git a/plugin/21_datascience.lua b/plugin/21_datascience.lua index 118ee20..62d8f49 100644 --- a/plugin/21_datascience.lua +++ b/plugin/21_datascience.lua @@ -44,6 +44,12 @@ end) -- r now(function() if nix.get_cat("r", false) then + local cwd = vim.fn.getcwd(-1) + vim.env.RNVIM_COMPLDIR = cwd .. "/.r-compl" + vim.env.R_LIBS_USER = (vim.env.R_LIBS_USER or ""):gsub("%$PWD", cwd) + vim.env.TMPDIR = cwd .. "/.r-tmp" + vim.fn.mkdir(vim.env.RNVIM_COMPLDIR, "p") + vim.fn.mkdir(vim.env.TMPDIR, "p") vim.g.rout_follow_colorscheme = true require("r").setup({ -- Create a table with the options to be passed to setup() From 1055522af932f5c781ff475cb390143534d49141 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Wed, 13 May 2026 12:30:17 +1000 Subject: [PATCH 05/28] moved r-nvim to flake build --- .Rprofile | 5 ++++ .r-tmp/R.nvim-daniel/globenv_1202824815 | 0 .r-tmp/R.nvim-daniel/liblist_1202824815 | 0 flake.lock | 38 ++++++++++++++++++++----- flake.nix | 9 +++++- modules/module/settings/env.nix | 4 +-- modules/module/specs/plugins.nix | 2 +- overlays/default.nix | 4 +++ overlays/r.nix | 29 ++----------------- 9 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 .Rprofile create mode 100644 .r-tmp/R.nvim-daniel/globenv_1202824815 create mode 100644 .r-tmp/R.nvim-daniel/liblist_1202824815 diff --git a/.Rprofile b/.Rprofile new file mode 100644 index 0000000..7617f61 --- /dev/null +++ b/.Rprofile @@ -0,0 +1,5 @@ +if (Sys.getenv("RNVIM_TMPDIR") == "") { + options(defaultPackages = c("utils", "grDevices", "graphics", "stats", "methods")) +} else { + options(defaultPackages = c("utils", "grDevices", "graphics", "stats", "methods", "nvimcom")) +} diff --git a/.r-tmp/R.nvim-daniel/globenv_1202824815 b/.r-tmp/R.nvim-daniel/globenv_1202824815 new file mode 100644 index 0000000..e69de29 diff --git a/.r-tmp/R.nvim-daniel/liblist_1202824815 b/.r-tmp/R.nvim-daniel/liblist_1202824815 new file mode 100644 index 0000000..e69de29 diff --git a/flake.lock b/flake.lock index 32a6765..bf489c1 100644 --- a/flake.lock +++ b/flake.lock @@ -22,11 +22,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1777954456, - "narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=", + "lastModified": 1778443072, + "narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=", "owner": "nixos", "repo": "nixpkgs", - "rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1", + "rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32", "type": "github" }, "original": { @@ -69,6 +69,29 @@ "type": "github" } }, + "r-nvim-nix": { + "inputs": { + "nixpkgs": [ + "rixpkgs" + ], + "rnvimsrc": [ + "plugins-r" + ] + }, + "locked": { + "lastModified": 1778638679, + "narHash": "sha256-+mdjgYfyNtI/5E6X8uUx3u9qpGC9POS4LagOHSM3Iy0=", + "owner": "dwinkler1", + "repo": "r_nvim_nix", + "rev": "eb784558e18b8f1dead5bd211b96fd287ac1bed7", + "type": "github" + }, + "original": { + "owner": "dwinkler1", + "repo": "r_nvim_nix", + "type": "github" + } + }, "rixpkgs": { "locked": { "lastModified": 1771303851, @@ -80,8 +103,8 @@ }, "original": { "owner": "dwinkler1", - "ref": "nixpkgs", "repo": "rixpkgs", + "rev": "af2dd3f7b4b172077747c0869d4e30702fb71b0e", "type": "github" } }, @@ -91,6 +114,7 @@ "nixpkgs": "nixpkgs", "plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references", "plugins-r": "plugins-r", + "r-nvim-nix": "r-nvim-nix", "rixpkgs": "rixpkgs", "wrappers": "wrappers" } @@ -102,11 +126,11 @@ ] }, "locked": { - "lastModified": 1777991014, - "narHash": "sha256-0DS24OW9d9iz+w0LCz6KpS2IpE2z2gHxeBdMZg9xpDY=", + "lastModified": 1778560014, + "narHash": "sha256-Hu9RMo7vJt/4dx/vAvyG+cE9RBwpaH1ouyunvruYaDI=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "dc5184095ad488e937ec308b52c9c0b218959d8b", + "rev": "e30aa99c9c7038e16efae3cad7916a47307a9e36", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index be28255..1ffa69a 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,11 @@ url = "github:BirdeeHub/nix-wrapper-modules"; inputs.nixpkgs.follows = "nixpkgs"; }; - rixpkgs.url = "github:dwinkler1/rixpkgs/nixpkgs"; + rixpkgs.url = "github:dwinkler1/rixpkgs/af2dd3f7b4b172077747c0869d4e30702fb71b0e"; + + r-nvim-nix.url = "github:dwinkler1/r_nvim_nix"; + r-nvim-nix.inputs.rnvimsrc.follows = "plugins-r"; + r-nvim-nix.inputs.nixpkgs.follows = "rixpkgs"; fran = { url = "github:dwinkler1/fran"; @@ -61,6 +65,7 @@ janitor languageserver styler + pkgs.nvimcom ]; julia = ["DataFramesMeta" "QuackIO"]; }; @@ -187,6 +192,8 @@ air-formatter yaml-language-server updateR + nvimcom + rnvimserver ]; juliaPackages = let diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index 0749ede..14e0a32 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -13,7 +13,7 @@ }) (lib.mkIf (config.cats.r or false) { RNVIM_COMPLDIR = "$PWD/.r-compl"; - R_LIBS_USER = "${pkgs.nvimcom}:$PWD/.Rlibs"; + R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; TMPDIR = "$PWD/.r-tmp"; }) ]; @@ -21,7 +21,7 @@ # Environment variables with defaults (can be overridden by user) config.envDefault = lib.mkMerge [ (lib.mkIf (config.cats.r or false) { - R_LIBS_USER = "${pkgs.nvimcom}:$PWD/.Rlibs"; + R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; }) ]; } diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index eb9d499..a47ba65 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -14,7 +14,7 @@ (config.nvim-lib.neovimPlugins.r.overrideAttrs (old: { postInstall = (old.postInstall or "") + '' mkdir -p $out/rnvimserver - cp ${pkgs.nvimcom}/bin/rnvimserver $out/rnvimserver/rnvimserver + cp ${pkgs.rnvimserver}/bin/rnvimserver $out/rnvimserver/rnvimserver chmod +x $out/rnvimserver/rnvimserver ''; })) diff --git a/overlays/default.nix b/overlays/default.nix index 821ff88..ebb6518 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -3,12 +3,14 @@ let lib = nixpkgs.lib; rOverlay = import ./r.nix {inherit inputs;}; + rNvimNixOverlay = inputs.r-nvim-nix.overlays.default; franOverlay = inputs.fran.overlays.default; pythonOverlay = import ./python.nix inputs; pluginsOverlay = import ./plugins.nix inputs; dependencyOverlays = [ rOverlay + rNvimNixOverlay pythonOverlay pluginsOverlay ]; @@ -17,6 +19,7 @@ in { inherit rOverlay + rNvimNixOverlay franOverlay pythonOverlay pluginsOverlay @@ -30,6 +33,7 @@ in overlays = { inherit rOverlay + rNvimNixOverlay franOverlay pythonOverlay pluginsOverlay diff --git a/overlays/r.nix b/overlays/r.nix index 22c42fa..a9961fb 100644 --- a/overlays/r.nix +++ b/overlays/r.nix @@ -33,38 +33,15 @@ overlays = [inputs.fran.overlays.default]; }; # rixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system}; - # Pre-build nvimcom from R.nvim plugin source so R.nvim never tries to - # compile it at runtime into the read-only nix store. - nvimcom = final.stdenv.mkDerivation { - pname = "nvimcom"; - version = "0.9.92"; - src = inputs.plugins-r; - nativeBuildInputs = [ - (rpkgs.rWrapper.override { packages = []; }) - ]; - buildPhase = '' - mkdir -p $out/bin - R CMD INSTALL -l $out nvimcom - cd rnvimserver - $CC -pthread -O2 -Wall \ - complete.c resolve.c hover.c definition.c signature.c \ - rhelp.c chunk.c roxygen.c data_structures.c logging.c \ - rnvimserver.c obbr.c tcp.c utilities.c ../nvimcom/src/common.c \ - -o $out/bin/rnvimserver - cd .. - mkdir -p $out/nvimcom/bin - cp $out/bin/rnvimserver $out/nvimcom/bin/rnvimserver - chmod +x $out/bin/rnvimserver $out/nvimcom/bin/rnvimserver - ''; - installPhase = "true"; - }; + # nvimcom and rnvimserver are provided by the r-nvim-nix flake overlay + # (inputs.r-nvim-nix.overlays.default) # Standard R packages used by default in rWrapper and quarto reqPkgs = with rpkgs.rPackages; [ # languageserver ]; in { - inherit rpkgs nvimcom; + inherit rpkgs; baseRPackages = reqPkgs; # R wrapper with standard packages From 55866137ba5379c266defbb50f3fd9b40fe1a8b2 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Wed, 13 May 2026 12:30:36 +1000 Subject: [PATCH 06/28] cleanup --- .r-tmp/R.nvim-daniel/globenv_1202824815 | 0 .r-tmp/R.nvim-daniel/liblist_1202824815 | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .r-tmp/R.nvim-daniel/globenv_1202824815 delete mode 100644 .r-tmp/R.nvim-daniel/liblist_1202824815 diff --git a/.r-tmp/R.nvim-daniel/globenv_1202824815 b/.r-tmp/R.nvim-daniel/globenv_1202824815 deleted file mode 100644 index e69de29..0000000 diff --git a/.r-tmp/R.nvim-daniel/liblist_1202824815 b/.r-tmp/R.nvim-daniel/liblist_1202824815 deleted file mode 100644 index e69de29..0000000 From 22809d94cd5f03cde3150d93b6e3b385cca738f6 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Wed, 13 May 2026 13:28:55 +1000 Subject: [PATCH 07/28] update --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index bf489c1..7f552ab 100644 --- a/flake.lock +++ b/flake.lock @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1778638679, - "narHash": "sha256-+mdjgYfyNtI/5E6X8uUx3u9qpGC9POS4LagOHSM3Iy0=", + "lastModified": 1778641093, + "narHash": "sha256-Cq0spPQCYJkyHFTBTXqjmbq663kIVZA63/TQkTzE4ps=", "owner": "dwinkler1", "repo": "r_nvim_nix", - "rev": "eb784558e18b8f1dead5bd211b96fd287ac1bed7", + "rev": "435103d25d56dbe43197f7969cf535fda17ff597", "type": "github" }, "original": { From 8811591fe0eabed342283e897bc25536a67fdca4 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 14 May 2026 00:52:03 +1000 Subject: [PATCH 08/28] Move to bundled R.nvim + rnvimserver without override --- flake.lock | 12 ++++++------ modules/module/specs/plugins.nix | 8 +------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/flake.lock b/flake.lock index 7f552ab..73686b6 100644 --- a/flake.lock +++ b/flake.lock @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1778641093, - "narHash": "sha256-Cq0spPQCYJkyHFTBTXqjmbq663kIVZA63/TQkTzE4ps=", + "lastModified": 1778683425, + "narHash": "sha256-bY44RR+7q+8R8PDNWbavFEcpSKiBvWyoWHI7iSLvsQc=", "owner": "dwinkler1", "repo": "r_nvim_nix", - "rev": "435103d25d56dbe43197f7969cf535fda17ff597", + "rev": "e54fb57802fa9eca81024762f397ec7caa446842", "type": "github" }, "original": { @@ -126,11 +126,11 @@ ] }, "locked": { - "lastModified": 1778560014, - "narHash": "sha256-Hu9RMo7vJt/4dx/vAvyG+cE9RBwpaH1ouyunvruYaDI=", + "lastModified": 1778662548, + "narHash": "sha256-e6XKnrzKr48r1UdCr+5bekibSqe2L1/Sgi46IODHtGQ=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "e30aa99c9c7038e16efae3cad7916a47307a9e36", + "rev": "46e7c1e3f0e149b28f539eb8601152db8a67ad0c", "type": "github" }, "original": { diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index a47ba65..ca8d970 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -11,13 +11,7 @@ config.specs.r = { data = with pkgs.vimPlugins; [ - (config.nvim-lib.neovimPlugins.r.overrideAttrs (old: { - postInstall = (old.postInstall or "") + '' - mkdir -p $out/rnvimserver - cp ${pkgs.rnvimserver}/bin/rnvimserver $out/rnvimserver/rnvimserver - chmod +x $out/rnvimserver/rnvimserver - ''; - })) + pkgs.r-nvim quarto-nvim { data = otter-nvim; From 4d28d0d4907c2d3d20bdf0c5b2482ccc860114dc Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Tue, 19 May 2026 13:15:29 +1000 Subject: [PATCH 09/28] fix for codecompanion --- flake.lock | 18 +++++++++--------- flake.nix | 2 +- modules/module/specs/plugins.nix | 11 ++++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 73686b6..9fbb80f 100644 --- a/flake.lock +++ b/flake.lock @@ -22,11 +22,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1778443072, - "narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=", + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1778683425, - "narHash": "sha256-bY44RR+7q+8R8PDNWbavFEcpSKiBvWyoWHI7iSLvsQc=", + "lastModified": 1778684156, + "narHash": "sha256-Z4y1tQfkIsPK4NRxGn668HMDfWxnxNxSJ0CAOOXiIfY=", "owner": "dwinkler1", "repo": "r_nvim_nix", - "rev": "e54fb57802fa9eca81024762f397ec7caa446842", + "rev": "2f49dfee27886068e2f49cbd54558ce4cc424c82", "type": "github" }, "original": { @@ -126,11 +126,11 @@ ] }, "locked": { - "lastModified": 1778662548, - "narHash": "sha256-e6XKnrzKr48r1UdCr+5bekibSqe2L1/Sgi46IODHtGQ=", + "lastModified": 1779145538, + "narHash": "sha256-j2RQqBLYhPuddU6C8n5hGKboXq1tDLCZ7bWe5/LgTHM=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "46e7c1e3f0e149b28f539eb8601152db8a67ad0c", + "rev": "597b35c93dd0ab0ae38758e3193582b2fd259aa1", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 1ffa69a..fa1140a 100644 --- a/flake.nix +++ b/flake.nix @@ -105,7 +105,7 @@ forAllSystems = nixpkgs.lib.genAttrs systems; extra_pkg_config = { - # allowUnfree = true; + allowUnfree = true; }; overlayDefs = import ./overlays inputs; diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index ca8d970..431005d 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -3,10 +3,9 @@ pkgs, lib, ... -}: -{ +}: { config.specs.gitPlugins = { - data = [ ]; + data = []; }; config.specs.r = { @@ -112,7 +111,9 @@ nvim-treesitter-context nvim-treesitter-textobjects { - data = pkgs.codecompanion-nvim; + data = pkgs.codecompanion-nvim.overrideAttrs (old: { + doCheck = false; + }); pname = "codecompanion"; } ]; @@ -176,6 +177,6 @@ config.specs.gitPlugins-lazy = { lazy = true; - data = [ ]; + data = []; }; } From bfd4ba417d3f385436974b5388981994116a13d0 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Tue, 19 May 2026 13:18:29 +1000 Subject: [PATCH 10/28] remove languageserver package from config --- plugin/25_lsp.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugin/25_lsp.lua b/plugin/25_lsp.lua index 9591da3..8c67295 100644 --- a/plugin/25_lsp.lua +++ b/plugin/25_lsp.lua @@ -15,17 +15,17 @@ now_if_args(function() marksman = { filetypes = { "markdown", "markdown_inline", "codecompanion" }, }, - r_language_server = { - filetypes = { 'r', 'rmd', 'rmarkdown' }, - settings = { - ['r_language_server'] = { - lsp = { - rich_documentation = true, - enable = true, - }, - }, - } - }, + -- r_language_server = { + -- filetypes = { 'r', 'rmd', 'rmarkdown' }, + -- settings = { + -- ['r_language_server'] = { + -- lsp = { + -- rich_documentation = true, + -- enable = true, + -- }, + -- }, + -- } + -- }, julials = { settings = { julia = { From ad9473a9166fc7e220449c9fd7625f8c52e05423 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Tue, 19 May 2026 13:28:40 +1000 Subject: [PATCH 11/28] different ls --- plugin/25_lsp.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugin/25_lsp.lua b/plugin/25_lsp.lua index 8c67295..f3c4c50 100644 --- a/plugin/25_lsp.lua +++ b/plugin/25_lsp.lua @@ -15,17 +15,17 @@ now_if_args(function() marksman = { filetypes = { "markdown", "markdown_inline", "codecompanion" }, }, - -- r_language_server = { - -- filetypes = { 'r', 'rmd', 'rmarkdown' }, - -- settings = { - -- ['r_language_server'] = { - -- lsp = { - -- rich_documentation = true, - -- enable = true, - -- }, - -- }, - -- } - -- }, + r_ls = { + filetypes = { 'r', 'rmd', 'rmarkdown' }, + settings = { + ['r_ls'] = { + lsp = { + rich_documentation = true, + enable = true, + }, + }, + } + }, julials = { settings = { julia = { From 74600519a5f4a73a96b44156b2f4c5b273d2268b Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 21 May 2026 18:45:36 +1000 Subject: [PATCH 12/28] Simplified codebase --- .commandcode/taste/taste.md | 1 + flake.lock | 6 +- flake.nix | 105 ++++++++-------------- modules/module/settings/cats.nix | 6 +- modules/module/settings/core.nix | 6 +- modules/module/settings/env.nix | 6 +- modules/module/settings/hosts.nix | 2 +- modules/module/settings/lang-packages.nix | 2 +- modules/module/settings/runtime-path.nix | 4 +- modules/module/specs/cats-enable.nix | 51 ----------- modules/module/specs/deps.nix | 66 +++----------- modules/module/specs/plugins.nix | 20 ++--- modules/neovim.nix | 16 ---- overlays/default.nix | 24 ++--- overlays/r.nix | 48 +--------- 15 files changed, 83 insertions(+), 280 deletions(-) delete mode 100644 modules/module/specs/cats-enable.nix diff --git a/.commandcode/taste/taste.md b/.commandcode/taste/taste.md index 4b588b2..54e4488 100644 --- a/.commandcode/taste/taste.md +++ b/.commandcode/taste/taste.md @@ -1,6 +1,7 @@ # nix - For R.nvim in the Nix wrapper, both RNVIM_COMPLDIR (C server compilation) and a writable R_LIBS_USER directory (nvimcom R package installation) must be configured — fixing only one leaves permission errors in the other. Confidence: 0.65 - For R.nvim writable directories (RNVIM_COMPLDIR, R_LIBS_USER, TMPDIR), prefer project-local paths (e.g., $PWD/.Rlibs) over global cache paths — the cache approach may let the build succeed but still fail at runtime. Confidence: 0.70 +- Do not use lib.mkDefault on values consumed by lib.optionals or other boolean-checking functions — mkDefault wraps values in a priority set that fails "expected a Boolean" at evaluation time. Use plain booleans for inline conditionals, reserving mkDefault for module options resolved by the merge system. Confidence: 0.70 # Taste (Continuously Learned by [CommandCode][cmd]) diff --git a/flake.lock b/flake.lock index 9fbb80f..698ccf9 100644 --- a/flake.lock +++ b/flake.lock @@ -126,11 +126,11 @@ ] }, "locked": { - "lastModified": 1779145538, - "narHash": "sha256-j2RQqBLYhPuddU6C8n5hGKboXq1tDLCZ7bWe5/LgTHM=", + "lastModified": 1779297405, + "narHash": "sha256-VFoBwH7ZjVxCnvZTb5ODRXt70sLtWMxstive0N+RS50=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "597b35c93dd0ab0ae38758e3193582b2fd259aa1", + "rev": "e7ed7a1205945befdf2e0d73ba7df91d935e5af1", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index fa1140a..f84715f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,11 +1,10 @@ -# Copyright (c) 2026 BirdeeHub +# Copyright (c) 2026 Daniel # Licensed under the MIT license { description = "Daniel's NixCats"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - #nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; wrappers = { url = "github:BirdeeHub/nix-wrapper-modules"; inputs.nixpkgs.follows = "nixpkgs"; @@ -40,13 +39,15 @@ wrappers, ... } @ inputs: let - mkWrapperConfig = pkgs: { - cats = { + mkWrapperConfig = pkgs: let + def = pkgs.lib.mkDefault; + in { + cats = pkgs.lib.mapAttrs (_: v: def v) { clickhouse = false; gitPlugins = true; julia = false; lua = true; - markdown = false; + markdown = true; nix = true; optional = false; python = false; @@ -54,46 +55,30 @@ }; settings = { lang_packages = { - python = with pkgs.python3Packages; [ + python = def (with pkgs.python3Packages; [ duckdb polars - ]; - r = with pkgs.rpkgs.rPackages; [ + ]); + r = def ((with pkgs.rpkgs.rPackages; [ arrow broom data_table janitor languageserver styler - pkgs.nvimcom - ]; - julia = ["DataFramesMeta" "QuackIO"]; + ]) ++ [ pkgs.nvimcom ]); + julia = def ["DataFramesMeta" "QuackIO"]; }; - colorscheme = "cyberdream"; - background = "dark"; - wrapRc = true; }; - binName = "vv"; + binName = def "vv"; }; wrapperSettings = pkgs: let cfg = mkWrapperConfig pkgs; - def = pkgs.lib.mkDefault; in wrapper.config.wrap { inherit pkgs; - cats = pkgs.lib.mapAttrs (_: v: def v) cfg.cats; - settings = { - lang_packages = { - python = def cfg.settings.lang_packages.python; - r = def cfg.settings.lang_packages.r; - julia = def cfg.settings.lang_packages.julia; - }; - colorscheme = def cfg.settings.colorscheme; - background = def cfg.settings.background; - wrapRc = def cfg.settings.wrapRc; - }; - binName = def cfg.binName; + inherit (cfg) cats settings binName; }; systems = [ @@ -104,54 +89,39 @@ forAllSystems = nixpkgs.lib.genAttrs systems; - extra_pkg_config = { - allowUnfree = true; - }; - overlayDefs = import ./overlays inputs; - dependencyOverlays = overlayDefs.dependencyOverlays; - - dependencyOverlay = overlayDefs.dependencyOverlay; - mkPkgs = system: import nixpkgs { inherit system; - config = extra_pkg_config; - overlays = [dependencyOverlay]; + config = { allowUnfree = true; }; + overlays = [ overlayDefs.dependencyOverlay ]; }; - module = nixpkgs.lib.modules.importApply ./modules/neovim.nix inputs; + module = (import ./modules/neovim.nix) inputs; wrapper = wrappers.lib.evalModule module; in { overlays = { + # overlay `vv` wraps the module with default settings only. + # For the fully-configured binary (including mkWrapperConfig overrides), + # use `packages..default` instead. default = nixpkgs.lib.composeManyExtensions [ - dependencyOverlay + overlayDefs.dependencyOverlay (final: prev: { vv = wrapper.config.wrap {pkgs = final;}; }) ]; - dependencies = dependencyOverlay; - vv = self.overlays.default; + dependencies = overlayDefs.dependencyOverlay; }; - wrapperModules = { - default = module; - neovim = self.wrapperModules.default; - }; - - wrappers = { - default = wrapper.config; - neovim = self.wrappers.default; - }; + wrapperModules.default = module; + wrapperConfigs.default = wrapper.config; packages = forAllSystems ( system: let pkgs = mkPkgs system; - nvimPkg = wrapperSettings pkgs; in { - default = nvimPkg; - vv = nvimPkg; + default = wrapperSettings pkgs; } ); @@ -208,16 +178,15 @@ shellPackages = [nvimPkg] - ++ pkgs.lib.optionals cfg.cats.python pythonPackages - ++ pkgs.lib.optionals cfg.cats.r rPackages - ++ pkgs.lib.optionals cfg.cats.julia juliaPackages - ++ pkgs.lib.optionals cfg.cats.markdown markdownPackages; + ++ pkgs.lib.optionals wrapper.config.cats.python pythonPackages + ++ pkgs.lib.optionals wrapper.config.cats.r rPackages + ++ pkgs.lib.optionals wrapper.config.cats.julia juliaPackages + ++ pkgs.lib.optionals wrapper.config.cats.markdown markdownPackages; in { default = pkgs.mkShell { name = "vShell"; packages = shellPackages; - nativeBuildInputs = with pkgs; [] ++ (pkgs.lib.optionals cfg.cats.optional [devenv]); - inputsFrom = []; + nativeBuildInputs = pkgs.lib.optionals wrapper.config.cats.optional [ pkgs.devenv ]; shellHook = '' echo 'I am a NixShell' export R_HOME=$(R RHOME) @@ -234,18 +203,11 @@ pkgs = mkPkgs system; nvimPkg = wrapperSettings pkgs; in { - default = nvimPkg; - module-eval = let - _ = wrapper.config; - in - pkgs.runCommand "check-module-eval" {} '' - echo "Module evaluation successful" > $out - ''; - package-build = pkgs.runCommand "check-vv" {} '' + default = pkgs.runCommand "check-vv" {} '' BINARY_PATH="${nvimPkg}/bin/vv" if [ ! -x "$BINARY_PATH" ]; then - echo "Error: Binary n not found or not executable" + echo "Error: Binary not found or not executable" exit 1 fi @@ -258,6 +220,11 @@ cat version_output.txt >> $out fi ''; + module-eval = + let _ = wrapper.config; + in pkgs.runCommand "check-module-eval" {} '' + echo "Module evaluation successful" > $out + ''; } ); diff --git a/modules/module/settings/cats.nix b/modules/module/settings/cats.nix index 3da043e..13758d4 100644 --- a/modules/module/settings/cats.nix +++ b/modules/module/settings/cats.nix @@ -14,7 +14,6 @@ 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 @@ -25,7 +24,6 @@ - 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 ''; @@ -33,18 +31,16 @@ 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 true; - markdown = lib.mkDefault false; + markdown = lib.mkDefault true; nix = lib.mkDefault true; optional = lib.mkDefault false; python = lib.mkDefault false; r = lib.mkDefault true; - test = lib.mkDefault false; treesitterParsers = lib.mkDefault true; utils = lib.mkDefault true; }; diff --git a/modules/module/settings/core.nix b/modules/module/settings/core.nix index 42e9e11..ec9bb5c 100644 --- a/modules/module/settings/core.nix +++ b/modules/module/settings/core.nix @@ -16,7 +16,7 @@ # Lua packages available to neovim (for :lua require()) config.settings.nvim_lua_env = lp: - lib.optionals (config.cats.general or false) [ lp.tiktoken_core ]; + lib.optionals (config.cats.general or true) [ lp.tiktoken_core ]; # Binary name for the wrapper config.binName = lib.mkDefault "vv"; @@ -25,10 +25,10 @@ config.settings.block_normal_config = true; # Don't symlink the config (we wrap it instead) - config.settings.dont_link = false; + config.settings.dont_link = lib.mkDefault false; # Create additional aliases for the binary - config.settings.aliases = [ "vvim" ]; + config.settings.aliases = lib.mkDefault [ "vvim" ]; # Enable wrapper handling of spec runtimeDeps (template pattern). config.settings.autowrapRuntimeDeps = true; diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index 14e0a32..2fcab8a 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -7,11 +7,11 @@ # Environment variables set for the wrapper. # These are available when running neovim. config.env = lib.mkMerge [ - (lib.mkIf (config.cats.python or false) { + (lib.mkIf (config.cats.python or true) { UV_PYTHON_DOWNLOADS = "never"; UV_PYTHON = pkgs.python.interpreter; }) - (lib.mkIf (config.cats.r or false) { + (lib.mkIf (config.cats.r or true) { RNVIM_COMPLDIR = "$PWD/.r-compl"; R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; TMPDIR = "$PWD/.r-tmp"; @@ -20,7 +20,7 @@ # Environment variables with defaults (can be overridden by user) config.envDefault = lib.mkMerge [ - (lib.mkIf (config.cats.r or false) { + (lib.mkIf (config.cats.r or true) { R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; }) ]; diff --git a/modules/module/settings/hosts.nix b/modules/module/settings/hosts.nix index 0743979..f248a00 100644 --- a/modules/module/settings/hosts.nix +++ b/modules/module/settings/hosts.nix @@ -15,7 +15,7 @@ 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}"; + nvim-host.flags."--neovim-bin" = "${builtins.placeholder "out"}/bin/${config.binName}"; }; m = { diff --git a/modules/module/settings/lang-packages.nix b/modules/module/settings/lang-packages.nix index 3315363..531b811 100644 --- a/modules/module/settings/lang-packages.nix +++ b/modules/module/settings/lang-packages.nix @@ -26,7 +26,7 @@ }; default = { }; description = '' - Language-specific package overrides appended to each language spec's extraPackages. + Language-specific package overrides appended to each language spec's runtimePackages. Intended for flake.nix overrides via wrapper.config.wrap. ''; }; diff --git a/modules/module/settings/runtime-path.nix b/modules/module/settings/runtime-path.nix index 96c5d0f..b321019 100644 --- a/modules/module/settings/runtime-path.nix +++ b/modules/module/settings/runtime-path.nix @@ -10,14 +10,13 @@ let 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 [ ]; + packages = spec.runtimePackages 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: [ { @@ -31,5 +30,4 @@ let in { config.prefixVar = lib.optionals (prefix_packages != [ ]) (to_path_specs prefix_packages); - config.suffixVar = lib.optionals (suffix_packages != [ ]) (to_path_specs suffix_packages); } diff --git a/modules/module/specs/cats-enable.nix b/modules/module/specs/cats-enable.nix deleted file mode 100644 index f5a9826..0000000 --- a/modules/module/specs/cats-enable.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ 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. 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; - } - ]; -} diff --git a/modules/module/specs/deps.nix b/modules/module/specs/deps.nix index a8bfaf6..c3a40ea 100644 --- a/modules/module/specs/deps.nix +++ b/modules/module/specs/deps.nix @@ -5,24 +5,14 @@ wlib, ... }: { - # ============================================================================ - # SPEC MODULE DEFAULTS - # ============================================================================ - # Define default options available to all specs - config.specMods = {parentSpec ? null, ...}: { - options.extraPackages = lib.mkOption { + options.runtimePkgs = lib.mkOption { type = lib.types.listOf wlib.types.stringable; default = []; - description = "a extraPackages spec field to put packages to suffix to the PATH"; + description = "a runtimePkgs 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"]; @@ -30,7 +20,7 @@ vim.o.shell = "${pkgs.zsh}/bin/zsh" ''; runtimeDeps = "prefix"; - extraPackages = with pkgs; [ + runtimePkgs = with pkgs; [ perl ruby shfmt @@ -39,15 +29,11 @@ ]; }; - # ============================================================================ - # 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; [ + runtimePkgs = with pkgs; [ bat broot devenv @@ -76,54 +62,38 @@ ]; }; - # ============================================================================ - # MARKDOWN SPEC - # ============================================================================ - config.specs.markdown = lib.mkIf (config.cats.markdown or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - extraPackages = with pkgs; [ + runtimePkgs = 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; [ + runtimePkgs = 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; [ + runtimePkgs = 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 + runtimePkgs = let python_packages_fn = if pkgs ? basePythonPackages then ps: pkgs.basePythonPackages ps ++ config.settings.lang_packages.python @@ -139,14 +109,10 @@ ]; }; - # ============================================================================ - # R SPEC - # ============================================================================ - config.specs.r = lib.mkIf (config.cats.r or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - extraPackages = let + runtimePkgs = let r_packages = (pkgs.baseRPackages or []) ++ config.settings.lang_packages.r; in with pkgs; [ @@ -159,30 +125,22 @@ ]; }; - # ============================================================================ - # JULIA SPEC - # ============================================================================ - config.specs.julia = lib.mkIf (config.cats.julia or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - extraPackages = let + runtimePkgs = 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; [ + runtimePkgs = with pkgs; [ clickhouse-lts ]; }; - config.extraPackages = config.specCollect (acc: v: acc ++ (v.extraPackages or [])) []; + config.runtimePkgs = config.specCollect (acc: v: acc ++ (v.runtimePkgs or [])) []; } diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index 431005d..ff00a72 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -4,11 +4,11 @@ lib, ... }: { - config.specs.gitPlugins = { + config.specs.gitPlugins = lib.mkIf (config.cats.gitPlugins or true) { data = []; }; - config.specs.r = { + config.specs.r = lib.mkIf (config.cats.r or true) { data = with pkgs.vimPlugins; [ pkgs.r-nvim quarto-nvim @@ -19,14 +19,14 @@ ]; }; - config.specs.markdown-lazy = { + config.specs.markdown-lazy = lib.mkIf (config.cats.markdown or true) { lazy = true; data = [ config.nvim-lib.neovimPlugins.cmp-pandoc-references ]; }; - config.specs.general = { + config.specs.general = lib.mkIf (config.cats.general or true) { data = with pkgs.vimPlugins; [ lze lzextras @@ -79,7 +79,7 @@ ]; }; - config.specs.lua = { + config.specs.lua = lib.mkIf (config.cats.lua or true) { data = with pkgs.vimPlugins; [ luvit-meta { @@ -89,7 +89,7 @@ ]; }; - config.specs.markdown = { + config.specs.markdown = lib.mkIf (config.cats.markdown or true) { data = with pkgs.vimPlugins; [ quarto-nvim render-markdown-nvim @@ -104,7 +104,7 @@ ]; }; - config.specs.utils = { + config.specs.utils = lib.mkIf (config.cats.utils or true) { data = with pkgs.vimPlugins; [ blink-cmp nvim-lspconfig @@ -119,7 +119,7 @@ ]; }; - config.specs.treesitterParsers = { + config.specs.treesitterParsers = lib.mkIf (config.cats.treesitterParsers or true) { data = with pkgs.vimPlugins.nvim-treesitter-parsers; [ bash c @@ -158,7 +158,7 @@ ]; }; - config.specs.utils-lazy = { + config.specs.utils-lazy = lib.mkIf (config.cats.utils or true) { lazy = true; data = with pkgs.vimPlugins; [ blink-compat @@ -175,7 +175,7 @@ ]; }; - config.specs.gitPlugins-lazy = { + config.specs.gitPlugins-lazy = lib.mkIf (config.cats.gitPlugins or true) { lazy = true; data = []; }; diff --git a/modules/neovim.nix b/modules/neovim.nix index ba0361c..64d2cda 100644 --- a/modules/neovim.nix +++ b/modules/neovim.nix @@ -7,16 +7,10 @@ inputs: ... }: { - # ============================================================================ - # IMPORTS - # ============================================================================ - # Import the base neovim wrapper module and all configuration modules - imports = [ wlib.wrapperModules.neovim ./module/specs/deps.nix ./module/specs/plugins.nix - ./module/specs/cats-enable.nix ./module/settings/core.nix ./module/settings/cats.nix ./module/settings/env.nix @@ -25,11 +19,6 @@ inputs: ./module/settings/runtime-path.nix ]; - # ============================================================================ - # HELPER FUNCTIONS - # ============================================================================ - # Utilities for working with plugin inputs - options.nvim-lib.neovimPlugins = lib.mkOption { readOnly = true; type = lib.types.attrsOf wlib.types.stringable; @@ -58,11 +47,6 @@ inputs: ]; }; - # ============================================================================ - # CONFIGURATION - # ============================================================================ - # Pass cats configuration to neovim and expose metadata - config.settings.cats = config.cats; config.info.cats = config.cats; config.info.nixCats_config_location = config.settings.config_directory; diff --git a/overlays/default.nix b/overlays/default.nix index ebb6518..5a4cc6c 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -4,9 +4,8 @@ let rOverlay = import ./r.nix {inherit inputs;}; rNvimNixOverlay = inputs.r-nvim-nix.overlays.default; - franOverlay = inputs.fran.overlays.default; - pythonOverlay = import ./python.nix inputs; - pluginsOverlay = import ./plugins.nix inputs; + pythonOverlay = import ./python.nix {inherit inputs;}; + pluginsOverlay = import ./plugins.nix {inherit inputs;}; dependencyOverlays = [ rOverlay @@ -15,6 +14,11 @@ let pluginsOverlay ]; dependencyOverlay = lib.composeManyExtensions dependencyOverlays; + + # franOverlay provides R-specific tooling (radianWrapper, air-formatter). + # It is scoped to rixpkgs (via overlays/r.nix) rather than the global + # package set, since it only applies to R package derivations. + franOverlay = inputs.fran.overlays.default; in { inherit @@ -26,20 +30,6 @@ in dependencyOverlays dependencyOverlay; - # Named exports for downstream composition. default = dependencyOverlay; dependencies = dependencyOverlays; - - overlays = { - inherit - rOverlay - rNvimNixOverlay - franOverlay - pythonOverlay - pluginsOverlay - dependencyOverlays - dependencyOverlay; - default = dependencyOverlay; - dependencies = dependencyOverlays; - }; } diff --git a/overlays/r.nix b/overlays/r.nix index a9961fb..14c02eb 100644 --- a/overlays/r.nix +++ b/overlays/r.nix @@ -1,55 +1,15 @@ -# R packages overlay (rix) -# -# This overlay provides access to R packages from rstats-on-nix. -# -# rstats-on-nix maintains snapshots of CRAN packages built with Nix: -# - Provides reproducible R package versions -# - Ensures binary cache availability for faster builds -# - Maintained by the rstats-on-nix community -# -# Available attributes after applying this overlay: -# - pkgs.rpkgs: R packages from rstats-on-nix -# - pkgs.rpkgs.rPackages: All CRAN packages -# - pkgs.rpkgs.quarto: Quarto publishing system -# - pkgs.rpkgs.rWrapper: R with package management -# - pkgs.rWrapper: R wrapper with standard packages pre-configured -# - pkgs.quarto: Quarto with R integration and standard packages -# -# Custom R packages and tools (radianWrapper, air-formatter) come from -# the fran overlay which should be applied separately. -# -# To use specific R packages, reference them via: -# with pkgs.rpkgs.rPackages; [ package1 package2 ] -# -# Update the R snapshot date in flake.nix inputs section: -# rixpkgs.url = "github:rstats-on-nix/nixpkgs/YYYY-MM-DD" { inputs, ... }: final: prev: let - # R packages from rstats-on-nix for the current system rpkgs = import inputs.rixpkgs { system = prev.stdenv.hostPlatform.system; overlays = [inputs.fran.overlays.default]; - }; # rixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system}; - - # nvimcom and rnvimserver are provided by the r-nvim-nix flake overlay - # (inputs.r-nvim-nix.overlays.default) - - # Standard R packages used by default in rWrapper and quarto - reqPkgs = with rpkgs.rPackages; [ - # languageserver - ]; + }; in { inherit rpkgs; - baseRPackages = reqPkgs; - - # R wrapper with standard packages - rWrapper = rpkgs.rWrapper.override {packages = reqPkgs;}; - - # Quarto with R integration - quarto = rpkgs.quarto.override {extraRPackages = reqPkgs;}; - - # Update helper for rix + baseRPackages = [ ]; + rWrapper = rpkgs.rWrapper.override {packages = [ ];}; + quarto = rpkgs.quarto.override {extraRPackages = [ ];}; updateR = import ../scripts/updater.nix {pkgs = final;}; } From d23c7f6f51b5730f94628dab6ce43f76fb6048f2 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 21 May 2026 20:04:45 +1000 Subject: [PATCH 13/28] load packages only if installed --- flake.nix | 51 +++++++++++++++++++----------------- ftplugin/markdown.lua | 55 +++++++++++++++++++++------------------ plugin/20_startup.lua | 36 +++++++++++++------------ plugin/21_datascience.lua | 32 ++++++++++++----------- 4 files changed, 92 insertions(+), 82 deletions(-) diff --git a/flake.nix b/flake.nix index f84715f..2780328 100644 --- a/flake.nix +++ b/flake.nix @@ -39,10 +39,8 @@ wrappers, ... } @ inputs: let - mkWrapperConfig = pkgs: let - def = pkgs.lib.mkDefault; - in { - cats = pkgs.lib.mapAttrs (_: v: def v) { + mkWrapperConfig = pkgs: { + cats = { clickhouse = false; gitPlugins = true; julia = false; @@ -55,22 +53,12 @@ }; settings = { lang_packages = { - python = def (with pkgs.python3Packages; [ - duckdb - polars - ]); - r = def ((with pkgs.rpkgs.rPackages; [ - arrow - broom - data_table - janitor - languageserver - styler - ]) ++ [ pkgs.nvimcom ]); - julia = def ["DataFramesMeta" "QuackIO"]; + python = []; + r = []; + julia = []; }; }; - binName = def "vv"; + binName = "vv"; }; wrapperSettings = pkgs: let @@ -78,7 +66,7 @@ in wrapper.config.wrap { inherit pkgs; - inherit (cfg) cats settings binName; + inherit (cfg) settings binName; }; systems = [ @@ -135,14 +123,29 @@ devShells = forAllSystems ( system: let pkgs = mkPkgs system; - cfg = mkWrapperConfig pkgs; nvimPkg = wrapperSettings pkgs; + pythonPkgs = with pkgs.python3Packages; [ + duckdb + polars + ]; + + rPkgs = (with pkgs.rpkgs.rPackages; [ + arrow + broom + data_table + janitor + languageserver + styler + ]) ++ [ pkgs.nvimcom ]; + + juliaPkgs = ["DataFramesMeta" "QuackIO"]; + pythonPackages = let python_packages_fn = if pkgs ? basePythonPackages - then ps: pkgs.basePythonPackages ps ++ cfg.settings.lang_packages.python - else _: cfg.settings.lang_packages.python; + then ps: pkgs.basePythonPackages ps ++ pythonPkgs + else _: pythonPkgs; in with pkgs; [ (python3.withPackages python_packages_fn) @@ -153,7 +156,7 @@ ]; rPackages = let - r_packages = (pkgs.baseRPackages or []) ++ cfg.settings.lang_packages.r; + r_packages = (pkgs.baseRPackages or []) ++ rPkgs; in with pkgs; [ (rWrapper.override {packages = r_packages;}) @@ -167,7 +170,7 @@ ]; juliaPackages = let - julia_with_packages = pkgs.julia-bin.withPackages cfg.settings.lang_packages.julia; + julia_with_packages = pkgs.julia-bin.withPackages juliaPkgs; in [julia_with_packages]; markdownPackages = with pkgs; [ diff --git a/ftplugin/markdown.lua b/ftplugin/markdown.lua index b673b60..db316fc 100644 --- a/ftplugin/markdown.lua +++ b/ftplugin/markdown.lua @@ -1,32 +1,35 @@ -- Add the key mappings only for Markdown files in a zk notebook. -if require("zk.util").notebook_root(vim.fn.expand('%:p')) ~= nil then - local map = vim.keymap.set - -- Open the link under the caret. - map("n", "", "lua vim.lsp.buf.definition()", { noremap = true, silent = false, buffer = true }) +local nix = require("config.nix") +if nix.get_cat("markdown", false) then + if require("zk.util").notebook_root(vim.fn.expand('%:p')) ~= nil then + local map = vim.keymap.set + -- Open the link under the caret. + map("n", "", "lua vim.lsp.buf.definition()", { noremap = true, silent = false, buffer = true }) - -- Create a new note after asking for its title. - -- This overrides the global `zn` mapping to create the note in the same directory as the current buffer. - map("n", "zhn", "ZkNew { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", - { noremap = true, silent = false, buffer = true, desc = "Note (here)" }) - -- Create a new note in the same directory as the current buffer, using the current selection for title. - map("v", "zhnt", ":'<,'>ZkNewFromTitleSelection { dir = vim.fn.expand('%:p:h') }", - { noremap = true, silent = false, buffer = true, desc = "Note from selection (title)" }) - -- Create a new note in the same directory as the current buffer, using the current selection for note content and asking for its title. - map("v", "zhnc", - ":'<,'>ZkNewFromContentSelection { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", - { noremap = true, silent = false, buffer = true, desc = "Note from selection (content)" }) + -- Create a new note after asking for its title. + -- This overrides the global `zn` mapping to create the note in the same directory as the current buffer. + map("n", "zhn", "ZkNew { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", + { noremap = true, silent = false, buffer = true, desc = "Note (here)" }) + -- Create a new note in the same directory as the current buffer, using the current selection for title. + map("v", "zhnt", ":'<,'>ZkNewFromTitleSelection { dir = vim.fn.expand('%:p:h') }", + { noremap = true, silent = false, buffer = true, desc = "Note from selection (title)" }) + -- Create a new note in the same directory as the current buffer, using the current selection for note content and asking for its title. + map("v", "zhnc", + ":'<,'>ZkNewFromContentSelection { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", + { noremap = true, silent = false, buffer = true, desc = "Note from selection (content)" }) - -- Open notes linking to the current buffer. - map("n", "zb", "ZkBacklinks", { noremap = true, silent = false, buffer = true, desc = "Backlinks" }) - -- Alternative for backlinks using pure LSP and showing the source context. - --map('n', 'zb', 'lua vim.lsp.buf.references()', opts) - -- Open notes linked by the current buffer. - map("n", "zL", "ZkLinks", { noremap = true, silent = false, buffer = true, desc = "Links" }) - map("n", "zi", "ZkInsertLink", { noremap = true, silent = false, buffer = true, desc = "Insert link" }) + -- Open notes linking to the current buffer. + map("n", "zb", "ZkBacklinks", { noremap = true, silent = false, buffer = true, desc = "Backlinks" }) + -- Alternative for backlinks using pure LSP and showing the source context. + --map('n', 'zb', 'lua vim.lsp.buf.references()', opts) + -- Open notes linked by the current buffer. + map("n", "zL", "ZkLinks", { noremap = true, silent = false, buffer = true, desc = "Links" }) + map("n", "zi", "ZkInsertLink", { noremap = true, silent = false, buffer = true, desc = "Insert link" }) - -- Preview a linked note. - -- Open the code actions for a visual selection. - map("v", "za", ":'<,'>lua vim.lsp.buf.range_code_action()", - { noremap = true, silent = false, buffer = true, desc = "Code actions" }) + -- Preview a linked note. + -- Open the code actions for a visual selection. + map("v", "za", ":'<,'>lua vim.lsp.buf.range_code_action()", + { noremap = true, silent = false, buffer = true, desc = "Code actions" }) + end end diff --git a/plugin/20_startup.lua b/plugin/20_startup.lua index ca18bd8..0404b2c 100644 --- a/plugin/20_startup.lua +++ b/plugin/20_startup.lua @@ -390,23 +390,25 @@ end) -- zk now_if_args(function() - require("zk").setup({ - picker = "minipick", - lsp = { - -- `config` is passed to `vim.lsp.start_client(config)` - config = { - cmd = { "zk", "lsp" }, - name = "zk", - -- on_attach = ... - -- etc, see `:h vim.lsp.start_client()` - }, + if nix.get_cat("markdown", false) then + require("zk").setup({ + picker = "minipick", + lsp = { + -- `config` is passed to `vim.lsp.start_client(config)` + config = { + cmd = { "zk", "lsp" }, + name = "zk", + -- on_attach = ... + -- etc, see `:h vim.lsp.start_client()` + }, - -- automatically attach buffers in a zk notebook that match the given filetypes - auto_attach = { - enabled = true, - filetypes = { "markdown" }, - }, + -- automatically attach buffers in a zk notebook that match the given filetypes + auto_attach = { + enabled = true, + filetypes = { "markdown" }, + }, - }, - }) + }, + }) + end end) diff --git a/plugin/21_datascience.lua b/plugin/21_datascience.lua index 62d8f49..70902ca 100644 --- a/plugin/21_datascience.lua +++ b/plugin/21_datascience.lua @@ -71,22 +71,24 @@ end) now(function() vim.treesitter.language.register("markdown", { "quarto", "rmd" }) - vim.api.nvim_create_autocmd("FileType", { - pattern = { "quarto" }, - callback = function() - require("otter").activate() - end, - }) + if nix.get_cat({"r", "markdown"}, false) then + vim.api.nvim_create_autocmd("FileType", { + pattern = { "quarto" }, + callback = function() + require("otter").activate() + end, + }) - require("otter").setup({ - lsp = { - diagnostic_update_events = { "BufWritePost", "InsertLeave" }, - }, - buffers = { - set_filetype = true, - write_to_disk = true, - }, - }) + require("otter").setup({ + lsp = { + diagnostic_update_events = { "BufWritePost", "InsertLeave" }, + }, + buffers = { + set_filetype = true, + write_to_disk = true, + }, + }) + end end) later(function() From 6226a1c9b1a9525aa0cf2ed0a4993a89d062911e Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 21 May 2026 21:10:30 +1000 Subject: [PATCH 14/28] make lua package loading conditional on cat --- plugin/22_languages.lua | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/plugin/22_languages.lua b/plugin/22_languages.lua index 1983b25..ed4682a 100644 --- a/plugin/22_languages.lua +++ b/plugin/22_languages.lua @@ -1,6 +1,7 @@ local add = Config.add local now_if_args = Config.now_if_args local later = MiniDeps.later +local nix = require('config.nix') if not Config.isNixCats then local m_add = MiniDeps.add @@ -12,19 +13,21 @@ end -- lua later(function() - add("luvit-meta") - add("lazydev") - require("lazydev").setup({ - library = { - -- See the configuration section for more details - -- Load luvit types when the `vim.uv` word is found - "lua", - "mini.nvim", - "MiniDeps", - { path = "luvit-meta/library", words = { "vim%.uv" } }, - { path = "${3rd}/luv/library", words = { "vim%.uv" } }, - }, - }) + if nix.get_cat("lua", false) then + add("luvit-meta") + add("lazydev") + require("lazydev").setup({ + library = { + -- See the configuration section for more details + -- Load luvit types when the `vim.uv` word is found + "lua", + "mini.nvim", + "MiniDeps", + { path = "luvit-meta/library", words = { "vim%.uv" } }, + { path = "${3rd}/luv/library", words = { "vim%.uv" } }, + }, + }) + end end) -- Markdown From af6d975129768cce36ac4c46198ab2b3ebaafad3 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Thu, 21 May 2026 21:15:50 +1000 Subject: [PATCH 15/28] make quarto load optional on r or markdown cat --- plugin/21_datascience.lua | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/plugin/21_datascience.lua b/plugin/21_datascience.lua index 70902ca..2e9f86c 100644 --- a/plugin/21_datascience.lua +++ b/plugin/21_datascience.lua @@ -71,7 +71,7 @@ end) now(function() vim.treesitter.language.register("markdown", { "quarto", "rmd" }) - if nix.get_cat({"r", "markdown"}, false) then + if nix.get_cat({ "r", "markdown" }, false) then vim.api.nvim_create_autocmd("FileType", { pattern = { "quarto" }, callback = function() @@ -92,22 +92,24 @@ now(function() end) later(function() - require("quarto").setup({ - lspFeatures = { - enabled = true, - chunks = "curly", - languages = { "r", "python", "julia" }, - diagnostics = { + if nix.get_cat({ "r", "markdown" }, false) then + require("quarto").setup({ + lspFeatures = { enabled = true, - triggers = { "BufWritePost" }, + chunks = "curly", + languages = { "r", "python", "julia" }, + diagnostics = { + enabled = true, + triggers = { "BufWritePost" }, + }, + completion = { + enabled = true, + }, }, - completion = { + codeRunner = { enabled = true, + default_method = "slime", }, - }, - codeRunner = { - enabled = true, - default_method = "slime", - }, - }) + }) + end end) From 10254b11c727c139794d4d3b555c24562d9847ba Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 18:41:22 +1000 Subject: [PATCH 16/28] Corrected langpackage installation --- .commandcode/taste/taste.md | 9 ------- .gitignore | 2 ++ flake.nix | 52 ++++++++++++++++++------------------- plugin/10_keymap.lua | 4 +-- 4 files changed, 30 insertions(+), 37 deletions(-) delete mode 100644 .commandcode/taste/taste.md diff --git a/.commandcode/taste/taste.md b/.commandcode/taste/taste.md deleted file mode 100644 index 54e4488..0000000 --- a/.commandcode/taste/taste.md +++ /dev/null @@ -1,9 +0,0 @@ -# nix -- For R.nvim in the Nix wrapper, both RNVIM_COMPLDIR (C server compilation) and a writable R_LIBS_USER directory (nvimcom R package installation) must be configured — fixing only one leaves permission errors in the other. Confidence: 0.65 -- For R.nvim writable directories (RNVIM_COMPLDIR, R_LIBS_USER, TMPDIR), prefer project-local paths (e.g., $PWD/.Rlibs) over global cache paths — the cache approach may let the build succeed but still fail at runtime. Confidence: 0.70 -- Do not use lib.mkDefault on values consumed by lib.optionals or other boolean-checking functions — mkDefault wraps values in a priority set that fails "expected a Boolean" at evaluation time. Use plain booleans for inline conditionals, reserving mkDefault for module options resolved by the merge system. Confidence: 0.70 - -# Taste (Continuously Learned by [CommandCode][cmd]) - -[cmd]: https://commandcode.ai/ - diff --git a/.gitignore b/.gitignore index 8474af7..e402ff0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.R .Rlibs .nvimcom +.commandcode +.commandcode/ diff --git a/flake.nix b/flake.nix index 2780328..a19f7dc 100644 --- a/flake.nix +++ b/flake.nix @@ -1,4 +1,4 @@ -# Copyright (c) 2026 Daniel +# Copyright (c) 2026 BirdeeHub & Daniel # Licensed under the MIT license { description = "Daniel's NixCats"; @@ -39,6 +39,25 @@ wrappers, ... } @ inputs: let + langPackages = pkgs: { + python = with pkgs.python3Packages; [ + duckdb + polars + ]; + r = (with pkgs.rpkgs.rPackages; [ + arrow + broom + data_table + janitor + styler + pkgs.nvimcom + ]) ++ [ pkgs.nvimcom ]; + julia = [ + "DataFramesMeta" + "QuackIO" + ]; + }; + mkWrapperConfig = pkgs: { cats = { clickhouse = false; @@ -52,11 +71,7 @@ r = true; }; settings = { - lang_packages = { - python = []; - r = []; - julia = []; - }; + lang_packages = langPackages pkgs; }; binName = "vv"; }; @@ -125,27 +140,13 @@ pkgs = mkPkgs system; nvimPkg = wrapperSettings pkgs; - pythonPkgs = with pkgs.python3Packages; [ - duckdb - polars - ]; - - rPkgs = (with pkgs.rpkgs.rPackages; [ - arrow - broom - data_table - janitor - languageserver - styler - ]) ++ [ pkgs.nvimcom ]; - - juliaPkgs = ["DataFramesMeta" "QuackIO"]; + langPkgs = langPackages pkgs; pythonPackages = let python_packages_fn = if pkgs ? basePythonPackages - then ps: pkgs.basePythonPackages ps ++ pythonPkgs - else _: pythonPkgs; + then ps: pkgs.basePythonPackages ps ++ langPkgs.python + else _: langPkgs.python; in with pkgs; [ (python3.withPackages python_packages_fn) @@ -156,7 +157,7 @@ ]; rPackages = let - r_packages = (pkgs.baseRPackages or []) ++ rPkgs; + r_packages = (pkgs.baseRPackages or []) ++ langPkgs.r; in with pkgs; [ (rWrapper.override {packages = r_packages;}) @@ -164,13 +165,12 @@ (quarto.override {extraRPackages = r_packages;}) air-formatter yaml-language-server - updateR nvimcom rnvimserver ]; juliaPackages = let - julia_with_packages = pkgs.julia-bin.withPackages juliaPkgs; + julia_with_packages = pkgs.julia-bin.withPackages langPkgs.julia; in [julia_with_packages]; markdownPackages = with pkgs; [ diff --git a/plugin/10_keymap.lua b/plugin/10_keymap.lua index ebbebf0..5682b93 100644 --- a/plugin/10_keymap.lua +++ b/plugin/10_keymap.lua @@ -37,7 +37,7 @@ _G.Config.leader_group_clues = { { mode = 'x', keys = 'l', desc = '+LSP' }, { mode = 'x', keys = 'r', desc = '+R' }, { mode = 'n', keys = 'z', desc = '+ZK' }, - { mode = 'n', keys = 'zr', desc = '+Reviews' }, + { mode = 'n', keys = 'zr', desc = '+Reviews' }, { mode = 'x', keys = 'a', desc = '+AI' }, } @@ -144,7 +144,7 @@ nmap_leader('gc', 'Git commit', 'Commit') nmap_leader('gC', 'Git commit --amend', 'Commit amend') nmap_leader('gd', 'Git diff', 'Diff') nmap_leader('gD', 'Git diff -- %', 'Diff buffer') -nmap_leader('gg', 'lua require("neogit").open()', 'Git tab') +nmap_leader("gg", "Neogit", "Open Neogit UI") nmap_leader('gl', '' .. git_log_cmd .. '', 'Log') nmap_leader('gL', '' .. git_log_cmd .. ' --follow -- %', 'Log buffer') nmap_leader('go', 'lua MiniDiff.toggle_overlay()', 'Toggle overlay') From a0ba90c4d2ff20c4deb961b839b8c8e7518f4268 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 20:15:23 +1000 Subject: [PATCH 17/28] refactor package installation --- README.md | 247 +++++++++++++++++++++++ flake.lock | 28 ++- flake.nix | 109 ++++------ modules/module/settings/cat-packages.nix | 109 ++++++++++ modules/module/settings/cats.nix | 2 + modules/module/settings/runtime-path.nix | 33 --- modules/module/specs/deps.nix | 96 ++------- modules/neovim.nix | 2 +- 8 files changed, 433 insertions(+), 193 deletions(-) create mode 100644 README.md create mode 100644 modules/module/settings/cat-packages.nix delete mode 100644 modules/module/settings/runtime-path.nix diff --git a/README.md b/README.md new file mode 100644 index 0000000..c50d03e --- /dev/null +++ b/README.md @@ -0,0 +1,247 @@ +# nvimConfig + +Modular Neovim wrapper config. Defines a wrapped `vv` binary with per-category packages, plugins, and environment variables. Available as NixOS module, Home Manager module, or single-starflake import. + +## Quick start (imported into another flake) + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + rixpkgs.url = "github:dwinkler1/rixpkgs/af2dd3f7b4b172077747c0869d4e30702fb71b0e"; + fran = { + url = "github:dwinkler1/fran"; + inputs.nixpkgs.follows = "rixpkgs"; + }; + nvimConfig = { + url = "github:dwinkler1/nvimConfig"; + inputs = { + nixpkgs.follows = "nixpkgs"; + rixpkgs.follows = "rixpkgs"; + fran.follows = "fran"; + }; + }; + }; + + outputs = { self, nixpkgs, nvimConfig, ... } @ inputs: let + systems = ["aarch64-darwin" "x86_64-linux" "aarch64-linux"]; + forAllSystems = nixpkgs.lib.genAttrs systems; + in { + packages = forAllSystems (system: let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [ nvimConfig.overlays.dependencies ]; + }; + evalResult = nvimConfig.inputs.wrappers.lib.evalModules { + modules = [ + nvimConfig.wrapperModules.default + projectSettings # see below + ]; + }; + in { + default = evalResult.config.wrap { inherit pkgs; }; + }); + + devShells = forAllSystems (system: let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [ nvimConfig.overlays.dependencies ]; + }; + evalResult = nvimConfig.inputs.wrappers.lib.evalModules { + modules = [ + nvimConfig.wrapperModules.default + projectSettings + ]; + }; + nv = evalResult.config.wrap { inherit pkgs; }; + in { + default = pkgs.mkShell { + packages = + [ nv ] + ++ (evalResult.config.catPkgs.markdown or []) + ++ (evalResult.config.catPkgs.nix or []); + }; + }); + }; +} +``` + +## Home Manager module + +```nix +{ inputs, ... }: { + home.packages = [ + (inputs.nvimConfig.homeModules.default { inherit pkgs; }) + # Or via the overlay: + # pkgs.vv + ]; +} +``` + +## NixOS module + +```nix +{ inputs, ... }: { + environment.systemPackages = [ + (inputs.nvimConfig.nixosModules.default { inherit pkgs; }) + ]; +} +``` + +## Overriding settings + +Define a `projectSettings` attrset and pass it as the second module in `evalModules`. Every option in `nvimConfig.wrapperConfigs.default` can be overridden here. + +### Categories + +Enable only the cats you need. Defaults are listed in `modules/module/settings/cats.nix`. + +```nix +projectSettings = { + cats = { + python = true; # enable Python tooling + r = false; # disable R + nix = true; + lua = false; + markdown = false; + optional = false; + gitPlugins = false; + }; +}; +``` + +### Language packages (overlay extension) + +Add Python/R/Julia libraries that get appended to the overlay base packages. + +```nix +projectSettings = { + settings.lang_packages = { + python = with pkgs.python3Packages; [ pandas numpy ]; + r = with pkgs.rpkgs.rPackages; [ fixest data_table ]; + julia = [ "StatsBase" "Plots" ]; + }; +}; +``` + +Use `lib.mkForce` to replace rather than append: + +```nix +projectSettings = { + settings.lang_packages = { + python = pkgs.lib.mkForce (with pkgs.python3Packages; [ polars duckdb ]); + }; +}; +``` + +### Runtime dependencies (per-cat packages) + +Override `catPkgs` to add tools that appear in both the wrapper PATH and the devShell. To add always-available packages not gated by any cat, use `runtimePkgs` directly (see next section). + +```nix +projectSettings = { + catPkgs = { + nix = [ pkgs.nil pkgs.nixfmt ]; + python = [ + (pkgs.python3.withPackages (ps: [ ps.pandas ps.duckdb ])) + pkgs.ruff + ]; + }; +}; +``` + +### Direct runtimePkgs override (always-on) + +Add packages to `catPkgs.always` for tools that should always be available regardless of other cat toggles. + +```nix +projectSettings = { + catPkgs = { + always = [ pkgs.git pkgs.curl pkgs.pre-commit ]; + }; +}; +``` + +### Runtime env vars + +```nix +projectSettings = { + env = { + MY_PROJECT_VAR = "some-value"; + }; + envDefault = { + EDITOR = "vv"; + }; +}; +``` + +`env` values are forced; `envDefault` values can be overridden by the user's shell. + +### Neovim settings + +```nix +projectSettings = { + settings = { + colorscheme = "kanagawa"; + background = "dark"; + wrapRc = true; + config_directory = ./nvim; # path to init.lua + lua/ dir + aliases = [ "v" "nvim" ]; # extra binary names (default: [ "vvim" ]) + }; + binName = "nv"; # binary name (default: vv) +}; +``` + +## Adding plugins + +```nix +projectSettings = { + specs = { + extraPlugins = { + data = with pkgs.vimPlugins; [ + telescope-nvim + which-key-nvim + ]; + }; + + extraLazy = { + lazy = true; + data = with pkgs.vimPlugins; [ dashboard-nvim ]; + }; + + # Inject Lua config at startup + extraLua = { + data = pkgs.writeText "extra.lua" '' + vim.opt.number = true + vim.opt.relativenumber = true + ''; + before = ["INIT_MAIN"]; + }; + }; +}; +``` + +## Architecture + +``` +langPackages (flake.nix) ──► settings.lang_packages (module option) + │ +cats.nix ──► config.cats │ + │ │ + ▼ ▼ + cat-packages.nix ──► config.catPkgs. + │ │ + ┌───────┘ │ + ▼ ▼ + deps.nix (runtimePkgs) flake.nix (devShells) + │ │ + ▼ ▼ + wrapped vv PATH nix develop PATH +``` + +- **Overlays** (`overlays/`) inject base packages into nixpkgs (rWrapper, quarto, baseRPackages, basePythonPackages). +- **cat-packages.nix** is the single source of truth for per-category packages. Each list is gated by its cat toggle. +- **deps.nix** wires `catPkgs` into the wrapper's runtime PATH. +- **flake.nix** reads `catPkgs` for the devShell. `langPackages` feeds into `settings.lang_packages`. diff --git a/flake.lock b/flake.lock index 698ccf9..02745a6 100644 --- a/flake.lock +++ b/flake.lock @@ -74,20 +74,19 @@ "nixpkgs": [ "rixpkgs" ], - "rnvimsrc": [ - "plugins-r" - ] + "rnvimsrc": "rnvimsrc" }, "locked": { - "lastModified": 1778684156, - "narHash": "sha256-Z4y1tQfkIsPK4NRxGn668HMDfWxnxNxSJ0CAOOXiIfY=", + "lastModified": 1779438909, + "narHash": "sha256-1lvv0bdvSVyeCIgeZ7Ws7ffbDFurA5LJscS9dRLHzC8=", "owner": "dwinkler1", "repo": "r_nvim_nix", - "rev": "2f49dfee27886068e2f49cbd54558ce4cc424c82", + "rev": "ec17e22ab362a0ddfd6c2e9c5e95d43897a143be", "type": "github" }, "original": { "owner": "dwinkler1", + "ref": "v0.99.4", "repo": "r_nvim_nix", "type": "github" } @@ -108,6 +107,23 @@ "type": "github" } }, + "rnvimsrc": { + "flake": false, + "locked": { + "lastModified": 1776905071, + "narHash": "sha256-dXox6qEs1VDE7vPNDoN8bY4g06uj1IEs6uki72w8lpA=", + "owner": "R-nvim", + "repo": "R.nvim", + "rev": "582f2af11290ac067e49018db38e12a511325556", + "type": "github" + }, + "original": { + "owner": "R-nvim", + "ref": "v0.99.4", + "repo": "R.nvim", + "type": "github" + } + }, "root": { "inputs": { "fran": "fran", diff --git a/flake.nix b/flake.nix index a19f7dc..cde55df 100644 --- a/flake.nix +++ b/flake.nix @@ -11,9 +11,12 @@ }; rixpkgs.url = "github:dwinkler1/rixpkgs/af2dd3f7b4b172077747c0869d4e30702fb71b0e"; - r-nvim-nix.url = "github:dwinkler1/r_nvim_nix"; - r-nvim-nix.inputs.rnvimsrc.follows = "plugins-r"; - r-nvim-nix.inputs.nixpkgs.follows = "rixpkgs"; + r-nvim-nix = { + url = "github:dwinkler1/r_nvim_nix/v0.99.4"; + inputs = { + nixpkgs.follows = "rixpkgs"; + }; + }; fran = { url = "github:dwinkler1/fran"; @@ -44,14 +47,15 @@ duckdb polars ]; - r = (with pkgs.rpkgs.rPackages; [ - arrow - broom - data_table - janitor - styler - pkgs.nvimcom - ]) ++ [ pkgs.nvimcom ]; + r = + (with pkgs.rpkgs.rPackages; [ + arrow + broom + data_table + janitor + styler + ]) + ++ [pkgs.nvimcom]; julia = [ "DataFramesMeta" "QuackIO" @@ -59,17 +63,6 @@ }; mkWrapperConfig = pkgs: { - cats = { - clickhouse = false; - gitPlugins = true; - julia = false; - lua = true; - markdown = true; - nix = true; - optional = false; - python = false; - r = true; - }; settings = { lang_packages = langPackages pkgs; }; @@ -97,8 +90,12 @@ mkPkgs = system: import nixpkgs { inherit system; - config = { allowUnfree = true; }; - overlays = [ overlayDefs.dependencyOverlay ]; + config = {allowUnfree = true;}; + overlays = [ + overlayDefs.dependencyOverlay + inputs.r-nvim-nix.overlays.default + inputs.fran.overlays.default + ]; }; module = (import ./modules/neovim.nix) inputs; @@ -140,56 +137,21 @@ pkgs = mkPkgs system; nvimPkg = wrapperSettings pkgs; - langPkgs = langPackages pkgs; - - pythonPackages = let - python_packages_fn = - if pkgs ? basePythonPackages - then ps: pkgs.basePythonPackages ps ++ langPkgs.python - else _: langPkgs.python; - in - with pkgs; [ - (python3.withPackages python_packages_fn) - nodejs - ruff - basedpyright - uv - ]; - - rPackages = let - r_packages = (pkgs.baseRPackages or []) ++ langPkgs.r; - in - with pkgs; [ - (rWrapper.override {packages = r_packages;}) - radianWrapper - (quarto.override {extraRPackages = r_packages;}) - air-formatter - yaml-language-server - nvimcom - rnvimserver - ]; - - juliaPackages = let - julia_with_packages = pkgs.julia-bin.withPackages langPkgs.julia; - in [julia_with_packages]; - - markdownPackages = with pkgs; [ - python313Packages.pylatexenc - quarto - zk - ]; - - shellPackages = - [nvimPkg] - ++ pkgs.lib.optionals wrapper.config.cats.python pythonPackages - ++ pkgs.lib.optionals wrapper.config.cats.r rPackages - ++ pkgs.lib.optionals wrapper.config.cats.julia juliaPackages - ++ pkgs.lib.optionals wrapper.config.cats.markdown markdownPackages; + shellPackages = [nvimPkg] + ++ wrapper.config.catPkgs.always or [] + ++ wrapper.config.catPkgs.python or [] + ++ wrapper.config.catPkgs.r or [] + ++ wrapper.config.catPkgs.julia or [] + ++ wrapper.config.catPkgs.markdown or [] + ++ wrapper.config.catPkgs.optional or [] + ++ wrapper.config.catPkgs.external or [] + ++ wrapper.config.catPkgs.nix or [] + ++ wrapper.config.catPkgs.lua or [] + ++ wrapper.config.catPkgs.clickhouse or []; in { default = pkgs.mkShell { name = "vShell"; packages = shellPackages; - nativeBuildInputs = pkgs.lib.optionals wrapper.config.cats.optional [ pkgs.devenv ]; shellHook = '' echo 'I am a NixShell' export R_HOME=$(R RHOME) @@ -223,9 +185,10 @@ cat version_output.txt >> $out fi ''; - module-eval = - let _ = wrapper.config; - in pkgs.runCommand "check-module-eval" {} '' + module-eval = let + _ = wrapper.config; + in + pkgs.runCommand "check-module-eval" {} '' echo "Module evaluation successful" > $out ''; } diff --git a/modules/module/settings/cat-packages.nix b/modules/module/settings/cat-packages.nix new file mode 100644 index 0000000..3570ff6 --- /dev/null +++ b/modules/module/settings/cat-packages.nix @@ -0,0 +1,109 @@ +{ + config, + pkgs, + lib, + ... +}: +let + maybe = cat: pkgsList: + lib.optionals (config.cats.${cat} or false) pkgsList; +in +{ + options.catPkgs = lib.mkOption { + type = lib.types.attrsOf (lib.types.listOf lib.types.package); + description = "Per-cat package lists, gated by cat toggles. Single source of truth for runtimeDeps and devShells."; + }; + + config.catPkgs = { + always = maybe "always" (with pkgs; [ ]); + + clickhouse = maybe "clickhouse" (with pkgs; [ clickhouse-lts ]); + + external = maybe "external" (with pkgs; [ + perl + ruby + shfmt + sqlfluff + tree-sitter + ]); + + julia = maybe "julia" [ + (pkgs.julia-bin.withPackages config.settings.lang_packages.julia) + ]; + + lua = maybe "lua" (with pkgs; [ lua-language-server ]); + + markdown = maybe "markdown" (with pkgs; [ + python313Packages.pylatexenc + quarto + zk + ]); + + nix = maybe "nix" (with pkgs; [ + alejandra + nix-doc + nixd + ]); + + optional = maybe "optional" (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 + ]); + + python = maybe "python" (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 = maybe "r" (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 + rnvimserver + ]); + + # cats without packages get empty lists + general = [ ]; + gitPlugins = [ ]; + treesitterParsers = [ pkgs.tree-sitter ]; + utils = [ ]; + }; +} diff --git a/modules/module/settings/cats.nix b/modules/module/settings/cats.nix index 13758d4..e1895f7 100644 --- a/modules/module/settings/cats.nix +++ b/modules/module/settings/cats.nix @@ -13,6 +13,7 @@ Set a category to `false` to skip its dependency/plugin specs. Available categories: + - always: always-on packages (not gated by a toggle) - clickhouse: Clickhouse client and tools - external: external tools and integrations - general: core Neovim plugins/features @@ -30,6 +31,7 @@ }; config.cats = { + always = lib.mkDefault true; clickhouse = lib.mkDefault false; external = lib.mkDefault true; general = lib.mkDefault true; diff --git a/modules/module/settings/runtime-path.nix b/modules/module/settings/runtime-path.nix deleted file mode 100644 index b321019..0000000 --- a/modules/module/settings/runtime-path.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - 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.runtimePackages or [ ]; - in - acc ++ lib.optionals (is_enabled && has_runtime_deps) packages - ) - [ ]; - - prefix_packages = collect_runtime_packages "prefix"; - - to_path_specs = packages: [ - { - data = [ - "PATH" - ":" - "${lib.makeBinPath packages}" - ]; - } - ]; -in -{ - config.prefixVar = lib.optionals (prefix_packages != [ ]) (to_path_specs prefix_packages); -} diff --git a/modules/module/specs/deps.nix b/modules/module/specs/deps.nix index c3a40ea..b0c437f 100644 --- a/modules/module/specs/deps.nix +++ b/modules/module/specs/deps.nix @@ -13,133 +13,69 @@ }; }; - config.specs.external = { + config.specs.always = lib.mkIf (config.cats.always or true) { + data = lib.mkDefault null; + runtimeDeps = "prefix"; + runtimePkgs = config.catPkgs.always; + }; + + config.specs.external = lib.mkIf (config.cats.external or true) { data = lib.mkDefault null; before = ["INIT_MAIN"]; config = '' vim.o.shell = "${pkgs.zsh}/bin/zsh" ''; runtimeDeps = "prefix"; - runtimePkgs = with pkgs; [ - perl - ruby - shfmt - sqlfluff - tree-sitter - ]; + runtimePkgs = config.catPkgs.external; }; config.specs.optional = lib.mkIf (config.cats.optional or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; before = ["INIT_MAIN"]; - runtimePkgs = 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 - ]; + runtimePkgs = config.catPkgs.optional; }; config.specs.markdown = lib.mkIf (config.cats.markdown or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = with pkgs; [ - python313Packages.pylatexenc - quarto - zk - ]; + runtimePkgs = config.catPkgs.markdown; }; config.specs.nix = lib.mkIf (config.cats.nix or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = with pkgs; [ - alejandra - nix-doc - nixd - ]; + runtimePkgs = config.catPkgs.nix; }; config.specs.lua = lib.mkIf (config.cats.lua or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = with pkgs; [ - lua-language-server - ]; + runtimePkgs = config.catPkgs.lua; }; config.specs.python = lib.mkIf (config.cats.python or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = 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 - ]; + runtimePkgs = config.catPkgs.python; }; config.specs.r = lib.mkIf (config.cats.r or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = 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 - ]; + runtimePkgs = config.catPkgs.r; }; config.specs.julia = lib.mkIf (config.cats.julia or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = let - julia_with_packages = - pkgs.julia-bin.withPackages config.settings.lang_packages.julia; - in [julia_with_packages]; + runtimePkgs = config.catPkgs.julia; }; config.specs.clickhouse = lib.mkIf (config.cats.clickhouse or true) { data = lib.mkDefault null; runtimeDeps = "prefix"; - runtimePkgs = with pkgs; [ - clickhouse-lts - ]; + runtimePkgs = config.catPkgs.clickhouse; }; config.runtimePkgs = config.specCollect (acc: v: acc ++ (v.runtimePkgs or [])) []; diff --git a/modules/neovim.nix b/modules/neovim.nix index 64d2cda..f4ca40f 100644 --- a/modules/neovim.nix +++ b/modules/neovim.nix @@ -9,6 +9,7 @@ inputs: { imports = [ wlib.wrapperModules.neovim + ./module/settings/cat-packages.nix ./module/specs/deps.nix ./module/specs/plugins.nix ./module/settings/core.nix @@ -16,7 +17,6 @@ inputs: ./module/settings/env.nix ./module/settings/hosts.nix ./module/settings/lang-packages.nix - ./module/settings/runtime-path.nix ]; options.nvim-lib.neovimPlugins = lib.mkOption { From db610620b3a3f4a1b4976f466486393cd76f35b2 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 21:59:54 +1000 Subject: [PATCH 18/28] large refactor --- README.md | 158 +++++++++++++++----- flake.nix | 167 +++++++++++++--------- modules/module/settings/cat-packages.nix | 18 ++- modules/module/settings/core.nix | 2 +- modules/module/settings/env.nix | 10 +- modules/module/settings/hosts.nix | 6 +- modules/module/settings/lang-packages.nix | 26 +++- modules/module/specs/deps.nix | 20 +-- modules/module/specs/plugins.nix | 20 +-- plugin/21_datascience.lua | 2 +- 10 files changed, 286 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index c50d03e..cec155c 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,9 @@ Modular Neovim wrapper config. Defines a wrapped `vv` binary with per-category p config.allowUnfree = true; overlays = [ nvimConfig.overlays.dependencies ]; }; - evalResult = nvimConfig.inputs.wrappers.lib.evalModules { - modules = [ - nvimConfig.wrapperModules.default - projectSettings # see below - ]; + evalResult = nvimConfig.lib.eval { + inherit pkgs; + modules = [ projectSettings ]; # see below }; in { default = evalResult.config.wrap { inherit pkgs; }; @@ -49,19 +47,14 @@ Modular Neovim wrapper config. Defines a wrapped `vv` binary with per-category p config.allowUnfree = true; overlays = [ nvimConfig.overlays.dependencies ]; }; - evalResult = nvimConfig.inputs.wrappers.lib.evalModules { - modules = [ - nvimConfig.wrapperModules.default - projectSettings - ]; + evalResult = nvimConfig.lib.eval { + inherit pkgs; + modules = [ projectSettings ]; }; nv = evalResult.config.wrap { inherit pkgs; }; in { default = pkgs.mkShell { - packages = - [ nv ] - ++ (evalResult.config.catPkgs.markdown or []) - ++ (evalResult.config.catPkgs.nix or []); + packages = [ nv ] ++ nvimConfig.lib.devShellPackages evalResult.config; }; }); }; @@ -92,7 +85,96 @@ Modular Neovim wrapper config. Defines a wrapped `vv` binary with per-category p ## Overriding settings -Define a `projectSettings` attrset and pass it as the second module in `evalModules`. Every option in `nvimConfig.wrapperConfigs.default` can be overridden here. +Define a `projectSettings` attrset and pass it to `nvimConfig.lib.eval` or `nvimConfig.lib.mkWrapper`. The helper injects your overlaid `pkgs` automatically, so downstream consumers do not need to wire `specialArgs` themselves. Every option in `nvimConfig.wrapperConfigs.default` can be overridden here. Local `packages.default`, local `devShells.default`, downstream helper usage, and `pkgs.vv` all resolve the same module defaults unless you override them. + +### Basic downstream flake example + +This example enables a few cats, adds runtime tools to the shared wrapper/devShell package set, and appends language libraries to the default Python and R environments. + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + rixpkgs.url = "github:dwinkler1/rixpkgs/af2dd3f7b4b172077747c0869d4e30702fb71b0e"; + fran = { + url = "github:dwinkler1/fran"; + inputs.nixpkgs.follows = "rixpkgs"; + }; + nvimConfig = { + url = "github:dwinkler1/nvimConfig"; + inputs = { + nixpkgs.follows = "nixpkgs"; + rixpkgs.follows = "rixpkgs"; + fran.follows = "fran"; + }; + }; + }; + + outputs = { nixpkgs, nvimConfig, ... }: let + system = "aarch64-darwin"; + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [ nvimConfig.overlays.dependencies ]; + }; + projectSettings = { + cats = { + python = true; + r = true; + nix = true; + markdown = true; + optional = true; + }; + + settings.lang_packages = { + python = with pkgs.python3Packages; [ + pandas + pyarrow + ]; + r = with pkgs.rpkgs.rPackages; [ + fixest + modelsummary + ]; + }; + + catPkgs = { + python = [ + (pkgs.python3.withPackages (ps: + ps + ++ (with ps; [ + pandas + pyarrow + ]))) + pkgs.ruff + pkgs.basedpyright + pkgs.uv + pkgs.nodejs + ]; + nix = [ + pkgs.alejandra + pkgs.nil + ]; + optional = [ + pkgs.git + pkgs.fd + pkgs.ripgrep + ]; + }; + }; + evalResult = nvimConfig.lib.eval { + inherit pkgs; + modules = [ projectSettings ]; + }; + nv = evalResult.config.wrap { inherit pkgs; }; + in { + packages.${system}.default = nv; + + devShells.${system}.default = pkgs.mkShell { + packages = [ nv ] ++ nvimConfig.lib.devShellPackages evalResult.config; + }; + }; +} +``` ### Categories @@ -112,9 +194,13 @@ projectSettings = { }; ``` -### Language packages (overlay extension) +### Language packages (module defaults) -Add Python/R/Julia libraries that get appended to the overlay base packages. +Add Python/R/Julia libraries that get appended to the module defaults. The built-in defaults are: + +- Python: `duckdb`, `polars` +- R: `arrow`, `broom`, `data_table`, `janitor`, `styler`, `nvimcom` +- Julia: `DataFramesMeta`, `QuackIO` ```nix projectSettings = { @@ -138,7 +224,7 @@ projectSettings = { ### Runtime dependencies (per-cat packages) -Override `catPkgs` to add tools that appear in both the wrapper PATH and the devShell. To add always-available packages not gated by any cat, use `runtimePkgs` directly (see next section). +Override `catPkgs` to change the full runtime tool lists that appear in both the wrapper PATH and the devShell. Use normal assignments to merge list values, or `lib.mkForce` to replace them. ```nix projectSettings = { @@ -179,6 +265,14 @@ projectSettings = { `env` values are forced; `envDefault` values can be overridden by the user's shell. +### Choosing the right override surface + +- Use `cats` to enable or disable a whole language or tooling category. +- Use `settings.lang_packages` to add or replace Python, R, or Julia libraries within a language environment. +- Use `catPkgs` to change the full runtime tool list for a category. `config.runtimePkgs` drives wrapper PATH composition, while `nvimConfig.lib.devShellPackages config` returns the package-only list suitable for `mkShell`. +- Use `env` or `envDefault` for wrapper environment variables. +- Use `specs` for plugin additions or custom runtime behavior. + ### Neovim settings ```nix @@ -226,22 +320,20 @@ projectSettings = { ## Architecture ``` -langPackages (flake.nix) ──► settings.lang_packages (module option) - │ -cats.nix ──► config.cats │ - │ │ - ▼ ▼ - cat-packages.nix ──► config.catPkgs. - │ │ - ┌───────┘ │ - ▼ ▼ - deps.nix (runtimePkgs) flake.nix (devShells) - │ │ - ▼ ▼ - wrapped vv PATH nix develop PATH +settings/lang-packages.nix ──► settings.lang_packages + │ +cats.nix ───────────────► config.cats │ + │ │ + ▼ ▼ + cat-packages.nix ───────► config.catPkgs. + │ │ + ├──────────────┐ │ + ▼ ▼ ▼ + deps.nix PATH wrapper.config.wrap devShells.default ``` -- **Overlays** (`overlays/`) inject base packages into nixpkgs (rWrapper, quarto, baseRPackages, basePythonPackages). +- **Overlays** (`overlays/`) inject dependency package sets into nixpkgs (`rpkgs`, `baseRPackages`, `basePythonPackages`, plugins). Top-level `rWrapper` and `quarto` are compatibility conveniences, but `pkgs.rpkgs` is the canonical R surface for downstream configuration. - **cat-packages.nix** is the single source of truth for per-category packages. Each list is gated by its cat toggle. - **deps.nix** wires `catPkgs` into the wrapper's runtime PATH. -- **flake.nix** reads `catPkgs` for the devShell. `langPackages` feeds into `settings.lang_packages`. +- **settings.lang_packages** holds the shared defaults used by local outputs and downstream module consumers. +- **flake.nix** exports `lib.eval`, `lib.mkWrapper`, and `lib.devShellPackages` as the canonical downstream helpers, and builds `packages.default` and `devShells.default` from the same module config. diff --git a/flake.nix b/flake.nix index cde55df..b9e77e3 100644 --- a/flake.nix +++ b/flake.nix @@ -42,40 +42,42 @@ wrappers, ... } @ inputs: let - langPackages = pkgs: { - python = with pkgs.python3Packages; [ - duckdb - polars - ]; - r = - (with pkgs.rpkgs.rPackages; [ - arrow - broom - data_table - janitor - styler - ]) - ++ [pkgs.nvimcom]; - julia = [ - "DataFramesMeta" - "QuackIO" - ]; - }; - - mkWrapperConfig = pkgs: { - settings = { - lang_packages = langPackages pkgs; - }; - binName = "vv"; - }; - - wrapperSettings = pkgs: let - cfg = mkWrapperConfig pkgs; - in - wrapper.config.wrap { - inherit pkgs; - inherit (cfg) settings binName; + devShellCatOrder = [ + "always" + "clickhouse" + "external" + "julia" + "lua" + "markdown" + "nix" + "optional" + "python" + "r" + "treesitterParsers" + ]; + evalWithPkgs = pkgs: extraModules: + wrappers.lib.evalModules { + specialArgs = { + inherit pkgs; + }; + modules = + [ + module + ] + ++ extraModules; }; + mkDevShellPackages = config: + builtins.concatLists (map (name: config.catPkgs.${name} or []) devShellCatOrder); + mkShellHook = config: + '' + echo 'I am a NixShell' + '' + + nixpkgs.lib.optionalString (config.cats.r or false) '' + export R_HOME=$(R RHOME) + export R_LIBS_SITE=$(strings "$(command -v R)" | grep -oP '/nix/store/[^:]+/library' | sort -u | paste -sd: -) + export R_LIBS_USER="$PWD/.r-libs" + mkdir -p "$R_LIBS_USER" + ''; systems = [ "aarch64-darwin" @@ -93,35 +95,40 @@ config = {allowUnfree = true;}; overlays = [ overlayDefs.dependencyOverlay - inputs.r-nvim-nix.overlays.default - inputs.fran.overlays.default ]; }; module = (import ./modules/neovim.nix) inputs; - wrapper = wrappers.lib.evalModule module; in { + lib = { + eval = {pkgs, modules ? []}: evalWithPkgs pkgs modules; + mkWrapper = {pkgs, modules ? []}: (evalWithPkgs pkgs modules).config.wrap {inherit pkgs;}; + devShellPackages = config: mkDevShellPackages config; + }; + overlays = { # overlay `vv` wraps the module with default settings only. - # For the fully-configured binary (including mkWrapperConfig overrides), - # use `packages..default` instead. + # It is evaluated against the final package set so module defaults can + # depend on overlays such as rixpkgs-backed `pkgs.rpkgs`. default = nixpkgs.lib.composeManyExtensions [ overlayDefs.dependencyOverlay (final: prev: { - vv = wrapper.config.wrap {pkgs = final;}; + vv = (evalWithPkgs final []).config.wrap {pkgs = final;}; }) ]; dependencies = overlayDefs.dependencyOverlay; }; wrapperModules.default = module; - wrapperConfigs.default = wrapper.config; + wrapperConfigs.default = {pkgs, modules ? []}: (self.lib.eval {inherit pkgs modules;}).config; packages = forAllSystems ( system: let pkgs = mkPkgs system; in { - default = wrapperSettings pkgs; + default = self.lib.mkWrapper { + inherit pkgs; + }; } ); @@ -135,30 +142,13 @@ devShells = forAllSystems ( system: let pkgs = mkPkgs system; - nvimPkg = wrapperSettings pkgs; - - shellPackages = [nvimPkg] - ++ wrapper.config.catPkgs.always or [] - ++ wrapper.config.catPkgs.python or [] - ++ wrapper.config.catPkgs.r or [] - ++ wrapper.config.catPkgs.julia or [] - ++ wrapper.config.catPkgs.markdown or [] - ++ wrapper.config.catPkgs.optional or [] - ++ wrapper.config.catPkgs.external or [] - ++ wrapper.config.catPkgs.nix or [] - ++ wrapper.config.catPkgs.lua or [] - ++ wrapper.config.catPkgs.clickhouse or []; + config = (self.lib.eval {inherit pkgs;}).config; + nvimPkg = config.wrap {inherit pkgs;}; in { default = pkgs.mkShell { name = "vShell"; - packages = shellPackages; - shellHook = '' - echo 'I am a NixShell' - export R_HOME=$(R RHOME) - export R_LIBS_SITE=$(strings "$(command -v R)" | grep -oP '/nix/store/[^:]+/library' | sort -u | paste -sd: -) - export R_LIBS_USER="$PWD/.r-libs" - mkdir -p "$R_LIBS_USER" - ''; + packages = [nvimPkg] ++ self.lib.devShellPackages config; + shellHook = mkShellHook config; }; } ); @@ -166,10 +156,31 @@ checks = forAllSystems ( system: let pkgs = mkPkgs system; - nvimPkg = wrapperSettings pkgs; + defaultConfig = (self.lib.eval {inherit pkgs;}).config; + defaultNvimPkg = defaultConfig.wrap {inherit pkgs;}; + defaultShellHook = mkShellHook defaultConfig; + overrideConfig = + (self.lib.eval { + inherit pkgs; + modules = [ + { + cats = { + r = false; + python = true; + }; + settings.lang_packages.python = nixpkgs.lib.mkForce (with pkgs.python3Packages; [ + pandas + ]); + catPkgs.nix = nixpkgs.lib.mkForce [ + pkgs.alejandra + ]; + } + ]; + }).config; + overrideShellHook = mkShellHook overrideConfig; in { default = pkgs.runCommand "check-vv" {} '' - BINARY_PATH="${nvimPkg}/bin/vv" + BINARY_PATH="${defaultNvimPkg}/bin/vv" if [ ! -x "$BINARY_PATH" ]; then echo "Error: Binary not found or not executable" @@ -186,11 +197,37 @@ fi ''; module-eval = let - _ = wrapper.config; + _ = (self.lib.eval {inherit pkgs;}).config; in pkgs.runCommand "check-module-eval" {} '' echo "Module evaluation successful" > $out ''; + downstream-overrides = let + overrideNix = builtins.map (p: p.pname or p.name) overrideConfig.catPkgs.nix; + defaultAssertions = [ + (defaultConfig.cats.r or false) + (builtins.match ".*R RHOME.*" defaultShellHook != null) + (builtins.length (self.lib.devShellPackages defaultConfig) > 0) + ]; + overrideAssertions = [ + (!(overrideConfig.cats.r or false)) + (builtins.length overrideNix == 1) + ((builtins.head overrideNix) == "alejandra") + (builtins.match ".*R RHOME.*" overrideShellHook == null) + ]; + in + pkgs.runCommand "check-downstream-overrides" { + pass = + if builtins.all (x: x) (defaultAssertions ++ overrideAssertions) + then "1" + else ""; + } '' + if [ -z "$pass" ]; then + echo "Downstream override assertions failed" >&2 + exit 1 + fi + echo "Downstream override assertions passed" > $out + ''; } ); diff --git a/modules/module/settings/cat-packages.nix b/modules/module/settings/cat-packages.nix index 3570ff6..7dd3049 100644 --- a/modules/module/settings/cat-packages.nix +++ b/modules/module/settings/cat-packages.nix @@ -70,7 +70,6 @@ in tokei wget yq - zathura ]); python = maybe "python" (let @@ -90,15 +89,14 @@ in r = maybe "r" (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 - rnvimserver - ]); + in [ + (pkgs.rpkgs.rWrapper.override { packages = r_packages; }) + pkgs.rpkgs.radianWrapper + (pkgs.rpkgs.quarto.override { extraRPackages = r_packages; }) + pkgs.air-formatter + pkgs.yaml-language-server + pkgs.rnvimserver + ]); # cats without packages get empty lists general = [ ]; diff --git a/modules/module/settings/core.nix b/modules/module/settings/core.nix index ec9bb5c..f8b3188 100644 --- a/modules/module/settings/core.nix +++ b/modules/module/settings/core.nix @@ -16,7 +16,7 @@ # Lua packages available to neovim (for :lua require()) config.settings.nvim_lua_env = lp: - lib.optionals (config.cats.general or true) [ lp.tiktoken_core ]; + lib.optionals (config.cats.general or false) [ lp.tiktoken_core ]; # Binary name for the wrapper config.binName = lib.mkDefault "vv"; diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index 2fcab8a..db2986d 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -7,21 +7,21 @@ # Environment variables set for the wrapper. # These are available when running neovim. config.env = lib.mkMerge [ - (lib.mkIf (config.cats.python or true) { + (lib.mkIf (config.cats.python or false) { UV_PYTHON_DOWNLOADS = "never"; UV_PYTHON = pkgs.python.interpreter; }) - (lib.mkIf (config.cats.r or true) { + (lib.mkIf (config.cats.r or false) { RNVIM_COMPLDIR = "$PWD/.r-compl"; - R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; + R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.r-libs"; TMPDIR = "$PWD/.r-tmp"; }) ]; # Environment variables with defaults (can be overridden by user) config.envDefault = lib.mkMerge [ - (lib.mkIf (config.cats.r or true) { - R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.Rlibs"; + (lib.mkIf (config.cats.r or false) { + R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.r-libs"; }) ]; } diff --git a/modules/module/settings/hosts.nix b/modules/module/settings/hosts.nix index f248a00..7637633 100644 --- a/modules/module/settings/hosts.nix +++ b/modules/module/settings/hosts.nix @@ -29,7 +29,7 @@ ]; }; } - (lib.mkIf (config.cats.julia or true) { + (lib.mkIf (config.cats.julia or false) { jl = { nvim-host.enable = true; nvim-host.package = "${pkgs.julia-bin}/bin/julia"; @@ -39,10 +39,10 @@ ]; }; }) - (lib.mkIf (config.cats.python or true) { + (lib.mkIf (config.cats.python or false) { python3.nvim-host.enable = true; }) - (lib.mkIf (config.cats.r or true) { + (lib.mkIf (config.cats.r or false) { r = { nvim-host.enable = true; nvim-host.package = "${pkgs.rWrapper}/bin/R"; diff --git a/modules/module/settings/lang-packages.nix b/modules/module/settings/lang-packages.nix index 531b811..b6fff27 100644 --- a/modules/module/settings/lang-packages.nix +++ b/modules/module/settings/lang-packages.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: @@ -26,14 +27,29 @@ }; default = { }; description = '' - Language-specific package overrides appended to each language spec's runtimePackages. - Intended for flake.nix overrides via wrapper.config.wrap. + Language-specific package defaults and downstream overrides appended to each + language spec's runtime packages. ''; }; config.settings.lang_packages = { - python = lib.mkDefault [ ]; - r = lib.mkDefault [ ]; - julia = lib.mkDefault [ ]; + python = lib.mkDefault (with pkgs.python3Packages; [ + duckdb + polars + ]); + r = lib.mkDefault ( + (with pkgs.rpkgs.rPackages; [ + arrow + broom + data_table + janitor + styler + ]) + ++ [pkgs.nvimcom] + ); + julia = lib.mkDefault [ + "DataFramesMeta" + "QuackIO" + ]; }; } diff --git a/modules/module/specs/deps.nix b/modules/module/specs/deps.nix index b0c437f..5cbfe63 100644 --- a/modules/module/specs/deps.nix +++ b/modules/module/specs/deps.nix @@ -13,13 +13,13 @@ }; }; - config.specs.always = lib.mkIf (config.cats.always or true) { + config.specs.always = lib.mkIf (config.cats.always or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.always; }; - config.specs.external = lib.mkIf (config.cats.external or true) { + config.specs.external = lib.mkIf (config.cats.external or false) { data = lib.mkDefault null; before = ["INIT_MAIN"]; config = '' @@ -29,50 +29,50 @@ runtimePkgs = config.catPkgs.external; }; - config.specs.optional = lib.mkIf (config.cats.optional or true) { + config.specs.optional = lib.mkIf (config.cats.optional or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; before = ["INIT_MAIN"]; runtimePkgs = config.catPkgs.optional; }; - config.specs.markdown = lib.mkIf (config.cats.markdown or true) { + config.specs.markdown = lib.mkIf (config.cats.markdown or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.markdown; }; - config.specs.nix = lib.mkIf (config.cats.nix or true) { + config.specs.nix = lib.mkIf (config.cats.nix or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.nix; }; - config.specs.lua = lib.mkIf (config.cats.lua or true) { + config.specs.lua = lib.mkIf (config.cats.lua or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.lua; }; - config.specs.python = lib.mkIf (config.cats.python or true) { + config.specs.python = lib.mkIf (config.cats.python or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.python; }; - config.specs.r = lib.mkIf (config.cats.r or true) { + config.specs.r = lib.mkIf (config.cats.r or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.r; }; - config.specs.julia = lib.mkIf (config.cats.julia or true) { + config.specs.julia = lib.mkIf (config.cats.julia or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.julia; }; - config.specs.clickhouse = lib.mkIf (config.cats.clickhouse or true) { + config.specs.clickhouse = lib.mkIf (config.cats.clickhouse or false) { data = lib.mkDefault null; runtimeDeps = "prefix"; runtimePkgs = config.catPkgs.clickhouse; diff --git a/modules/module/specs/plugins.nix b/modules/module/specs/plugins.nix index ff00a72..ad464b8 100644 --- a/modules/module/specs/plugins.nix +++ b/modules/module/specs/plugins.nix @@ -4,11 +4,11 @@ lib, ... }: { - config.specs.gitPlugins = lib.mkIf (config.cats.gitPlugins or true) { + config.specs.gitPlugins = lib.mkIf (config.cats.gitPlugins or false) { data = []; }; - config.specs.r = lib.mkIf (config.cats.r or true) { + config.specs.r = lib.mkIf (config.cats.r or false) { data = with pkgs.vimPlugins; [ pkgs.r-nvim quarto-nvim @@ -19,14 +19,14 @@ ]; }; - config.specs.markdown-lazy = lib.mkIf (config.cats.markdown or true) { + config.specs.markdown-lazy = lib.mkIf (config.cats.markdown or false) { lazy = true; data = [ config.nvim-lib.neovimPlugins.cmp-pandoc-references ]; }; - config.specs.general = lib.mkIf (config.cats.general or true) { + config.specs.general = lib.mkIf (config.cats.general or false) { data = with pkgs.vimPlugins; [ lze lzextras @@ -79,7 +79,7 @@ ]; }; - config.specs.lua = lib.mkIf (config.cats.lua or true) { + config.specs.lua = lib.mkIf (config.cats.lua or false) { data = with pkgs.vimPlugins; [ luvit-meta { @@ -89,7 +89,7 @@ ]; }; - config.specs.markdown = lib.mkIf (config.cats.markdown or true) { + config.specs.markdown = lib.mkIf (config.cats.markdown or false) { data = with pkgs.vimPlugins; [ quarto-nvim render-markdown-nvim @@ -104,7 +104,7 @@ ]; }; - config.specs.utils = lib.mkIf (config.cats.utils or true) { + config.specs.utils = lib.mkIf (config.cats.utils or false) { data = with pkgs.vimPlugins; [ blink-cmp nvim-lspconfig @@ -119,7 +119,7 @@ ]; }; - config.specs.treesitterParsers = lib.mkIf (config.cats.treesitterParsers or true) { + config.specs.treesitterParsers = lib.mkIf (config.cats.treesitterParsers or false) { data = with pkgs.vimPlugins.nvim-treesitter-parsers; [ bash c @@ -158,7 +158,7 @@ ]; }; - config.specs.utils-lazy = lib.mkIf (config.cats.utils or true) { + config.specs.utils-lazy = lib.mkIf (config.cats.utils or false) { lazy = true; data = with pkgs.vimPlugins; [ blink-compat @@ -175,7 +175,7 @@ ]; }; - config.specs.gitPlugins-lazy = lib.mkIf (config.cats.gitPlugins or true) { + config.specs.gitPlugins-lazy = lib.mkIf (config.cats.gitPlugins or false) { lazy = true; data = []; }; diff --git a/plugin/21_datascience.lua b/plugin/21_datascience.lua index 2e9f86c..aeab360 100644 --- a/plugin/21_datascience.lua +++ b/plugin/21_datascience.lua @@ -61,7 +61,7 @@ now(function() min_editor_width = 80, rconsole_height = 20, nvimpager = "split_h", - pdfviewer = "zathura", + pdfviewer = "", }) end end) From ed7abad63cb63025d5d87a9a767ec5c00d7b3126 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 22:53:52 +1000 Subject: [PATCH 19/28] Expose shellhooks via API --- README.md | 4 +++- flake.nix | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cec155c..715d4c6 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Modular Neovim wrapper config. Defines a wrapped `vv` binary with per-category p in { default = pkgs.mkShell { packages = [ nv ] ++ nvimConfig.lib.devShellPackages evalResult.config; + shellHook = nvimConfig.lib.shellHook evalResult.config; }; }); }; @@ -171,6 +172,7 @@ This example enables a few cats, adds runtime tools to the shared wrapper/devShe devShells.${system}.default = pkgs.mkShell { packages = [ nv ] ++ nvimConfig.lib.devShellPackages evalResult.config; + shellHook = nvimConfig.lib.shellHook evalResult.config; }; }; } @@ -336,4 +338,4 @@ cats.nix ───────────────► config.cats │ - **cat-packages.nix** is the single source of truth for per-category packages. Each list is gated by its cat toggle. - **deps.nix** wires `catPkgs` into the wrapper's runtime PATH. - **settings.lang_packages** holds the shared defaults used by local outputs and downstream module consumers. -- **flake.nix** exports `lib.eval`, `lib.mkWrapper`, and `lib.devShellPackages` as the canonical downstream helpers, and builds `packages.default` and `devShells.default` from the same module config. +- **flake.nix** exports `lib.eval`, `lib.mkWrapper`, `lib.devShellPackages`, and `lib.shellHook` as the canonical downstream helpers, and builds `packages.default` and `devShells.default` from the same module config. diff --git a/flake.nix b/flake.nix index b9e77e3..4c8df73 100644 --- a/flake.nix +++ b/flake.nix @@ -104,6 +104,7 @@ eval = {pkgs, modules ? []}: evalWithPkgs pkgs modules; mkWrapper = {pkgs, modules ? []}: (evalWithPkgs pkgs modules).config.wrap {inherit pkgs;}; devShellPackages = config: mkDevShellPackages config; + shellHook = config: mkShellHook config; }; overlays = { From 1c5619312db77493cc07fd5ac991347e47638e5f Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 23:07:54 +1000 Subject: [PATCH 20/28] simplified --- flake.lock | 18 ------------------ flake.nix | 5 ----- overlays/r.nix | 1 - scripts/updater.nix | 14 -------------- scripts/updater.sh | 22 ---------------------- 5 files changed, 60 deletions(-) delete mode 100644 scripts/updater.nix delete mode 100644 scripts/updater.sh diff --git a/flake.lock b/flake.lock index 02745a6..0b89d7a 100644 --- a/flake.lock +++ b/flake.lock @@ -52,23 +52,6 @@ "type": "github" } }, - "plugins-r": { - "flake": false, - "locked": { - "lastModified": 1776905071, - "narHash": "sha256-dXox6qEs1VDE7vPNDoN8bY4g06uj1IEs6uki72w8lpA=", - "owner": "R-nvim", - "repo": "R.nvim", - "rev": "582f2af11290ac067e49018db38e12a511325556", - "type": "github" - }, - "original": { - "owner": "R-nvim", - "ref": "v0.99.4", - "repo": "R.nvim", - "type": "github" - } - }, "r-nvim-nix": { "inputs": { "nixpkgs": [ @@ -129,7 +112,6 @@ "fran": "fran", "nixpkgs": "nixpkgs", "plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references", - "plugins-r": "plugins-r", "r-nvim-nix": "r-nvim-nix", "rixpkgs": "rixpkgs", "wrappers": "wrappers" diff --git a/flake.nix b/flake.nix index 4c8df73..ee9c05c 100644 --- a/flake.nix +++ b/flake.nix @@ -25,11 +25,6 @@ }; }; - "plugins-r" = { - url = "github:R-nvim/R.nvim/v0.99.4"; - flake = false; - }; - "plugins-cmp-pandoc-references" = { url = "github:jmbuhr/cmp-pandoc-references"; flake = false; diff --git a/overlays/r.nix b/overlays/r.nix index 14c02eb..18f01dd 100644 --- a/overlays/r.nix +++ b/overlays/r.nix @@ -11,5 +11,4 @@ in { baseRPackages = [ ]; rWrapper = rpkgs.rWrapper.override {packages = [ ];}; quarto = rpkgs.quarto.override {extraRPackages = [ ];}; - updateR = import ../scripts/updater.nix {pkgs = final;}; } diff --git a/scripts/updater.nix b/scripts/updater.nix deleted file mode 100644 index 063ec8d..0000000 --- a/scripts/updater.nix +++ /dev/null @@ -1,14 +0,0 @@ -{pkgs}: -pkgs.writeShellApplication { - name = "updateR"; - - # Tools your script needs at runtime - runtimeInputs = [ - pkgs.wget - pkgs.gnused - pkgs.coreutils - ]; - - # Keep script in separate file, but embed contents - text = builtins.readFile ./updater.sh; -} diff --git a/scripts/updater.sh b/scripts/updater.sh deleted file mode 100644 index ccf5e2e..0000000 --- a/scripts/updater.sh +++ /dev/null @@ -1,22 +0,0 @@ -echo "📡 Fetching latest R version from rstats-on-nix..." -RVER=$( wget -qO- 'https://raw.githubusercontent.com/ropensci/rix/refs/heads/main/inst/extdata/available_df.csv' | tail -n 1 | head -n 1 | cut -d',' -f4 | tr -d '"' ) - -# Validate RVER matches YYYY-MM-DD format -if [[ ! "$RVER" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then - echo "❌ Error: Failed to fetch valid R version date. Got: '$RVER'" - exit 1 -fi - -echo "✅ R date is $RVER" - -# Create backup of flake.nix before modifying -cp flake.nix flake.nix.backup - -# Update rixpkgs date in flake.nix -if sed -i "s|rixpkgs.url = \"github:rstats-on-nix/nixpkgs/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\";|rixpkgs.url = \"github:rstats-on-nix/nixpkgs/$RVER\";|" flake.nix; then - echo "✅ Updated rixpkgs date in flake.nix" - rm flake.nix.backup -else - echo "⚠️ Warning: Failed to update flake.nix, restoring backup" - mv flake.nix.backup flake.nix -fi From d218b05d485d8d2db387c1d7a6016fdd6f3f1310 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 23:38:18 +1000 Subject: [PATCH 21/28] hopefully R fix --- modules/module/settings/cat-packages.nix | 17 ++++++++++------- modules/module/settings/hosts.nix | 6 +++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/module/settings/cat-packages.nix b/modules/module/settings/cat-packages.nix index 7dd3049..8f027ba 100644 --- a/modules/module/settings/cat-packages.nix +++ b/modules/module/settings/cat-packages.nix @@ -7,6 +7,11 @@ let maybe = cat: pkgsList: lib.optionals (config.cats.${cat} or false) pkgsList; + rPackages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; + quartoPkg = + if config.cats.r or false + then pkgs.rpkgs.quarto.override { extraRPackages = rPackages; } + else pkgs.quarto; in { options.catPkgs = lib.mkOption { @@ -35,7 +40,7 @@ in markdown = maybe "markdown" (with pkgs; [ python313Packages.pylatexenc - quarto + quartoPkg zk ]); @@ -87,16 +92,14 @@ in uv ]); - r = maybe "r" (let - r_packages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; - in [ - (pkgs.rpkgs.rWrapper.override { packages = r_packages; }) + r = maybe "r" [ + (pkgs.rpkgs.rWrapper.override { packages = rPackages; }) pkgs.rpkgs.radianWrapper - (pkgs.rpkgs.quarto.override { extraRPackages = r_packages; }) + quartoPkg pkgs.air-formatter pkgs.yaml-language-server pkgs.rnvimserver - ]); + ]; # cats without packages get empty lists general = [ ]; diff --git a/modules/module/settings/hosts.nix b/modules/module/settings/hosts.nix index 7637633..a47467a 100644 --- a/modules/module/settings/hosts.nix +++ b/modules/module/settings/hosts.nix @@ -4,6 +4,10 @@ lib, ... }: +let + rPackages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; + rWrapperPkg = pkgs.rpkgs.rWrapper.override { packages = rPackages; }; +in { config.hosts = lib.mkMerge [ { @@ -45,7 +49,7 @@ (lib.mkIf (config.cats.r or false) { r = { nvim-host.enable = true; - nvim-host.package = "${pkgs.rWrapper}/bin/R"; + nvim-host.package = "${rWrapperPkg}/bin/R"; nvim-host.argv0 = "R"; nvim-host.addFlag = [ "--no-save" From 740f86ad7b3494f51e1e051bf709aedcaa0ec11e Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 23:41:48 +1000 Subject: [PATCH 22/28] hopefully R fix --- modules/module/settings/env.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index db2986d..d7ecc36 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -13,7 +13,7 @@ }) (lib.mkIf (config.cats.r or false) { RNVIM_COMPLDIR = "$PWD/.r-compl"; - R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.r-libs"; + R_LIBS_USER = "$PWD/.r-libs"; TMPDIR = "$PWD/.r-tmp"; }) ]; @@ -21,7 +21,7 @@ # Environment variables with defaults (can be overridden by user) config.envDefault = lib.mkMerge [ (lib.mkIf (config.cats.r or false) { - R_LIBS_USER = "${pkgs.nvimcom}/library:$PWD/.r-libs"; + R_LIBS_USER = "$PWD/.r-libs"; }) ]; } From 458332a141840cdad6dc431a8fe9c3f3be5fea94 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 23:44:56 +1000 Subject: [PATCH 23/28] hopefully R fix --- README.md | 2 +- modules/module/settings/cat-packages.nix | 3 ++- modules/module/settings/hosts.nix | 2 +- modules/module/settings/lang-packages.nix | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 715d4c6..068d704 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ projectSettings = { Add Python/R/Julia libraries that get appended to the module defaults. The built-in defaults are: - Python: `duckdb`, `polars` -- R: `arrow`, `broom`, `data_table`, `janitor`, `styler`, `nvimcom` +- R: `arrow`, `broom`, `data_table`, `janitor`, `styler` - Julia: `DataFramesMeta`, `QuackIO` ```nix diff --git a/modules/module/settings/cat-packages.nix b/modules/module/settings/cat-packages.nix index 8f027ba..6406327 100644 --- a/modules/module/settings/cat-packages.nix +++ b/modules/module/settings/cat-packages.nix @@ -8,6 +8,7 @@ let maybe = cat: pkgsList: lib.optionals (config.cats.${cat} or false) pkgsList; rPackages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; + rWrapperPackages = rPackages ++ [pkgs.nvimcom]; quartoPkg = if config.cats.r or false then pkgs.rpkgs.quarto.override { extraRPackages = rPackages; } @@ -93,7 +94,7 @@ in ]); r = maybe "r" [ - (pkgs.rpkgs.rWrapper.override { packages = rPackages; }) + (pkgs.rpkgs.rWrapper.override { packages = rWrapperPackages; }) pkgs.rpkgs.radianWrapper quartoPkg pkgs.air-formatter diff --git a/modules/module/settings/hosts.nix b/modules/module/settings/hosts.nix index a47467a..aadd70f 100644 --- a/modules/module/settings/hosts.nix +++ b/modules/module/settings/hosts.nix @@ -6,7 +6,7 @@ }: let rPackages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; - rWrapperPkg = pkgs.rpkgs.rWrapper.override { packages = rPackages; }; + rWrapperPkg = pkgs.rpkgs.rWrapper.override { packages = rPackages ++ [pkgs.nvimcom]; }; in { config.hosts = lib.mkMerge [ diff --git a/modules/module/settings/lang-packages.nix b/modules/module/settings/lang-packages.nix index b6fff27..a91d9a5 100644 --- a/modules/module/settings/lang-packages.nix +++ b/modules/module/settings/lang-packages.nix @@ -45,7 +45,6 @@ janitor styler ]) - ++ [pkgs.nvimcom] ); julia = lib.mkDefault [ "DataFramesMeta" From 62f456ed46a4c283877bad845af6e404d637284a Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sat, 23 May 2026 23:54:07 +1000 Subject: [PATCH 24/28] hopefully R fix --- modules/module/settings/cat-packages.nix | 2 +- modules/module/settings/env.nix | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/module/settings/cat-packages.nix b/modules/module/settings/cat-packages.nix index 6406327..b92c331 100644 --- a/modules/module/settings/cat-packages.nix +++ b/modules/module/settings/cat-packages.nix @@ -8,7 +8,7 @@ let maybe = cat: pkgsList: lib.optionals (config.cats.${cat} or false) pkgsList; rPackages = (pkgs.baseRPackages or [ ]) ++ config.settings.lang_packages.r; - rWrapperPackages = rPackages ++ [pkgs.nvimcom]; + rWrapperPackages = rPackages; quartoPkg = if config.cats.r or false then pkgs.rpkgs.quarto.override { extraRPackages = rPackages; } diff --git a/modules/module/settings/env.nix b/modules/module/settings/env.nix index d7ecc36..c7a1a8b 100644 --- a/modules/module/settings/env.nix +++ b/modules/module/settings/env.nix @@ -13,15 +13,10 @@ }) (lib.mkIf (config.cats.r or false) { RNVIM_COMPLDIR = "$PWD/.r-compl"; - R_LIBS_USER = "$PWD/.r-libs"; TMPDIR = "$PWD/.r-tmp"; }) ]; # Environment variables with defaults (can be overridden by user) - config.envDefault = lib.mkMerge [ - (lib.mkIf (config.cats.r or false) { - R_LIBS_USER = "$PWD/.r-libs"; - }) - ]; + config.envDefault = lib.mkMerge [ ]; } From aec9110e709e1aa50d78f06293c4bde14974b23f Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Sun, 24 May 2026 00:01:12 +1000 Subject: [PATCH 25/28] hopefully R fix --- modules/module/settings/core.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/module/settings/core.nix b/modules/module/settings/core.nix index f8b3188..822fc53 100644 --- a/modules/module/settings/core.nix +++ b/modules/module/settings/core.nix @@ -32,4 +32,10 @@ # Enable wrapper handling of spec runtimeDeps (template pattern). config.settings.autowrapRuntimeDeps = true; + + # The wrapper library currently emits runtime PATH additions via `suffixVar`, + # which lets host-level tools in `/usr/local/bin` win inside `nix run`. + # Mirror those additions into `prefixVar` so wrapped Neovim resolves the + # Nix-provided toolchain first while preserving existing wrapper behavior. + config.prefixVar = lib.mkAfter config.suffixVar; } From 83b70216a980559ecd6823cf3e878f274ea743b7 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Mon, 8 Jun 2026 11:02:45 +0100 Subject: [PATCH 26/28] fixed treesitter --- lua/nix_smart_send.lua | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lua/nix_smart_send.lua b/lua/nix_smart_send.lua index c03af4c..1f82383 100644 --- a/lua/nix_smart_send.lua +++ b/lua/nix_smart_send.lua @@ -22,9 +22,11 @@ local COMMENT_TYPES = { } function M.get_current_node() - local ts_utils = require('nvim-treesitter.ts_utils') local cur_win = vim.api.nvim_get_current_win() - return ts_utils.get_node_at_cursor(cur_win, true) + return vim.treesitter.get_node({ + winid = cur_win, + ignore_injections = true, + }) end function M.detect_global_node() @@ -50,7 +52,6 @@ function M.detect_global_node() end function M.move_to_next_non_empty_line() - local ts_utils = require('nvim-treesitter.ts_utils') -- Search for the next non-empty line local line_num = vim.fn.search("[^;\\s]", "W") @@ -86,25 +87,27 @@ function M.move_to_next_non_empty_line() line_content = vim.api.nvim_buf_get_lines(0, line_num - 1, line_num, false)[1] first_non_ws = line_content:find("%S") or 1 vim.api.nvim_win_set_cursor(0, { line_num, first_non_ws - 1 }) - node = ts_utils.get_node_at_cursor() + node = vim.treesitter.get_node() end return true end function M.vselect_node(node) - local ts_utils = require('nvim-treesitter.ts_utils') if not node then return false end - local cur_buf = vim.api.nvim_get_current_buf() - ts_utils.update_selection(cur_buf, node, "V") + local start_row, _, end_row, _ = node:range() + + vim.api.nvim_win_set_cursor(0, { start_row + 1, 0 }) + vim.cmd("normal! V") + vim.api.nvim_win_set_cursor(0, { end_row + 1, 0 }) + return true end function M.select_until_global(global_nodes) - local ts_utils = require('nvim-treesitter.ts_utils') local root_node = M.detect_global_node() if not root_node and global_nodes then root_node = global_nodes[1] @@ -113,7 +116,7 @@ function M.select_until_global(global_nodes) -- Use empty table if no global nodes provided global_nodes = global_nodes or {} - local node = ts_utils.get_node_at_cursor() + local node = vim.treesitter.get_node() if not node then -- print("No syntax node found at cursor position") return nil @@ -167,7 +170,6 @@ function M.slime_send_region() end function M.send_repl(global_nodes) - local ts_utils = require('nvim-treesitter.ts_utils') local cur_node = M.get_current_node() if not cur_node then @@ -189,7 +191,9 @@ function M.send_repl(global_nodes) M.slime_send_region() -- Move cursor and continue - ts_utils.goto_node(sel_node, true) + local _, _, er, ec = sel_node:range() + vim.api.nvim_win_set_cursor(0, { er + 1, ec }) + M.move_to_next_non_empty_line() end From 3cf282e4f8d342021addd743400f11db8d88f811 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Mon, 8 Jun 2026 11:03:05 +0100 Subject: [PATCH 27/28] new font for gui --- plugin/00_options.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/00_options.lua b/plugin/00_options.lua index 2b4485b..e824333 100644 --- a/plugin/00_options.lua +++ b/plugin/00_options.lua @@ -176,7 +176,7 @@ if vim.g.neovide then vim.g.neovide_cursor_short_animation_length = 0 vim.g.neovide_font_hinting = 'none' vim.g.neovide_font_edging = 'subpixelantialias' - vim.o.guifont = 'Iosevka Nerd Font,Symbols Nerd Font:h14:#e-subpixelantialias:#h-none' + vim.o.guifont = 'JetBrainsMono Nerd Font,Symbols Nerd Font:h14:#e-subpixelantialias:#h-none' vim.g.neovide_floating_corner_radius = 0.35 vim.keymap.set("n", "nf", "NeovideFullscreen", { desc = "Toggle Neovide Fullscreen" }) end From 3ba96f380caf6e994515a76a31c43c2d1265400a Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Mon, 29 Jun 2026 09:59:40 +0200 Subject: [PATCH 28/28] Corrected Rnvim setup --- .gitignore | 1 + flake.lock | 24 ++++++++++++------------ flake.nix | 4 ++-- overlays/r.nix | 13 +++++-------- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index e402ff0..6e33f00 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .nvimcom .commandcode .commandcode/ +.r-* diff --git a/flake.lock b/flake.lock index 0b89d7a..21dc5ef 100644 --- a/flake.lock +++ b/flake.lock @@ -60,49 +60,49 @@ "rnvimsrc": "rnvimsrc" }, "locked": { - "lastModified": 1779438909, - "narHash": "sha256-1lvv0bdvSVyeCIgeZ7Ws7ffbDFurA5LJscS9dRLHzC8=", + "lastModified": 1781392459, + "narHash": "sha256-9CMG+trBd9AX7cWiGPrMr0eJwuZaql+pj2WVGyT417I=", "owner": "dwinkler1", "repo": "r_nvim_nix", - "rev": "ec17e22ab362a0ddfd6c2e9c5e95d43897a143be", + "rev": "03d7872d7702db37ede41f3c6e4d4ce4c129e862", "type": "github" }, "original": { "owner": "dwinkler1", - "ref": "v0.99.4", + "ref": "v0.99.5", "repo": "r_nvim_nix", "type": "github" } }, "rixpkgs": { "locked": { - "lastModified": 1771303851, - "narHash": "sha256-tgveHozOJ2D/mi3LxVy/FcmLFDlM5XKZxsNB2XpvzaM=", + "lastModified": 1782576256, + "narHash": "sha256-KOvpL9DJJmShb64mX9QTjhxHaxE8MizQIqNUAniuJ2E=", "owner": "dwinkler1", "repo": "rixpkgs", - "rev": "af2dd3f7b4b172077747c0869d4e30702fb71b0e", + "rev": "815afc01bc0cc9a2eba80906645bd08f976a4401", "type": "github" }, "original": { "owner": "dwinkler1", + "ref": "nixpkgs", "repo": "rixpkgs", - "rev": "af2dd3f7b4b172077747c0869d4e30702fb71b0e", "type": "github" } }, "rnvimsrc": { "flake": false, "locked": { - "lastModified": 1776905071, - "narHash": "sha256-dXox6qEs1VDE7vPNDoN8bY4g06uj1IEs6uki72w8lpA=", + "lastModified": 1780759435, + "narHash": "sha256-VxgKMOP1hseQre3cas2dmMXZu4PVyl05INla2OdHTU4=", "owner": "R-nvim", "repo": "R.nvim", - "rev": "582f2af11290ac067e49018db38e12a511325556", + "rev": "6ca306191531c3e3d501ee1609c84a5d29059386", "type": "github" }, "original": { "owner": "R-nvim", - "ref": "v0.99.4", + "ref": "v0.99.5", "repo": "R.nvim", "type": "github" } diff --git a/flake.nix b/flake.nix index ee9c05c..d8c0018 100644 --- a/flake.nix +++ b/flake.nix @@ -9,10 +9,10 @@ url = "github:BirdeeHub/nix-wrapper-modules"; inputs.nixpkgs.follows = "nixpkgs"; }; - rixpkgs.url = "github:dwinkler1/rixpkgs/af2dd3f7b4b172077747c0869d4e30702fb71b0e"; + rixpkgs.url = "github:dwinkler1/rixpkgs/nixpkgs"; r-nvim-nix = { - url = "github:dwinkler1/r_nvim_nix/v0.99.4"; + url = "github:dwinkler1/r_nvim_nix/v0.99.5"; inputs = { nixpkgs.follows = "rixpkgs"; }; diff --git a/overlays/r.nix b/overlays/r.nix index 18f01dd..e736b77 100644 --- a/overlays/r.nix +++ b/overlays/r.nix @@ -1,14 +1,11 @@ -{ - inputs, - ... -}: final: prev: let +{inputs, ...}: final: prev: let rpkgs = import inputs.rixpkgs { system = prev.stdenv.hostPlatform.system; - overlays = [inputs.fran.overlays.default]; + overlays = [inputs.fran.overlays.default inputs.r-nvim-nix.overlays.default]; }; in { inherit rpkgs; - baseRPackages = [ ]; - rWrapper = rpkgs.rWrapper.override {packages = [ ];}; - quarto = rpkgs.quarto.override {extraRPackages = [ ];}; + baseRPackages = [rpkgs.nvimcom]; + rWrapper = rpkgs.rWrapper.override {packages = [];}; + quarto = rpkgs.quarto.override {extraRPackages = [];}; }