From 490998275cbdc5ff032d4a39794bf850f4bfefec Mon Sep 17 00:00:00 2001 From: Hektor Misplon Date: Wed, 15 Oct 2025 22:18:59 +0200 Subject: [PATCH] Squashed 'dots/' changes from f64b634..f79bc54 f79bc54 Add minimal readme to my neovim configuration 4fe60cf Remove neovim lazy load related config 211da54 Fall back to 'paq.nvim' only when not on 'nixCats' b6d3015 Add 'nixCatsUtils' from 'nixCats' 139089f Add neovim packages to 'nixCats' flake a54e745 Add minimal 'nixCats' flake template 6e48621 Link NixOS repo in dotfiles repository git-subtree-dir: dots git-subtree-split: f79bc5427d4699c5c7b3ec72071370552367d36c --- .config/nvim/README.md | 6 + .config/nvim/flake.lock | 162 +++++++++++++++ .config/nvim/flake.nix | 212 ++++++++++++++++++++ .config/nvim/init.lua | 5 +- .config/nvim/lua/nixCatsUtils/catPacker.lua | 53 +++++ .config/nvim/lua/nixCatsUtils/init.lua | 136 +++++++++++++ .config/nvim/lua/paq-setup.lua | 37 +--- README.md | 3 + 8 files changed, 577 insertions(+), 37 deletions(-) create mode 100644 .config/nvim/README.md create mode 100644 .config/nvim/flake.lock create mode 100644 .config/nvim/flake.nix create mode 100644 .config/nvim/lua/nixCatsUtils/catPacker.lua create mode 100644 .config/nvim/lua/nixCatsUtils/init.lua diff --git a/.config/nvim/README.md b/.config/nvim/README.md new file mode 100644 index 0000000..56cfb3d --- /dev/null +++ b/.config/nvim/README.md @@ -0,0 +1,6 @@ +# Neovim configuration + +My neovim configuration. Available as a Nix flake [^nixcats]. When installing manually, +`paq.nvim` is used as a fallback plugin manager. + +[^nixcats]: Based on [this nixCats `example` template](https://github.com/BirdeeHub/nixCats-nvim/tree/77dffad8235eb77684fcb7599487c8e9f23d5b8f/templates/example) diff --git a/.config/nvim/flake.lock b/.config/nvim/flake.lock new file mode 100644 index 0000000..a1e599f --- /dev/null +++ b/.config/nvim/flake.lock @@ -0,0 +1,162 @@ +{ + "nodes": { + "nixCats": { + "locked": { + "lastModified": 1759730664, + "narHash": "sha256-boRlBQ/c4CaHsK/z04QL6+t81mcar37Io94HBX2GflY=", + "owner": "BirdeeHub", + "repo": "nixCats-nvim", + "rev": "77dffad8235eb77684fcb7599487c8e9f23d5b8f", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "nixCats-nvim", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1760256791, + "narHash": "sha256-uTpzDHRASEDeFUuToWSQ46Re8beXyG9dx4W36FQa0/c=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "832e3b6db48508ae436c2c7bfc0cf914eac6938e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "plugins-beancount-nvim": { + "flake": false, + "locked": { + "lastModified": 1707748314, + "narHash": "sha256-LuACGVB3kiaiJqoGtvFy6kbPNtqoGliKLDeR+Z7Wzbw=", + "owner": "polarmutex", + "repo": "beancount.nvim", + "rev": "869564aba3087ee5df8f282aa37555e314aa2152", + "type": "github" + }, + "original": { + "owner": "polarmutex", + "repo": "beancount.nvim", + "type": "github" + } + }, + "plugins-crazy-node-movement": { + "flake": false, + "locked": { + "lastModified": 1693654676, + "narHash": "sha256-hQcQEp39zFN2zphMfcr97yRVcuHhBsSkzKO7XNloDpQ=", + "owner": "theHamsta", + "repo": "crazy-node-movement", + "rev": "d5cf01cc44c5715501d3d6fe439af7c8b7fa5df2", + "type": "github" + }, + "original": { + "owner": "theHamsta", + "repo": "crazy-node-movement", + "type": "github" + } + }, + "plugins-helm-ls-nvim": { + "flake": false, + "locked": { + "lastModified": 1757598429, + "narHash": "sha256-nzuJxAAaEmuVYg9k0B8OKslxsihhg6RKlhz6E7xJTQU=", + "owner": "qvalentin", + "repo": "helm-ls.nvim", + "rev": "f36ecbd3e7b0b2ac8358a9d6a3213888e29943db", + "type": "github" + }, + "original": { + "owner": "qvalentin", + "repo": "helm-ls.nvim", + "type": "github" + } + }, + "plugins-mcphub-nvim": { + "flake": false, + "locked": { + "lastModified": 1759035242, + "narHash": "sha256-I6EbgY/2sAdtrxtmH0qbAAQvMCHhOsfolJfblV0fXOk=", + "owner": "ravitemer", + "repo": "mcphub.nvim", + "rev": "8ff40b5edc649959bb7e89d25ae18e055554859a", + "type": "github" + }, + "original": { + "owner": "ravitemer", + "repo": "mcphub.nvim", + "type": "github" + } + }, + "plugins-nvimkit-nvim": { + "flake": false, + "locked": { + "lastModified": 1721393835, + "narHash": "sha256-MdmrhLHMxrn6upu1chjKyitPZ5WkCQtpI465AKJXDOA=", + "owner": "jamesblckwell", + "repo": "nvimkit.nvim", + "rev": "af363d22699760f66988e8d36539a5753039217a", + "type": "github" + }, + "original": { + "owner": "jamesblckwell", + "repo": "nvimkit.nvim", + "type": "github" + } + }, + "plugins-shipwright-nvim": { + "flake": false, + "locked": { + "lastModified": 1711725275, + "narHash": "sha256-xh/2m//Cno5gPucjOYih79wVZj3X1Di/U3/IQhKXjc0=", + "owner": "rktjmp", + "repo": "shipwright.nvim", + "rev": "e596ab48328c31873f4f4d2e070243bf9de16ff3", + "type": "github" + }, + "original": { + "owner": "rktjmp", + "repo": "shipwright.nvim", + "type": "github" + } + }, + "plugins-tailwind-fold-nvim": { + "flake": false, + "locked": { + "lastModified": 1752559116, + "narHash": "sha256-8uefZIVsn9USEd6FyiO3m3TRKAS/vigU4t9Tk5ijd3c=", + "owner": "razak17", + "repo": "tailwind-fold.nvim", + "rev": "d9e7ca11691d252b35795726dff087bf013b2ebf", + "type": "github" + }, + "original": { + "owner": "razak17", + "repo": "tailwind-fold.nvim", + "type": "github" + } + }, + "root": { + "inputs": { + "nixCats": "nixCats", + "nixpkgs": "nixpkgs", + "plugins-beancount-nvim": "plugins-beancount-nvim", + "plugins-crazy-node-movement": "plugins-crazy-node-movement", + "plugins-helm-ls-nvim": "plugins-helm-ls-nvim", + "plugins-mcphub-nvim": "plugins-mcphub-nvim", + "plugins-nvimkit-nvim": "plugins-nvimkit-nvim", + "plugins-shipwright-nvim": "plugins-shipwright-nvim", + "plugins-tailwind-fold-nvim": "plugins-tailwind-fold-nvim" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/.config/nvim/flake.nix b/.config/nvim/flake.nix new file mode 100644 index 0000000..2206ad7 --- /dev/null +++ b/.config/nvim/flake.nix @@ -0,0 +1,212 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nixCats.url = "github:BirdeeHub/nixCats-nvim"; + + plugins-shipwright-nvim = { + url = "github:rktjmp/shipwright.nvim"; + flake = false; + }; + plugins-crazy-node-movement = { + url = "github:theHamsta/crazy-node-movement"; + flake = false; + }; + plugins-beancount-nvim = { + url = "github:polarmutex/beancount.nvim"; + flake = false; + }; + plugins-tailwind-fold-nvim = { + url = "github:razak17/tailwind-fold.nvim"; + flake = false; + }; + plugins-nvimkit-nvim = { + url = "github:jamesblckwell/nvimkit.nvim"; + flake = false; + }; + plugins-mcphub-nvim = { + url = "github:ravitemer/mcphub.nvim"; + flake = false; + }; + plugins-helm-ls-nvim = { + url = "github:qvalentin/helm-ls.nvim"; + flake = false; + }; + + }; + + outputs = + { + self, + nixpkgs, + nixCats, + ... + }@inputs: + let + inherit (nixCats) utils; + luaPath = ./.; + forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; + extra_pkg_config = { }; + + dependencyOverlays = [ + (utils.standardPluginOverlay inputs) + ]; + + categoryDefinitions = + { + pkgs, + ... + }: + { + lspsAndRuntimeDeps = with pkgs; { + general = [ + tree-sitter + ]; + }; + + startupPlugins = { + general = with pkgs.vimPlugins; [ + eyeliner-nvim + fzf-lua + ltex_extra-nvim + nvim-lspconfig + lsp_lines-nvim + lsp-progress-nvim + neodev-nvim + SchemaStore-nvim + nvim-lint + conform-nvim + luasnip + cmp_luasnip + nvim-cmp + cmp-nvim-lsp + cmp-buffer + cmp-path + plenary-nvim + nui-nvim + trouble-nvim + pkgs.neovimPlugins.shipwright-nvim + lush-nvim + zenbones-nvim + pkgs.neovimPlugins.crazy-node-movement + nvim-treesitter.withAllGrammars + nvim-treesitter-textobjects + # nvim-treesitter-context + nvim-ts-context-commentstring + treesj + sniprun + gitsigns-nvim + nvim-highlight-colors + pkgs.neovimPlugins.tailwind-fold-nvim + auto-session + nvim-dbee + image-nvim + pkgs.neovimPlugins.beancount-nvim + pkgs.neovimPlugins.nvimkit-nvim + codecompanion-nvim + pkgs.neovimPlugins.mcphub-nvim + copilot-lua + copilot-cmp + pkgs.neovimPlugins.helm-ls-nvim + ]; + }; + + optionalPlugins = { + general = with pkgs.vimPlugins; [ + ]; + }; + + sharedLibraries = { + general = [ ]; + }; + + environmentVariables = { }; + }; + + packageDefinitions = { + nvim = + { ... }: + { + settings = { + suffix-path = true; + suffix-LD = true; + wrapRc = true; + aliases = [ "vim" ]; + }; + categories = { + general = true; + }; + }; + }; + defaultPackageName = "nvim"; + in + + forEachSystem ( + system: + let + nixCatsBuilder = utils.baseBuilder luaPath { + inherit + nixpkgs + system + dependencyOverlays + extra_pkg_config + ; + } categoryDefinitions packageDefinitions; + defaultPackage = nixCatsBuilder defaultPackageName; + pkgs = import nixpkgs { inherit system; }; + in + { + packages = utils.mkAllWithDefault defaultPackage; + + devShells = { + default = pkgs.mkShell { + name = defaultPackageName; + packages = [ defaultPackage ]; + inputsFrom = [ ]; + shellHook = ''''; + }; + }; + + } + ) + // ( + let + nixosModule = utils.mkNixosModules { + moduleNamespace = [ defaultPackageName ]; + inherit + defaultPackageName + dependencyOverlays + luaPath + categoryDefinitions + packageDefinitions + extra_pkg_config + nixpkgs + ; + }; + homeModule = utils.mkHomeModules { + moduleNamespace = [ defaultPackageName ]; + inherit + defaultPackageName + dependencyOverlays + luaPath + categoryDefinitions + packageDefinitions + extra_pkg_config + nixpkgs + ; + }; + in + { + + overlays = utils.makeOverlays luaPath { + inherit nixpkgs dependencyOverlays extra_pkg_config; + } categoryDefinitions packageDefinitions defaultPackageName; + + nixosModules.default = nixosModule; + homeModules.default = homeModule; + + inherit utils nixosModule homeModule; + inherit (utils) templates; + } + ); + +} diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index 0fad537..2ed7ee5 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -1,9 +1,12 @@ +require("nixCatsUtils").setup({ non_nix_value = true }) -- https://github.com/BirdeeHub/nixCats-nvim/blob/77dffad8235eb77684fcb7599487c8e9f23d5b8f/templates/example/init.lua + require("vim") require("ftdetect") require("keymaps") require("highlight") -require("paq-setup") require("diagnostic") +require("paq-setup") -- when not on nixCats + -- vim.opt.background = "dark" -- vim.opt.laststatus = 3 diff --git a/.config/nvim/lua/nixCatsUtils/catPacker.lua b/.config/nvim/lua/nixCatsUtils/catPacker.lua new file mode 100644 index 0000000..bc28ccb --- /dev/null +++ b/.config/nvim/lua/nixCatsUtils/catPacker.lua @@ -0,0 +1,53 @@ +-- Source: https://github.com/BirdeeHub/nixCats-nvim/blob/main/templates/example/lua/nixCatsUtils/catPacker.lua +--[[ + This directory is the luaUtils template. + You can choose what things from it that you would like to use. + And then delete the rest. + Everything in this directory is optional. +--]] + +local M = {} +-- NOTE: This function is for defining a paq.nvim fallback method of downloading plugins +-- when nixCats was not used to install your config. +-- If you only ever load your config using nixCats, you don't need this file. + +-- it literally just only runs it when not on nixCats +-- all neovim package managers that use the regular plugin loading scheme +-- can be used this way, just do whatever the plugin manager needs to put it in the +-- opt directory for lazy loading, and add the build steps so that when theres no nix the steps are ran +function M.setup(v) + if not vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] then + local function clone_paq() + local path = vim.fn.stdpath("data") .. "/site/pack/paqs/start/paq-nvim" + local is_installed = vim.fn.empty(vim.fn.glob(path)) == 0 + if not is_installed then + vim.fn.system({ "git", "clone", "--depth=1", "https://github.com/savq/paq-nvim.git", path }) + return true + end + end + local function bootstrap_paq(packages) + local first_install = clone_paq() + vim.cmd.packadd("paq-nvim") + local paq = require("paq") + if first_install then + vim.notify("Installing plugins... If prompted, hit Enter to continue.") + end + paq(packages) + paq.install() + end + + vim.api.nvim_create_autocmd("VimEnter", { + once = true, + callback = function() + local pkgs_count = #require("paq").query("to_install") + if pkgs_count < 1 then + return + end + vim.notify(string.format("There are %d to install", pkgs_count)) + end, + }) + + bootstrap_paq(vim.list_extend({ "savq/paq-nvim" }, v)) + end +end +return M diff --git a/.config/nvim/lua/nixCatsUtils/init.lua b/.config/nvim/lua/nixCatsUtils/init.lua new file mode 100644 index 0000000..c8253d8 --- /dev/null +++ b/.config/nvim/lua/nixCatsUtils/init.lua @@ -0,0 +1,136 @@ +-- Source: https://github.com/BirdeeHub/nixCats-nvim/blob/main/templates/example/lua/nixCatsUtils/init.lua +--[[ + This directory is the luaUtils template. + You can choose what things from it that you would like to use. + And then delete the rest. + Everything in this directory is optional. +--]] + +local M = {} + +--[[ + This file is for making your config still work WITHOUT nixCats. + When you don't use nixCats to load your config, + you wont have the nixCats plugin. + + The setup function defined here defines a mock nixCats plugin when nixCats wasnt used to load the config. + This will help avoid indexing errors when the nixCats plugin doesnt exist. + + NOTE: If you only ever use nixCats to load your config, you don't need this file. +--]] + +---@type boolean +M.isNixCats = vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil + +---@class nixCatsSetupOpts +---@field non_nix_value boolean|nil + +---This function will setup a mock nixCats plugin when not using nix +---It will help prevent you from running into indexing errors without a nixCats plugin from nix. +---If you loaded the config via nix, it does nothing +---non_nix_value defaults to true if not provided or is not a boolean. +---@param v nixCatsSetupOpts +function M.setup(v) + if not M.isNixCats then + local nixCats_default_value + if type(v) == "table" and type(v.non_nix_value) == "boolean" then + nixCats_default_value = v.non_nix_value + else + nixCats_default_value = true + end + local mk_with_meta = function(tbl) + return setmetatable(tbl, { + __call = function(_, attrpath) + local strtable = {} + if type(attrpath) == "table" then + strtable = attrpath + elseif type(attrpath) == "string" then + for key in attrpath:gmatch("([^%.]+)") do + table.insert(strtable, key) + end + else + print("function requires a table of strings or a dot separated string") + return + end + return vim.tbl_get(tbl, unpack(strtable)) + end, + }) + end + package.preload["nixCats"] = function() + local ncsub = { + get = function(_) + return nixCats_default_value + end, + cats = mk_with_meta({ + nixCats_config_location = vim.fn.stdpath("config"), + wrapRc = false, + }), + settings = mk_with_meta({ + nixCats_config_location = vim.fn.stdpath("config"), + configDirName = os.getenv("NVIM_APPNAME") or "nvim", + wrapRc = false, + }), + petShop = mk_with_meta({}), + extra = mk_with_meta({}), + pawsible = mk_with_meta({ + allPlugins = { + start = {}, + opt = {}, + }, + }), + configDir = vim.fn.stdpath("config"), + packageBinPath = os.getenv("NVIM_WRAPPER_PATH_NIX") or vim.v.progpath, + } + return setmetatable(ncsub, { + __call = function(_, cat) + return ncsub.get(cat) + end, + }) + end + _G.nixCats = require("nixCats") + end +end + +---allows you to guarantee a boolean is returned, and also declare a different +---default value than specified in setup when not using nix to load the config +---@overload fun(v: string|string[]): boolean +---@overload fun(v: string|string[], default: boolean): boolean +function M.enableForCategory(v, default) + if M.isNixCats or default == nil then + if nixCats(v) then + return true + else + return false + end + else + return default + end +end + +---if nix, return value of nixCats(v) else return default +---Exists to specify a different non_nix_value than the one in setup() +---@param v string|string[] +---@param default any +---@return any +function M.getCatOrDefault(v, default) + if M.isNixCats then + return nixCats(v) + else + return default + end +end + +---for conditionally disabling build steps on nix, as they are done via nix +---I should probably have named it dontAddIfCats or something. +---@overload fun(v: any): any|nil +---Will return the second value if nix, otherwise the first +---@overload fun(v: any, o: any): any +function M.lazyAdd(v, o) + if M.isNixCats then + return o + else + return v + end +end + +return M diff --git a/.config/nvim/lua/paq-setup.lua b/.config/nvim/lua/paq-setup.lua index 6deeba1..273f181 100644 --- a/.config/nvim/lua/paq-setup.lua +++ b/.config/nvim/lua/paq-setup.lua @@ -1,38 +1,4 @@ --- Automate paq installation {{{ -local function clone_paq() - local path = vim.fn.stdpath("data") .. "/site/pack/paqs/start/paq-nvim" - local is_installed = vim.fn.empty(vim.fn.glob(path)) == 0 - if not is_installed then - vim.fn.system({ "git", "clone", "--depth=1", "https://github.com/savq/paq-nvim.git", path }) - return true - end -end -local function bootstrap_paq(packages) - local first_install = clone_paq() - vim.cmd.packadd("paq-nvim") - local paq = require("paq") - if first_install then - vim.notify("Installing plugins... If prompted, hit Enter to continue.") - end - paq(packages) - paq.install() -end - -vim.api.nvim_create_autocmd("VimEnter", { - once = true, - callback = function() - local pkgs_count = #require("paq").query("to_install") - if pkgs_count < 1 then - return - end - vim.notify(string.format("There are %d to install", pkgs_count)) - end, -}) - --- }}} - --- Set up paq plugins {{{ -bootstrap_paq({ +require("nixCatsUtils.catPacker").setup({ { "savq/paq-nvim" }, { "jinh0/eyeliner.nvim" }, { "ibhagwan/fzf-lua" }, @@ -77,4 +43,3 @@ bootstrap_paq({ { "zbirenbaum/copilot-cmp" }, { "qvalentin/helm-ls.nvim", ft = "helm" }, }) --- }}} diff --git a/README.md b/README.md index 0a51aed..fb139a5 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ bash <(curl -s https://git.hektormisplon.xyz/hektor/dots/raw/branch/master/.bin/ Note: will not set up *everything* (e.g. `/etc` configs, dependencies...), but should get you up and running. + +2025-10-04: I am migrating from Arch Linux to NixOS. For this transition, these +dotfiles are currently included as a subtree in my [NixOS repository](https://git.hektormisplon.xyz/hektor/nix).