From 42cd0732781ee8ba0b4b680bed324f168f1742f6 Mon Sep 17 00:00:00 2001
From: Matei Adriel <rafaeladriel11@gmail.com>
Date: Mon, 25 Dec 2023 14:14:33 +0100
Subject: [PATCH] Huge progress on korora-based tempest generation

---
 home/features/neovim/config/lua/my/init.lua   |    7 +-
 .../features/neovim/config/lua/my/keymaps.lua |   81 -
 home/features/neovim/config/lua/my/lazy.lua   |    2 +-
 .../features/neovim/config/lua/my/tempest.lua |   72 +-
 home/features/neovim/default.nix              | 2353 +++++++++--------
 modules/common/korora-lua.nix                 |  371 +--
 modules/common/korora-neovim.nix              |  252 +-
 modules/common/lua-encoders.nix               |    2 +-
 8 files changed, 1678 insertions(+), 1462 deletions(-)

diff --git a/home/features/neovim/config/lua/my/init.lua b/home/features/neovim/config/lua/my/init.lua
index 74d201a..4e3b81b 100644
--- a/home/features/neovim/config/lua/my/init.lua
+++ b/home/features/neovim/config/lua/my/init.lua
@@ -1,11 +1,14 @@
 local M = {}
 
 function M.setup()
+  vim.opt.runtimepath:append(vim.g.nix_extra_runtime)
+  local tempest = require("my.tempest")
+  local nix = require("nix")
   -- Import my other files
-  require("my.options").setup()
+  tempest.configureMany(nix.pre)
   require("my.keymaps").setup()
   require("my.lazy").setup()
-  require("my.abbreviations").setup()
+  tempest.configureMany(nix.post)
 end
 
 return M
diff --git a/home/features/neovim/config/lua/my/keymaps.lua b/home/features/neovim/config/lua/my/keymaps.lua
index fae8005..76faee8 100644
--- a/home/features/neovim/config/lua/my/keymaps.lua
+++ b/home/features/neovim/config/lua/my/keymaps.lua
@@ -55,92 +55,11 @@ end
 -- }}}
 
 function M.setup()
-  -- {{{ Free up q and Q
-  M.move("q", "yq", { desc = "Record macro" })
-  M.move("Q", "yQ")
-  -- }}}
-  -- {{{ Easier access to <C-^>
-  M.move("<C-^>", "<Leader>a", { desc = "[A]lternate file" })
-  -- }}}
-  -- {{{ Quit all buffers
-  M.nmap("Q", ":wqa<cr>", "Save all files and [q]uit")
-  -- }}}
-  -- {{{ Replace word in file
-  M.nmap("<leader>rw", ":%s/<C-r><C-w>/", "[R]eplace [w]ord in file")
-  -- }}}
-  -- {{{ Toggle settings
-  M.nmap(
-    "<leader>sw",
-    require("my.helpers.wrapMovement").toggle,
-    "toggle word [w]rap"
-  )
-  -- }}}
   -- {{{ Text objects
   M.delimitedTextobject("q", '"', "[q]uotes")
   M.delimitedTextobject("a", "'", "[a]postrophes")
   M.delimitedTextobject("r", "[", "squa[r]e brackets")
   -- }}}
-  -- {{{Diagnostic keymaps
-  M.nmap("[d", vim.diagnostic.goto_prev, "Goto previous [d]iagnostic")
-  M.nmap("]d", vim.diagnostic.goto_next, "Goto next [d]iagnostic")
-  M.move("J", "qj")
-  M.nmap("J", vim.diagnostic.open_float, "Open current diagnostic")
-  M.nmap("<leader>D", vim.diagnostic.setloclist, "[D]iagnostic loclist")
-  -- }}}
-  -- {{{ Chords (save, clipboard)
-  -- Different chords get mapped to f keys by a custom script of mine.
-  -- In the future, I might get this on my keyboard firmware.
-  vim.keymap.set({ "i", "v" }, "<f10>", "<Esc>", { desc = "Exit insert mode" }) -- Exit inset mode using *jk*
-  vim.keymap.set({ "n", "v" }, "<f11>", '"+', { desc = "Use global clipboard" }) -- Use global clipboard with *cp*
-  M.nmap("<f12>", "<cmd>silent write<cr>", "Save current file", true) -- Save using *ji*
-  -- }}}
-  -- {{{ Shift-Enter for not continuing the current comment
-  -- This does not preserve intendation. Not sure what a better solution would look like.
-  vim.keymap.set("i", "<S-CR>", function()
-    vim.paste({ "", "" }, -1)
-  end, { desc = "Insert newline without continuing the current comment" })
-  -- }}}
-  -- {{{ Allow quiting basic buffers with "qq"
-  vim.api.nvim_create_autocmd("FileType", {
-    pattern = { "help" },
-    group = vim.api.nvim_create_augroup("BasicBufferQuitting", {}),
-    callback = function(event)
-      vim.keymap.set(
-        "n",
-        "qq",
-        "<cmd>close<cr>",
-        { buffer = event.buf, silent = true, desc = "[q]uit current buffer" }
-      )
-    end,
-  })
-  -- }}}
-  -- {{{ Winblend
-  vim.api.nvim_create_autocmd("FileType", {
-    pattern = { "*" },
-    group = vim.api.nvim_create_augroup("WinblendSettings", {}),
-    callback = function()
-      vim.opt.winblend = 0
-    end,
-  })
-  -- }}}
-  -- {{{ Manage cmdheight
-  vim.api.nvim_create_autocmd("CmdlineEnter", {
-    group = vim.api.nvim_create_augroup("SetCmdheightCmdlineEnter", {}),
-    callback = function()
-      if not vim.g.inside_venn then
-        vim.opt.cmdheight = 1
-      end
-    end,
-  })
-  vim.api.nvim_create_autocmd("CmdlineLeave", {
-    group = vim.api.nvim_create_augroup("SetCmdheightCmdlineLeave", {}),
-    callback = function()
-      if not vim.g.inside_venn then
-        vim.opt.cmdheight = 0
-      end
-    end,
-  })
-  -- }}}
 end
 
 return M
diff --git a/home/features/neovim/config/lua/my/lazy.lua b/home/features/neovim/config/lua/my/lazy.lua
index d8bd7fd..0772aa0 100644
--- a/home/features/neovim/config/lua/my/lazy.lua
+++ b/home/features/neovim/config/lua/my/lazy.lua
@@ -7,8 +7,8 @@ end
 function M.setup()
   require("lazy").setup({
     importFrom("my.plugins"),
-    importFrom("nix.plugins"),
     importFrom("my.plugins.themes"),
+    unpack(require("nix").lazy),
   }, {
     defaults = { lazy = true },
     install = {
diff --git a/home/features/neovim/config/lua/my/tempest.lua b/home/features/neovim/config/lua/my/tempest.lua
index bc930c9..9f4bb87 100644
--- a/home/features/neovim/config/lua/my/tempest.lua
+++ b/home/features/neovim/config/lua/my/tempest.lua
@@ -119,17 +119,26 @@ end
 
 function M.configure(opts, context)
   if type(opts) == "function" then
-    return M.configure(opts(context), context)
+    opts = opts(context)
   end
 
-  if type(opts.mk_context) == "function" then
-    context = opts.mk_context(context)
+  if type(opts) ~= "table" then
+    -- TODO: throw
+    return
+  end
+
+  if type(opts.mkContext) == "function" then
+    context = opts.mkContext(context)
   end
 
   if type(opts.vim) == "table" then
     recursive_assign(opts.vim, vim)
   end
 
+  if type(opts.keys) == "function" then
+    opts.keys = opts.keys(context)
+  end
+
   if type(opts.keys) == "table" then
     local keys = opts.keys
 
@@ -143,6 +152,10 @@ function M.configure(opts, context)
     end
   end
 
+  if type(opts.autocmds) == "function" then
+    opts.autocmds = opts.autocmds(context)
+  end
+
   if type(opts.autocmds) == "table" then
     local autocmds = opts.autocmds
 
@@ -180,8 +193,10 @@ function M.configure(opts, context)
   end
 end
 
-M.lazy = function(lazy, opts, spec)
-  return M.configure(spec, { lazy = lazy, opts = opts })
+function M.configureMany(specs, context)
+  for _, spec in ipairs(specs) do
+    M.configure(spec, context)
+  end
 end
 -- }}}
 -- {{{ Neovim env handling
@@ -230,29 +245,46 @@ end
 -- {{{ Fixup lazy spec generated by nix
 function M.prepareLazySpec(spec)
   for _, module in ipairs(spec) do
-    if spec.tempest ~= nil then
-      spec.config = function(lazy, opts)
-        M.configure(spec.tempest, { lazy = lazy, opts = opts })
+    if module.package ~= nil then
+      module[1] = module.package
+      module.package = nil
+    end
+
+    local configType = type(module.config)
+    if configType == "function" or configType == "table" then
+      local previousConfig = module.config
+      module.config = function(lazy, opts)
+        M.configure(previousConfig, { lazy = lazy, opts = opts })
       end
     end
 
-    if spec.dependencies ~= nil then
-      spec.dependencies = spec.dependencies.lua
-    end
-
-    if spec.keys ~= nil then
-      local keys = spec.keys
-      if spec.keys.mapping ~= nil then
-        keys = { keys }
+    if module.keys ~= nil then
+      if type(module.keys) == "string" or module.keys.mapping ~= nil then
+        module.keys = { module.keys }
       end
 
-      for _, key in ipairs(keys) do
-        key[1] = key.mapping
-        if key.mode ~= nil then
-          key.mode = H.string_chars(key.mode)
+      for _, key in ipairs(module.keys) do
+        if type(key) ~= "string" then
+          key[1] = key.mapping
+          key.mapping = nil
+          if key.mode ~= nil then
+            key.mode = H.string_chars(key.mode)
+          end
+          if key.action ~= nil then
+            key[2] = key.action
+            key.action = nil
+          end
         end
       end
     end
+
+    if type(module.cond) == "table" then
+      local final = true
+      for _, cond in ipairs(module.cond) do
+        final = final and cond
+      end
+      module.cond = final
+    end
   end
 end
 -- }}}
diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix
index d510990..b9b2ecf 100644
--- a/home/features/neovim/default.nix
+++ b/home/features/neovim/default.nix
@@ -1,5 +1,1267 @@
 { upkgs, pkgs, lib, config, inputs, ... }:
 let
+  korora = inputs.korora.lib;
+  nlib = import ../../../modules/common/korora-neovim.nix
+    {
+      inherit lib korora;
+    }
+    {
+      languageServerModule = "my.plugins.lspconfig";
+      tempestModule = "my.tempest";
+    };
+
+  generated = nlib.generateConfig (lib.fix (self: {
+    # {{{ Pre-plugin config
+    pre = {
+      # {{{ General options
+      "0:general-options".vim = {
+        g = {
+          # Disable filetype.vim
+          do_filetype_lua = true;
+          did_load_filetypes = false;
+
+          # Set leader
+          mapleader = " ";
+        };
+
+        opt = {
+          # Basic options
+          joinspaces = false; # No double spaces with join (mapped to qj in my config)
+          list = true; # Show some invisible characters
+          cmdheight = 0; # Hide command line when it's not getting used
+
+          # tcqj are there by default, and "r" automatically continues comments on enter
+          formatoptions = "tcqjr";
+
+          scrolloff = 4; # Starts scrolling 4 lines from the edge of the screen
+          termguicolors = true; # True color support
+
+          wrap = false; # Disable line wrap (by default)
+          wildmode = [ "list" "longest" ]; # Command-line completion mode
+          completeopt = [ "menu" "menuone" "noselect" ];
+
+          undofile = true; # persist undos!!
+
+          # {{{ Line numbers
+          number = true; # Show line numbers
+          relativenumber = true; # Relative line numbers
+          # }}}
+          # {{{ Indents
+          expandtab = true; # Use spaces for the tab char
+          shiftwidth = 2; # Size of an indent
+          tabstop = 2; # Size of tab character
+          shiftround = true; # When using < or >, rounds to closest multiple of shiftwidth
+          smartindent = true; # Insert indents automatically
+          # }}}
+          # {{{ Casing 
+          ignorecase = true; # Ignore case
+          smartcase = true; # Do not ignore case with capitals
+          # }}}
+          # {{{ Splits
+          splitbelow = true; # Put new windows below current
+          splitright = true; # Put new windows right of current
+          # }}}
+          # {{{ Folding
+          foldmethod = "marker"; # use {{{ }}} for folding
+          foldcolumn = "1"; # show column with folds on the left
+          # }}}
+        };
+
+        # Disable pseudo-transparency;
+        autocmds = {
+          event = "FileType";
+          group = " WinblendSettings";
+          action.vim.opt.winblend = 0;
+        };
+      };
+      # }}}
+      # {{{ Misc keybinds
+      "1:misc-keybinds" = {
+        # {{{ Global keybinds 
+        keys =
+          let
+            # {{{ Keybind helpers 
+            nmap = mapping: action: desc:
+              { inherit mapping action desc; };
+            unmap = mapping:
+              { inherit mapping; action = "<nop>"; };
+            dmap = mapping: action: desc: {
+              inherit mapping desc;
+              action = nlib.lua "vim.diagnostic.${action}";
+            };
+            # }}}
+          in
+          [
+            # {{{ Free up q and Q
+            (nmap "<c-q>" "q" "Record macro")
+            (nmap "<c-s-q>" "Q" "Repeat last recorded macro")
+            (unmap "q")
+            (unmap "Q")
+            # }}}
+            # {{{ Chords
+            # Different chords get remapped to f-keys by my slambda config.
+            # See [my slambda config](../../../hosts/nixos/common/optional/services/slambda.nix) for details.
+            #
+            # Exit insert mode using *jk*
+            {
+              mode = "iv";
+              mapping = "<f10>";
+              action = "<esc>";
+              desc = "Exit insert mode";
+            }
+            # Use global clipboard using *cp*
+            {
+              mode = "nv";
+              mapping = "<f11>";
+              action = ''"+'';
+              desc = "Use global clipboard";
+            }
+            # Save using *ji*
+            (nmap "<f12>" "<cmd>silent write<cr>" "Save current file")
+            # }}}
+            # {{{ Newline without comments 
+            {
+              mode = "i";
+              mapping = "<c-cr>";
+              action = nlib.thunk /* lua */ ''
+                vim.paste({ "", "" }, -1)
+              '';
+              desc = "Insert newline without continuing the current comment";
+            }
+            {
+              mode = "i";
+              mapping = "<c-s-cr>";
+              # This is a bit scuffed and might not work for all languages
+              action = "<cmd>norm O<bs><bs><bs><cr>";
+              desc = "Insert newline above without continuing the current comment";
+            }
+            # }}}
+            # {{{ Diagnostics
+            (dmap "[d" "goto_prev" "Goto previous [d]iagnostic")
+            (dmap "]d" "goto_next" "Goto next [d]iagnostic")
+            (dmap "J" "open_float" "Open current diagnostic")
+            (dmap "<leader>D" "setloclist" "[D]iagnostic loclist")
+            {
+              mapping = "qj";
+              action = "J";
+              desc = "join lines";
+            }
+            # }}}
+            # {{{ Other misc keybinds 
+            (nmap "<Leader>a" "<C-^>" "[A]lternate file")
+            (unmap "<C-^>")
+            (nmap "Q" ":wqa<cr>" "Save all files and [q]uit")
+            (nmap "<leader>rw" ":%s/<C-r><C-w>/" "[R]eplace [w]ord in file")
+            (nmap "<leader>sw"
+              (nlib.lua ''require("my.helpers.wrapMovement").toggle'')
+              "toggle word [w]rap")
+            # }}}
+          ];
+        # }}}
+        # {{{ Exit certain buffers with qq 
+        autocmds = {
+          event = "FileType";
+          pattern = [ "help" ];
+          group = "BasicBufferQuitting";
+          action.keys = {
+            mapping = "qq";
+            action = "<cmd>close<cr>";
+            desc = "[q]uit current buffer";
+          };
+        };
+        # }}}
+      };
+      # }}}
+      # {{{ Manage cmdheight 
+      "2:manage-cmdheight".autocmds = [
+        {
+          event = "CmdlineEnter";
+          group = "SetCmdheightCmdlineEnter";
+          action.vim.opt.cmdheight = 1;
+        }
+        {
+          event = "CmdlineLeave";
+          group = "SetCmdheightCmdlineLeave";
+          action.vim.opt.cmdheight = 0;
+        }
+      ];
+      # }}}
+    };
+    # }}}
+    # {{{ Plugins
+    lazy = {
+      # {{{ libraries
+      # {{{ plenary
+      plenary = {
+        package = "nvim-lua/plenary.nvim";
+        # Autoload when running tests
+        cmd = [ "PlenaryBustedDirectory" "PlenaryBustedFile" ];
+      };
+      # }}}
+      # {{{ nui
+      nui.package = "MunifTanjim/nui.nvim";
+      # }}}
+      # {{{ web-devicons
+      web-devicons.package = "nvim-tree/nvim-web-devicons";
+      # }}}
+      # {{{ Scrap
+      scrap = {
+        package = "mateiadrielrafael/scrap.nvim";
+
+        event = "InsertEnter";
+        config.setup."my.abbreviations" = true;
+      };
+      # }}}
+      # }}}
+      # {{{ ui
+      # {{{ nvim-tree 
+      nvim-tree = {
+        package = "kyazdani42/nvim-tree.lua";
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        config = true;
+
+        keys.mapping = "<C-n>";
+        keys.desc = "Toggle [n]vim-tree";
+        keys.action = "<cmd>NvimTreeToggle<cr>";
+      };
+      # }}}
+      # {{{ mini.statusline
+      mini-statusline = {
+        package = "echasnovski/mini.statusline";
+        name = "mini.statusline";
+        dependencies.lua = [ self.lazy.web-devicons.package ];
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        lazy = false;
+
+        opts.content.inactive = nlib.thunk /* lua */ ''
+          require("mini.statusline").combine_groups({
+            { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } },
+          })
+        '';
+
+        opts.content.active = nlib.thunk /* lua */ ''
+          local st = require("mini.statusline");
+          local mode, mode_hl = st.section_mode({ trunc_width = 120 })
+          local git = st.section_git({ trunc_width = 75 })
+          local diagnostics = st.section_diagnostics({ trunc_width = 75 })
+
+          return st.combine_groups({
+            { hl = mode_hl, strings = { mode } },
+            { hl = "MiniStatuslineDevinfo", strings = { git } },
+            { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } },
+            "%=", -- End left alignment
+            { hl = "MiniStatuslineFilename", strings = { diagnostics } },
+            { hl = "MiniStatuslineDevinfo", strings = { vim.bo.filetype } },
+          })
+        '';
+      };
+      # }}}
+      # {{{ mini.files
+      mini-files = {
+        package = "echasnovski/mini.files";
+        name = "mini.files";
+        dependencies.lua = [ self.lazy.web-devicons.package ];
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        keys = {
+          mapping = "<c-s-f>";
+          desc = "[S]earch [F]iles";
+          action = nlib.thunk /* lua */ ''
+            local files = require("mini.files")
+            if not files.close() then
+              files.open(vim.api.nvim_buf_get_name(0))
+              files.reveal_cwd()
+            end
+          '';
+        };
+
+        opts.windows.preview = false;
+        opts.mappings.go_in_plus = "l";
+      };
+      # }}}
+      # {{{ winbar
+      winbar = {
+        package = "fgheng/winbar.nvim";
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        event = "BufReadPost";
+
+        opts.enabled = true;
+        # TODO: blacklist harpoon, NeogitStatus
+      };
+      # }}}
+      # {{{ harpoon
+      harpoon = {
+        package = "ThePrimeagen/harpoon";
+        keys =
+          let goto = key: index: {
+            desc = "Goto harpoon file ${toString index}";
+            mapping = "<c-s>${key}";
+            action = nlib.thunk
+              /* lua */ ''require("harpoon.ui").nav_file(${toString index})'';
+          };
+          in
+          [
+            {
+              desc = "Add file to [h]arpoon";
+              mapping = "<leader>H";
+              action = nlib.thunk
+                /* lua */ ''require("harpoon.mark").add_file()'';
+            }
+            {
+              desc = "Toggle harpoon quickmenu";
+              mapping = "<c-a>";
+              action = nlib.thunk
+                /* lua */ ''require("harpoon.ui").toggle_quick_menu()'';
+            }
+            (goto "q" 1)
+            (goto "w" 2)
+            (goto "e" 3)
+            (goto "r" 4)
+            (goto "a" 5)
+            (goto "s" 6)
+            (goto "d" 7)
+            (goto "f" 8)
+            (goto "z" 9)
+          ];
+      };
+      # }}}
+      # {{{ neogit
+      neogit = {
+        package = "TimUntersberger/neogit";
+        dependencies.lua = [ self.lazy.plenary.package ];
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        cmd = "Neogit"; # We sometimes spawn this directly from fish using a keybind
+        keys = {
+          mapping = "<c-g>";
+          action = "<cmd>Neogit<cr>";
+          desc = "Open neo[g]it";
+        };
+
+        opts = true; # Here so the tempest runtime will call .setup
+        config.autocmds = {
+          event = "FileType";
+          pattern = "NeogitStatus";
+          group = "NeogitStatusDisableFolds";
+          action.vim.opt.foldenable = false;
+        };
+      };
+      # }}}
+      # {{{ telescope
+      telescope = {
+        package = "nvim-telescope/telescope.nvim";
+        version = "0.1.x";
+        cond = nlib.blacklist "vscode";
+
+        # {{{ Dependencies
+        dependencies = {
+          nix = [ pkgs.ripgrep ];
+          lua = [
+            self.lazy.plenary.package
+            {
+              # We want a prebuilt version of this plugin
+              dir = pkgs.vimPlugins.telescope-fzf-native-nvim;
+              name = "telescope-fzf-native";
+            }
+          ];
+        };
+        # }}}
+        # {{{ Keymaps
+        keys =
+          let
+            keymap = mapping: action: desc: {
+              inherit mapping desc;
+              action = "<cmd>Telescope ${action} theme=ivy<cr>";
+            };
+
+            findFilesByExtension = mapping: extension: tag:
+              keymap
+                "<leader>f${mapping}"
+                "find_files find_command=rg,--files,--glob=**/*.${extension}"
+                "Find ${tag} files";
+          in
+          [
+            (keymap "<c-p>" "find_files" "File finder [p]alette")
+            (keymap "<leader>d" "diagnostics" "[D]iagnostics")
+            (keymap "<c-f>" "live_grep" "[F]ind in project")
+            (keymap "<leader>t" "builtin" "[T]elescope pickers")
+            # {{{ Files by extension 
+            (findFilesByExtension "tx" "tex" "[t]ex")
+            (findFilesByExtension "ts" "ts" "[t]ypescript")
+            (findFilesByExtension "ty" "typ" "[t]ypst")
+            (findFilesByExtension "l" "lua" "[l]ua")
+            (findFilesByExtension "n" "nix" "[n]ua")
+            (findFilesByExtension "p" "purs" "[p]urescript")
+            (findFilesByExtension "h" "hs" "[h]askell")
+            (findFilesByExtension "e" "elm" "[e]lm")
+            (findFilesByExtension "r" "rs" "[r]ust")
+            # }}}
+          ];
+        # }}}
+        # {{{ Disable folds in telescope windows
+        config.autocmds = {
+          event = "FileType";
+          pattern = "TelescopeResults";
+          group = "TelescopeResultsDisableFolds";
+          action.vim.opt.foldenable = false;
+        };
+        # }}}
+        # {{{ Load fzf extension
+        config.callback = nlib.thunk /* lua */ ''
+          require("telescope").load_extension("fzf")
+        '';
+        # }}}
+        # {{{ Options
+        opts.defaults.mappings.i."<C-h>" = "which_key";
+        opts.pickers.find_files.hidden = true;
+        opts.extensions.fzf = {
+          fuzzy = true;
+          override_generic_sorter = true;
+          override_file_sorter = true;
+        };
+        # }}}
+      };
+      # }}}
+      # }}}
+      # {{{ visual
+      # The line between `ui` and `visual` is a bit rought. I currenlty mostly judge
+      # it by vibe.
+      # {{{ indent-blankline 
+      indent-blankline = {
+        package = "lukas-reineke/indent-blankline.nvim";
+        main = "ibl";
+        config = true;
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost";
+      };
+      # }}}
+      # {{{ live-command
+      # Live command preview for commands like :norm
+      live-command = {
+        package = "smjonas/live-command.nvim";
+        version = "remote"; # https://github.com/smjonas/live-command.nvim/pull/29
+        main = "live-command";
+
+        event = "CmdlineEnter";
+        opts.commands.Norm.cmd = "norm";
+        opts.commands.G.cmd = "g";
+
+        keys = {
+          mode = "v";
+          mapping = "N";
+          action = ":Norm ";
+          desc = "Map lines in [n]ormal mode";
+        };
+      };
+      # }}}
+      # {{{ fidget
+      fidget = {
+        package = "j-hui/fidget.nvim";
+        tag = "legacy";
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPre";
+        config = true;
+      };
+      # }}}
+      # {{{ treesitter
+      treesitter = {
+        # REASON: more grammars
+        dir = upkgs.vimPlugins.nvim-treesitter.withAllGrammars;
+        dependencies.lua = [ "nvim-treesitter/nvim-treesitter-textobjects" ];
+        dependencies.nix = [ pkgs.tree-sitter ];
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost";
+
+        #{{{ Highlighting
+        opts.highlight = {
+          enable = true;
+          disable = [ "kotlin" ]; # This one seemed a bit broken
+          additional_vim_regex_highlighting = false;
+        };
+        #}}}
+        # {{{ Textobjects
+        opts.textobjects = {
+          #{{{ Select
+          select = {
+            enable = true;
+            lookahead = true;
+            keymaps = {
+              # You can use the capture groups defined in textobjects.scm
+              af = "@function.outer";
+              "if" = "@function.inner";
+              ac = "@class.outer";
+              ic = "@class.inner";
+            };
+          };
+          #}}}
+          #{{{ Move
+          move = {
+            enable = true;
+            set_jumps = true; # whether to set jumps in the jumplist
+            goto_next_start = {
+              "]f" = "@function.outer";
+              "]t" = "@class.outer";
+            };
+            goto_next_end = {
+              "]F" = "@function.outer";
+              "]T" = "@class.outer";
+            };
+            goto_previous_start = {
+              "[f" = "@function.outer";
+              "[t" = "@class.outer";
+            };
+            goto_previous_end = {
+              "[F" = "@function.outer";
+              "[T" = "@class.outer";
+            };
+          };
+          #}}}
+        };
+        # }}}
+        opts.indent.enable = true;
+      };
+      # }}}
+      # {{{ treesitter context
+      # Show context at the of closing delimiters
+      treesitter-virtual-context = {
+        package = "haringsrob/nvim_context_vt";
+        dependencies.lua = [ "treesitter" ];
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost";
+      };
+
+      # show context at top of file
+      treesitter-top-context = {
+        package = "nvim-treesitter/nvim-treesitter-context";
+        dependencies.lua = [ "treesitter" ];
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost";
+        opts.enable = true;
+      };
+      # }}}
+      # }}}
+      # {{{ editing {{{ text navigation
+      # {{{ flash
+      flash = {
+        package = "folke/flash.nvim";
+
+        cond = nlib.blacklist "vscode";
+        keys =
+          let keybind = mode: mapping: action: desc: {
+            inherit mapping desc mode;
+            action = nlib.thunk /* lua */ ''require("flash").${action}()'';
+          };
+          in
+          [
+            (keybind "nxo" "s" "jump" "Flash")
+            (keybind "nxo" "S" "treesitter" "Flash Treesitter")
+            (keybind "o" "r" "remote" "Remote Flash")
+            (keybind "ox" "R" "treesitter_search" "Treesitter Search")
+            (keybind "c" "<C-S>" "toggle" "Toggle Flash Search")
+          ];
+
+        # Disable stuff like f/t/F/T
+        opts.modes.char.enabled = false;
+      };
+      # }}}
+      # {{{ ftft (quickscope but written in lua)
+      ftft = {
+        package = "gukz/ftFT.nvim";
+
+        cond = nlib.blacklist "vscode";
+        keys = [ "f" "F" "t" "T" ];
+        config = true;
+      };
+      # }}}
+      # }}}
+      # {{{ clipboard-image
+      clipboard-image = {
+        package = "postfen/clipboard-image.nvim";
+
+        cond = nlib.blacklist "firenvim";
+        cmd = "PasteImg";
+
+        keys = {
+          mapping = "<leader>p";
+          action = "<cmd>PasteImg<cr>";
+          desc = "[P]aste image from clipboard";
+        };
+
+        opts.default.img_name = nlib.import ./plugins/clipboard-image.lua "img_name";
+        opts.tex = {
+          img_dir = [ "%:p:h" "img" ];
+          affix = "\\includegraphics[width=\\textwidth]{%s}";
+        };
+        opts.typst = {
+          img_dir = [ "%:p:h" "img" ];
+          affix = ''#image("%s", width: 100)'';
+        };
+      };
+      # }}}
+      # {{{ lastplace 
+      lastplace = {
+        package = "ethanholz/nvim-lastplace";
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPre";
+
+        opts.lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ];
+      };
+      # }}}
+      # {{{ undotree
+      undotree = {
+        package = "mbbill/undotree";
+
+        cond = nlib.blacklist "vscode";
+        cmd = "UndotreeToggle";
+        keys = {
+          mapping = "<leader>u";
+          action = "<cmd>UndoTreeToggle<cr>";
+          desc = "[U]ndo tree";
+        };
+      };
+      # }}}
+      # {{{ ssr (structured search & replace)
+      ssr = {
+        package = "cshuaimin/ssr.nvim";
+
+        cond = nlib.blacklist "vscode";
+        keys = {
+          mode = "nx";
+          mapping = "<leader>rt";
+          action = nlib.thunk /* lua */ ''require("ssr").open()'';
+          desc = "[r]eplace [t]emplate";
+        };
+
+        opts.keymaps.replace_all = "<s-cr>";
+      };
+      # }}}
+      # {{{ edit-code-block (edit injections in separate buffers)
+      edit-code-block = {
+        package = "dawsers/edit-code-block.nvim";
+        dependencies.lua = [ "treesitter" ];
+        main = "ecb";
+
+        cond = nlib.blacklist "vscode";
+        config = true;
+        keys = {
+          mapping = "<leader>e";
+          action = "<cmd>EditCodeBlock<cr>";
+          desc = "[e]dit injection";
+        };
+      };
+      # }}}
+      # {{{ mini.comment 
+      mini-comment = {
+        package = "echasnovski/mini.comment";
+        name = "mini.comment";
+
+        config = true;
+        keys = [
+          { mapping = "gc"; mode = "nxv"; }
+          "gcc"
+        ];
+      };
+      # }}}
+      # {{{ mini.surround
+      mini-surround = {
+        package = "echasnovski/mini.surround";
+        name = "mini.surround";
+
+        keys = lib.flatten [
+          # ^ doing the whole `flatten` thing to lie to my formatter
+          { mapping = "<tab>s"; mode = "nv"; }
+          [ "<tab>d" "<tab>f" "<tab>F" "<tab>h" "<tab>r" ]
+        ];
+
+        # {{{ Keymaps
+        opts.mappings = {
+          add = "<tab>s"; # Add surrounding in Normal and Visul modes
+          delete = "<tab>d"; # Delete surrounding
+          find = "<tab>f"; # Find surrounding (to the right)
+          find_left = "<tab>F"; # Find surrounding (to the left)
+          highlight = "<tab>h"; # Highlight surrounding
+          replace = "<tab>r"; # Replace surrounding
+          update_n_lines = ""; # Update `n_lines`
+        };
+        # }}}
+        # {{{ Custom surroundings
+        opts.custom_surroundings =
+          let mk = balanced: input: left: right: {
+            input = [
+              input
+              (if balanced
+              then "^.%s*().-()%s*.$"
+              else "^.().*().$")
+            ];
+            output = { inherit left right; };
+          };
+          in
+          {
+            b = mk true "%b()" "(" ")";
+            B = mk true "%b{}" "{" "}";
+            r = mk true "%b[]" "[" "]";
+            q = mk false "\".-\"" "\"" "\"";
+            a = mk false "'.-'" "'" "'";
+          };
+        # }}}
+      };
+      # }}}
+      # {{{ mini.operators
+      mini-operators = {
+        package = "echasnovski/mini.operators";
+        name = "mini.operators";
+
+        config = true;
+        keys =
+          let operator = key: [
+            { mapping = "g${key}"; mode = "nv"; }
+            "g${key}${key}"
+          ];
+          in
+          lib.flatten [
+            (operator "=")
+            (operator "x")
+            (operator "r")
+            (operator "s")
+          ];
+      };
+      # }}}
+      # {{{ luasnip
+      # snippeting engine
+      luasnip =
+        let reload = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()'';
+        in
+        {
+          package = "L3MON4D3/LuaSnip";
+          version = "v2";
+
+          cond = nlib.blacklist "vscode";
+          config = nlib.thunk reload;
+
+          # {{{ Keybinds
+          keys = [
+            {
+              mapping = "<leader>rs";
+              action = nlib.thunk reload;
+              desc = "[R]eload [s]nippets";
+            }
+            {
+              mode = "i";
+              expr = true;
+              mapping = "<tab>";
+              action = nlib.thunk /* lua */ ''
+                local luasnip = require("luasnip")
+
+                if not luasnip.jumpable(1) then
+                  return "<tab>"
+                end
+
+                vim.schedule(function()
+                  luasnip.jump(1)
+                end)
+
+                return "<ignore>"
+              '';
+              desc = "Jump to next snippet tabstop";
+            }
+            {
+              mode = "i";
+              mapping = "<s-tab>";
+              action = nlib.thunk /* lua */ ''
+                require("luasnip").jump(-1)
+              '';
+              desc = "Jump to previous snippet tabstop";
+            }
+          ];
+          # }}}
+        };
+      # }}}
+      # }}}
+      # {{{ ide
+      # {{{ conform
+      conform = {
+        package = "stevearc/conform.nvim";
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost";
+
+        opts.format_on_save.lsp_fallback = true;
+        opts.formatters_by_ft = let prettier = [ [ "prettierd" "prettier" ] ]; in
+          {
+            lua = [ "stylua" ];
+            python = [ "ruff_format" ];
+
+            javascript = prettier;
+            typescript = prettier;
+            javascriptreact = prettier;
+            typescriptreact = prettier;
+            html = prettier;
+            css = prettier;
+            markdown = prettier;
+          };
+      };
+      # }}}
+      # {{{ neoconf
+      neoconf = {
+        package = "folke/neoconf.nvim";
+
+        cmd = "Neoconf";
+
+        opts.import = {
+          vscode = true; # local .vscode/settings.json
+          coc = false; # global/local coc-settings.json
+          nlsp = false; # global/local nlsp-settings.nvim json settings
+        };
+      };
+      # }}}
+      # {{{ null-ls
+      null-ls = {
+        package = "jose-elias-alvarez/null-ls.nvim";
+        dependencies.lua = [ "neovim/nvim-lspconfig" ];
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPre";
+
+        opts = nlib.thunk /* lua */ ''
+          local p = require("null-ls")
+          return {
+            on_attach = require("my.plugins.lspconfig").on_attach, 
+            sources = {
+              p.builtins.diagnostics.ruff
+            }
+          }
+        '';
+      };
+      # }}}
+      # {{{ gitsigns
+      gitsigns = {
+        package = "lewis6991/gitsigns.nvim";
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        event = "BufReadPost";
+
+        opts.on_attach = nlib.tempest {
+          mkContext = nlib.lua /* lua */
+            "function(bufnr) return { bufnr = bufnr } end";
+          keys =
+            let
+              prefix = m: "<leader>h${m}";
+              gs = "package.loaded.gitsigns";
+
+              # {{{ nmap helper
+              nmap = mapping: action: desc: {
+                inherit desc;
+                mapping = prefix "mapping";
+                action = "${gs}.action";
+              };
+              # }}}
+              # {{{ exprmap helper
+              exprmap = mapping: action: desc: {
+                inherit mapping desc;
+                action = nlib.thunk /* lua */ ''
+                  if vim.wo.diff then
+                    return "${mapping}"
+                  end
+
+                  vim.schedule(function()
+                    ${gs}.${action}()
+                  end)
+
+                  return "<ignore>"
+                '';
+                expr = true;
+              };
+              # }}}
+            in
+            [
+              # {{{ navigation
+              (exprmap "]c" "next_hunk" "Navigate to next hunk")
+              (exprmap "[c" "prev_hunk" "Navigate to previous hunk")
+              # }}}
+              # {{{ actions
+              (nmap "s" "stage_hunk" "[s]tage hunk")
+              (nmap "r" "reset_hunk" "[s]tage hunk")
+              (nmap "S" "stage_buffer" "[s]tage hunk")
+              (nmap "u" "undo_stage_hunk" "[s]tage hunk")
+              (nmap "R" "reset_buffer" "[s]tage hunk")
+              (nmap "p" "preview_hunk" "[s]tage hunk")
+              (nmap "d" "diffthis" "[s]tage hunk")
+              {
+                mapping = prefix "D";
+                action = nlib.thunk ''
+                  ${gs}.diffthis("~")
+                '';
+                desc = "[d]iff file (?)";
+              }
+              {
+                mapping = prefix "b";
+                action = nlib.thunk ''
+                  ${gs}.blame_line({ full = true })
+                '';
+                desc = "[b]lame line";
+              }
+              # }}}
+              # {{{ Toggles
+              (nmap "tb" "toggle_current_line_blame" "[t]oggle line [b]laming")
+              (nmap "td" "toggle_deleted" "[t]oggle [d]eleted")
+              # }}}
+              # {{{ visual mappings
+              {
+                mode = "v";
+                mapping = prefix "s";
+                action = nlib.thunk /* lua */ ''
+                  ${gs}.stage_hunk({ vim.fn.line("."), vim.fn.line("v") })
+                '';
+                desc = "stage visual hunk";
+              }
+              {
+                mode = "v";
+                mapping = prefix "r";
+                action = nlib.thunk /* lua */ ''
+                  ${gs}.reset_hunk({ vim.fn.line("."), vim.fn.line("v") })
+                '';
+                desc = "reset visual hunk";
+              }
+              # }}}
+            ];
+        };
+      };
+      # }}}
+      # {{{ cmp
+      cmp = {
+        package = "hrsh7th/nvim-cmp";
+        dependencies.lua = [
+          # {{{ Completion sources
+          "hrsh7th/cmp-nvim-lsp"
+          "hrsh7th/cmp-buffer"
+          "hrsh7th/cmp-emoji"
+          "hrsh7th/cmp-cmdline"
+          "hrsh7th/cmp-path"
+          "saadparwaiz1/cmp_luasnip"
+          "dmitmel/cmp-digraphs"
+          # }}}
+          "onsails/lspkind.nvim" # show icons in lsp completion menus
+          self.lazy.luasnip.package
+        ];
+
+        cond = nlib.blacklist "vscode";
+        event = [ "InsertEnter" "CmdlineEnter" ];
+        config = nlib.import ./plugins/cmp.lua "config";
+      };
+      # }}}
+      # }}}
+      # {{{ language support 
+      # {{{ haskell support
+      haskell-tools = {
+        package = "mrcjkb/haskell-tools.nvim";
+        dependencies.lua = [ self.lazy.plenary.package ];
+        version = "^2";
+
+        cond = nlib.blacklist "vscode";
+        ft = [ "haskell" "lhaskell" "cabal" "cabalproject" ];
+
+        config.vim.g.haskell_tools = {
+          hls = {
+            on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach'';
+            settings.haskell = {
+              formattingProvider = "fourmolu";
+
+              # This seems to work better with custom preludes
+              # See this issue https://github.com/fourmolu/fourmolu/issues/357
+              plugin.fourmolu.config.external = true;
+            };
+          };
+
+          # I think this wasn't showing certain docs as I expected (?)
+          tools.hover.enable = false;
+        };
+      };
+      # }}}
+      # {{{ rust support
+      # {{{ rust-tools 
+      rust-tools = {
+        package = "simrat39/rust-tools.nvim";
+        dependencies.nix = [ pkgs.rust-analyzer pkgs.rustfmt ];
+
+        cond = nlib.blacklist "vscode";
+        ft = "rust";
+
+        opts.server.on_attach = nlib.customLanguageServerOnAttach {
+          keys = {
+            mapping = "<leader>lc";
+            action = "<cmd>RustOpenCargo<cr>";
+            desc = "Open [c]argo.toml";
+          };
+        };
+      };
+      # }}}
+      # {{{ crates 
+      crates = {
+        package = "saecki/crates.nvim";
+        dependencies.lua = [ self.lazy.plenary.package ];
+
+        cond = nlib.blacklist "vscode";
+        event = "BufReadPost Cargo.toml";
+
+        # {{{ Set up null_ls source
+        opts.null_ls = {
+          enabled = true;
+          name = "crates";
+        };
+        # }}}
+
+        config.autocmds = [
+          # {{{ Load cmp source on insert 
+          {
+            event = "InsertEnter";
+            group = "CargoCmpSource";
+            pattern = "Cargo.toml";
+            action = nlib.thunk /* lua */ ''
+              require("cmp").setup.buffer({ sources = { { name = "crates" } } })
+            '';
+          }
+          # }}}
+          # {{{ Load keybinds on attach
+          {
+            event = "BufReadPost";
+            group = "CargoKeybinds";
+            pattern = "Cargo.toml";
+            # # {{{ Register which-key info
+            # action.callback = nlib.contextThunk /* lua */ ''
+            #  require("which-key").register({
+            #    ["<leader>lc"] = {
+            #      name = "[l]ocal [c]rates",
+            #      bufnr = context.bufnr
+            #    },
+            #  })
+            # '';
+            # }}}
+
+            action.keys = _:
+              let
+                # {{{ Keymap helpers 
+                keymap = mapping: action: desc: {
+                  inherit mapping desc;
+                  action = nlib.lua /* lua */ ''require("crates").${action}'';
+                };
+
+                keyroot = "<leader>lc";
+                # }}}
+              in
+              # {{{ Keybinds
+              [
+                (keymap "${keyroot}t" "toggle" "[c]rates [t]oggle")
+                (keymap "${keyroot}r" "reload" "[c]rates [r]efresh")
+
+                (keymap "${keyroot}H" "open_homepage" "[c]rate [H]omephage")
+                (keymap "${keyroot}R" "open_repository" "[c]rate [R]epository")
+                (keymap "${keyroot}D" "open_documentation" "[c]rate [D]ocumentation")
+                (keymap "${keyroot}C" "open_crates_io" "[c]rate [C]rates.io")
+
+                (keymap "${keyroot}v" "show_versions_popup" "[c]rate [v]ersions")
+                (keymap "${keyroot}f" "show_features_popup" "[c]rate [f]eatures")
+                (keymap "${keyroot}d" "show_dependencies_popup" "[c]rate [d]eps")
+                (keymap "K" "show_popup" "[c]rate popup")
+              ];
+            # }}}
+          }
+          # }}}
+        ];
+      };
+      # }}}
+      # }}}
+      # {{{ lean support
+      lean = {
+        package = "Julian/lean.nvim";
+        name = "lean";
+        dependencies.lua = [
+          self.lazy.plenary.package
+          "neovim/nvim-lspconfig"
+        ];
+
+        cond = nlib.blacklist "vscode";
+        ft = "lean";
+
+        opts = {
+          abbreviations = {
+            builtin = true;
+            cmp = true;
+          };
+
+          lsp = {
+            on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach'';
+            capabilites = nlib.lua /* lua */ ''require("my.plugins.lspconfig").capabilities'';
+          };
+
+          lsp3 = false; # We don't want the lean 3 language server!
+          mappings = true;
+        };
+      };
+      # }}}
+      # {{{ idris support
+      idris = {
+        package = "ShinKage/idris2-nvim";
+        name = "idris";
+        dependencies.lua = [
+          self.lazy.nui.package
+          "neovim/nvim-lspconfig"
+        ];
+
+        cond = nlib.blacklist "vscode";
+        ft = [ "idris2" "lidris2" "ipkg" ];
+
+        opts = {
+          client.hover.use_split = true;
+          serve.on_attach = nlib.customLanguageServerOnAttach {
+            # {{{ Keymaps
+            keys =
+              let keymap = mapping: action: desc: {
+                inherit desc;
+                mapping = "<leader>i${mapping}";
+                action = nlib.lua /* lua */ ''require("idris2.code_action").${action}'';
+              };
+              in
+              [
+                (keymap "C" "make_case" "Make [c]ase")
+                (keymap "L" "make_lemma" "Make [l]emma")
+                (keymap "c" "add_clause" "Add [c]lause")
+                (keymap "e" "expr_search" "[E]xpression search")
+                (keymap "d" "generate_def" "Generate [d]efinition")
+                (keymap "s" "case_split" "Case [s]plit")
+                (keymap "h" "refine_hole" "Refine [h]ole")
+              ];
+            # }}}
+          };
+        };
+      };
+      # }}}
+      # {{{ github actions
+      github-actions = {
+        package = "yasuhiroki/github-actions-yaml.vim";
+
+        cond = nlib.blacklist "vscode";
+        ft = [ "yml" "yaml" ];
+      };
+      # }}}
+      # {{{ typst support
+      typst = {
+        package = "kaarmu/typst.vim";
+        dependencies.nix = [ pkgs.typst-lsp pkgs.typst-fmt ];
+
+        cond = nlib.blacklist "vscode";
+        ft = "typst";
+      };
+      # }}}
+      # {{{ hyprland
+      hyprland = {
+        package = "theRealCarneiro/hyprland-vim-syntax";
+
+        cond = nlib.blacklist "vscode";
+        ft = "hypr";
+
+        config.autocmds = {
+          event = "BufRead";
+          group = "DetectHyprlandConfig";
+          pattern = "hyprland.conf";
+          action.vim.opt.ft = "hypr";
+        };
+      };
+      # }}}
+      # }}}
+      # {{{ external
+      # These plugins integrate neovim with external services
+      # {{{ wakatime
+      wakatime = {
+        package = "wakatime/vim-wakatime";
+        dependencies.nix = [ pkgs.wakatime ];
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        event = "BufReadPost";
+      };
+      # }}}
+      # {{{ discord rich presence 
+      discord-rich-presence = {
+        package = "andweeb/presence.nvim";
+        main = "presence";
+
+        cond = nlib.blacklist [ "vscode" "firenvim" ];
+        event = "BufReadPost";
+        config = true;
+      };
+      # }}}
+      # {{{ gitlinker 
+      # generate permalinks for code
+      gitlinker =
+        let mapping = "<leader>yg";
+        in
+        {
+          package = "ruifm/gitlinker.nvim";
+          dependencies.lua = [ self.lazy.plenary.package ];
+
+          cond = nlib.blacklist [ "vscode" "firenvim" ];
+          opts.mappings = mapping;
+          keys = mapping;
+        };
+      # }}}
+      # {{{ paperplanes
+      # export to pastebin like services
+      paperlanes = {
+        package = "rktjmp/paperplanes.nvim";
+        cmd = "PP";
+        opts.provider = "paste.rs";
+      };
+      # }}}
+      # {{{ obsidian
+      obsidian =
+        let vault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
+        in
+        {
+          package = "epwalsh/obsidian.nvim";
+          dependencies.lua = [ self.lazy.plenary.package ];
+
+          cond = [
+            (nlib.blacklist [ "vscode" "firenvim" ])
+            (nlib.lua /* lua */ "vim.loop.cwd() == ${nlib.encode vault}")
+          ];
+          event = "VeryLazy";
+
+          keys.mapping = "<C-O>";
+          keys.action = "<cmd>ObsidianQuickSwitch<cr>";
+
+          opts = {
+            dir = vault;
+            notes_subdir = "chaos";
+            daily_notes = {
+              folder = "daily";
+              date_format = "%Y-%m-%d";
+            };
+
+            completion = {
+              nvim_cmp = true;
+              min_chars = 2;
+              new_notes_location = "current_dir";
+              prepend_note_id = true;
+            };
+
+            mappings = { };
+            disable_frontmatter = true;
+          };
+        };
+      # }}}
+      # }}}
+    };
+    # }}}
+  }));
+
   # {{{ extraPackages
   extraPackages = with pkgs; [
     # Language servers
@@ -33,13 +1295,15 @@ let
     # Latex setup
     # texlive.combined.scheme-full # Latex stuff
     # python38Packages.pygments # required for latex syntax highlighting
-  ] ++ config.satellite.neovim.generated.dependencies;
+  ] ++ generated.dependencies;
   # }}}
   # {{{ extraRuntime
-  extraRuntimePaths = [
-    # Experimental nix module generation
-    config.satellite.neovim.generated.lazySingleFile
-  ];
+  # Experimental nix module generation
+  generatedConfig = (config.satellite.lib.lua.writeFile
+    "lua/nix" "init"
+    generated.lua);
+
+  extraRuntimePaths = [ generatedConfig ];
 
   extraRuntimeJoinedPaths = pkgs.symlinkJoin {
     name = "nixified-neovim-lua-modules";
@@ -103,20 +1367,17 @@ let
     extraArgs = "--set GIT_DISCOVERY_ACROSS_FILESYSTEM 1";
   };
   # }}}
-
-  nlib = config.satellite.neovim.lib;
-  lazy = config.satellite.neovim.lazy;
 in
 {
+  satellite.lua.styluaConfig = ../../../stylua.toml;
+
   # {{{ Basic config
   # We still want other modules to know that we are using neovim!
   satellite.toggles.neovim.enable = true;
 
   xdg.configFile.nvim.source = config.satellite.dev.path "home/features/neovim/config";
-  home.sessionVariables = {
-    EDITOR = "nvim";
-    NVIM_GENERATED_RUNTIME = extraRuntimeJoinedPaths;
-  };
+  home.sessionVariables.EDITOR = "nvim";
+  home.file.".nvim_nix_runtime".source = generatedConfig;
 
   home.packages = [
     neovim
@@ -171,1074 +1432,6 @@ in
         };
     };
   # }}}
-  # {{{ Plugins
-  satellite.lua.styluaConfig = ../../../stylua.toml;
-  satellite.neovim.runtime = {
-    languageServerOnAttach = "my.plugins.lspconfig";
-    tempest = "my.tempest";
-  };
-
-  # {{{ libraries
-  # {{{ plenary
-  satellite.neovim.lazy.plenary = {
-    package = "nvim-lua/plenary.nvim";
-    # Autoload when running tests
-    cmd = [ "PlenaryBustedDirectory" "PlenaryBustedFile" ];
-  };
-  # }}}
-  # {{{ nui
-  satellite.neovim.lazy.nui.package = "MunifTanjim/nui.nvim";
-  # }}}
-  # {{{ web-devicons
-  satellite.neovim.lazy.web-devicons.package = "nvim-tree/nvim-web-devicons";
-  # }}}
-  # {{{ Scrap
-  satellite.neovim.lazy.scrap.package = "mateiadrielrafael/scrap.nvim";
-  # }}}
-  # }}}
-  # {{{ ui
-  # {{{ nvim-tree 
-  satellite.neovim.lazy.nvim-tree = {
-    package = "kyazdani42/nvim-tree.lua";
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    setup = true;
-
-    keys.mapping = "<C-n>";
-    keys.desc = "Toggle [n]vim-tree";
-    keys.action = "<cmd>NvimTreeToggle<cr>";
-  };
-  # }}}
-  # {{{ mini.statusline
-  satellite.neovim.lazy.mini-statusline = {
-    package = "echasnovski/mini.statusline";
-    name = "mini.statusline";
-    dependencies.lua = [ lazy.web-devicons.package ];
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    lazy = false;
-
-    opts.content.inactive = nlib.thunk /* lua */ ''
-      require("mini.statusline").combine_groups({
-        { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } },
-      })
-    '';
-
-    opts.content.active = nlib.thunk /* lua */ ''
-      local st = require("mini.statusline");
-      local mode, mode_hl = st.section_mode({ trunc_width = 120 })
-      local git = st.section_git({ trunc_width = 75 })
-      local diagnostics = st.section_diagnostics({ trunc_width = 75 })
-
-      return st.combine_groups({
-        { hl = mode_hl, strings = { mode } },
-        { hl = "MiniStatuslineDevinfo", strings = { git } },
-        { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } },
-        "%=", -- End left alignment
-        { hl = "MiniStatuslineFilename", strings = { diagnostics } },
-        { hl = "MiniStatuslineDevinfo", strings = { vim.bo.filetype } },
-      })
-    '';
-  };
-  # }}}
-  # {{{ mini.files
-  satellite.neovim.lazy.mini-files = {
-    package = "echasnovski/mini.files";
-    name = "mini.files";
-    dependencies.lua = [ lazy.web-devicons.package ];
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    keys = {
-      mapping = "<c-s-f>";
-      desc = "[S]earch [F]iles";
-      action = nlib.thunk /* lua */ ''
-        local files = require("mini.files")
-        if not files.close() then
-          files.open(vim.api.nvim_buf_get_name(0))
-          files.reveal_cwd()
-        end
-      '';
-    };
-
-    opts.windows.preview = false;
-    opts.mappings.go_in_plus = "l";
-  };
-  # }}}
-  # {{{ winbar
-  satellite.neovim.lazy.winbar = {
-    package = "fgheng/winbar.nvim";
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    event = "BufReadPost";
-
-    opts.enabled = true;
-    # TODO: blacklist harpoon, NeogitStatus
-  };
-  # }}}
-  # {{{ harpoon
-  satellite.neovim.lazy.harpoon = {
-    package = "ThePrimeagen/harpoon";
-    keys =
-      let goto = key: index: {
-        desc = "Goto harpoon file ${toString index}";
-        mapping = "<c-s>${key}";
-        action = nlib.thunk
-          /* lua */ ''require("harpoon.ui").nav_file(${toString index})'';
-      };
-      in
-      [
-        {
-          desc = "Add file to [h]arpoon";
-          mapping = "<leader>H";
-          action = nlib.thunk
-            /* lua */ ''require("harpoon.mark").add_file()'';
-        }
-        {
-          desc = "Toggle harpoon quickmenu";
-          mapping = "<c-a>";
-          action = nlib.thunk
-            /* lua */ ''require("harpoon.ui").toggle_quick_menu()'';
-        }
-        (goto "q" 1)
-        (goto "w" 2)
-        (goto "e" 3)
-        (goto "r" 4)
-        (goto "a" 5)
-        (goto "s" 6)
-        (goto "d" 7)
-        (goto "f" 8)
-        (goto "z" 9)
-      ];
-  };
-  # }}}
-  # {{{ neogit
-  satellite.neovim.lazy.neogit = {
-    package = "TimUntersberger/neogit";
-    dependencies.lua = [ lazy.plenary.package ];
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    cmd = "Neogit"; # We sometimes spawn this directly from fish using a keybind
-    keys = {
-      mapping = "<c-g>";
-      action = "<cmd>Neogit<cr>";
-      desc = "Open neo[g]it";
-    };
-
-    opts = true; # Here so the tempest runtime will call .setup
-    setup.autocmds = {
-      event = "FileType";
-      pattern = "NeogitStatus";
-      group = "NeogitStatusDisableFolds";
-      action.vim.opt.foldenable = false;
-    };
-  };
-  # }}}
-  # {{{ telescope
-  satellite.neovim.lazy.telescope = {
-    package = "nvim-telescope/telescope.nvim";
-    version = "0.1.x";
-    env.blacklist = "vscode";
-
-    # {{{ Dependencies
-    dependencies = {
-      nix = [ pkgs.ripgrep ];
-      lua = [
-        lazy.plenary.package
-        {
-          # We want a prebuilt version of this plugin
-          dir = pkgs.vimPlugins.telescope-fzf-native-nvim;
-          name = "telescope-fzf-native";
-        }
-      ];
-    };
-    # }}}
-    # {{{ Keymaps
-    keys =
-      let
-        keymap = mapping: action: desc: {
-          inherit mapping desc;
-          action = "<cmd>Telescope ${action} theme=ivy<cr>";
-        };
-
-        findFilesByExtension = mapping: extension: tag:
-          keymap
-            "<leader>f${mapping}"
-            "find_files find_command=rg,--files,--glob=**/*.${extension}"
-            "Find ${tag} files";
-      in
-      [
-        (keymap "<c-p>" "find_files" "File finder [p]alette")
-        (keymap "<leader>d" "diagnostics" "[D]iagnostics")
-        (keymap "<c-f>" "live_grep" "[F]ind in project")
-        (keymap "<leader>t" "builtin" "[T]elescope pickers")
-        # {{{ Files by extension 
-        (findFilesByExtension "tx" "tex" "[t]ex")
-        (findFilesByExtension "ts" "ts" "[t]ypescript")
-        (findFilesByExtension "ty" "typ" "[t]ypst")
-        (findFilesByExtension "l" "lua" "[l]ua")
-        (findFilesByExtension "n" "nix" "[n]ua")
-        (findFilesByExtension "p" "purs" "[p]urescript")
-        (findFilesByExtension "h" "hs" "[h]askell")
-        (findFilesByExtension "e" "elm" "[e]lm")
-        (findFilesByExtension "r" "rs" "[r]ust")
-        # }}}
-      ];
-    # }}}
-    # {{{ Disable folds in telescope windows
-    setup.autocmds = {
-      event = "FileType";
-      pattern = "TelescopeResults";
-      group = "TelescopeResultsDisableFolds";
-      action.vim.opt.foldenable = false;
-    };
-    # }}}
-    # {{{ Load fzf extension
-    setup.callback = nlib.thunkString /* lua */ ''
-      require("telescope").load_extension("fzf")
-    '';
-    # }}}
-    # {{{ Options
-    opts.defaults.mappings.i."<C-h>" = "which_key";
-    opts.pickers.find_files.hidden = true;
-    opts.extensions.fzf = {
-      fuzzy = true;
-      override_generic_sorter = true;
-      override_file_sorter = true;
-    };
-    # }}}
-  };
-  # }}}
-  # }}}
-  # {{{ visual
-  # The line between `ui` and `visual` is a bit rought. I currenlty mostly judge
-  # it by vibe.
-  # {{{ indent-blankline 
-  satellite.neovim.lazy.indent-blankline = {
-    package = "lukas-reineke/indent-blankline.nvim";
-    main = "ibl";
-    setup = true;
-
-    env.blacklist = "vscode";
-    event = "BufReadPost";
-  };
-  # }}}
-  # {{{ live-command
-  # Live command preview for commands like :norm
-  satellite.neovim.lazy.live-command = {
-    package = "smjonas/live-command.nvim";
-    version = "remote"; # https://github.com/smjonas/live-command.nvim/pull/29
-    main = "live-command";
-
-    event = "CmdlineEnter";
-    opts.commands.Norm.cmd = "norm";
-    opts.commands.G.cmd = "g";
-
-    keys = {
-      mode = "v";
-      mapping = "N";
-      action = ":Norm ";
-      desc = "Map lines in [n]ormal mode";
-    };
-  };
-  # }}}
-  # {{{ fidget
-  satellite.neovim.lazy.fidget = {
-    package = "j-hui/fidget.nvim";
-    tag = "legacy";
-
-    env.blacklist = "vscode";
-    event = "BufReadPre";
-    setup = true;
-  };
-  # }}}
-  # {{{ treesitter
-  satellite.neovim.lazy.treesitter = {
-    # REASON: more grammars
-    dir = upkgs.vimPlugins.nvim-treesitter.withAllGrammars;
-    dependencies.lua = [ "nvim-treesitter/nvim-treesitter-textobjects" ];
-    dependencies.nix = [ pkgs.tree-sitter ];
-
-    env.blacklist = "vscode";
-    event = "BufReadPost";
-
-    #{{{ Highlighting
-    opts.highlight = {
-      enable = true;
-      disable = [ "kotlin" ]; # This one seemed a bit broken
-      additional_vim_regex_highlighting = false;
-    };
-    #}}}
-    # {{{ Textobjects
-    opts.textobjects = {
-      #{{{ Select
-      select = {
-        enable = true;
-        lookahead = true;
-        keymaps = {
-          # You can use the capture groups defined in textobjects.scm
-          af = "@function.outer";
-          "if" = "@function.inner";
-          ac = "@class.outer";
-          ic = "@class.inner";
-        };
-      };
-      #}}}
-      #{{{ Move
-      move = {
-        enable = true;
-        set_jumps = true; # whether to set jumps in the jumplist
-        goto_next_start = {
-          "]f" = "@function.outer";
-          "]t" = "@class.outer";
-        };
-        goto_next_end = {
-          "]F" = "@function.outer";
-          "]T" = "@class.outer";
-        };
-        goto_previous_start = {
-          "[f" = "@function.outer";
-          "[t" = "@class.outer";
-        };
-        goto_previous_end = {
-          "[F" = "@function.outer";
-          "[T" = "@class.outer";
-        };
-      };
-      #}}}
-    };
-    # }}}
-    opts.indent.enable = true;
-  };
-  # }}}
-  # {{{ treesitter context
-  # Show context at the of closing delimiters
-  satellite.neovim.lazy.treesitter-virtual-context = {
-    package = "haringsrob/nvim_context_vt";
-    dependencies.lua = [ lazy.treesitter.name ];
-
-    env.blacklist = "vscode";
-    event = "BufReadPost";
-  };
-
-  # show context at top of file
-  satellite.neovim.lazy.treesitter-top-context = {
-    package = "nvim-treesitter/nvim-treesitter-context";
-    dependencies.lua = [ lazy.treesitter.name ];
-
-    env.blacklist = "vscode";
-    event = "BufReadPost";
-    opts.enable = true;
-  };
-  # }}}
-  # }}}
-  # {{{ editing {{{ text navigation
-  # {{{ flash
-  satellite.neovim.lazy.flash = {
-    package = "folke/flash.nvim";
-
-    env.blacklist = "vscode";
-    keys =
-      let keybind = mode: mapping: action: desc: {
-        inherit mapping desc mode;
-        action = nlib.thunk /* lua */ ''require("flash").${action}()'';
-      };
-      in
-      [
-        (keybind "nxo" "s" "jump" "Flash")
-        (keybind "nxo" "S" "treesitter" "Flash Treesitter")
-        (keybind "o" "r" "remote" "Remote Flash")
-        (keybind "ox" "R" "treesitter_search" "Treesitter Search")
-        (keybind "c" "<C-S>" "toggle" "Toggle Flash Search")
-      ];
-
-    # Disable stuff like f/t/F/T
-    opts.modes.char.enabled = false;
-  };
-  # }}}
-  # {{{ ftft (quickscope but written in lua)
-  satellite.neovim.lazy.ftft = {
-    package = "gukz/ftFT.nvim";
-
-    env.blacklist = "vscode";
-    keys = [ "f" "F" "t" "T" ];
-    setup = true;
-  };
-  # }}}
-  # }}}
-  # {{{ clipboard-image
-  satellite.neovim.lazy.clipboard-image = {
-    package = "postfen/clipboard-image.nvim";
-
-    env.blacklist = "firenvim";
-    cmd = "PasteImg";
-
-    keys = {
-      mapping = "<leader>p";
-      action = "<cmd>PasteImg<cr>";
-      desc = "[P]aste image from clipboard";
-    };
-
-    opts.default.img_name = nlib.import ./plugins/clipboard-image.lua "img_name";
-    opts.tex = {
-      img_dir = [ "%:p:h" "img" ];
-      affix = "\\includegraphics[width=\\textwidth]{%s}";
-    };
-    opts.typst = {
-      img_dir = [ "%:p:h" "img" ];
-      affix = ''#image("%s", width: 100)'';
-    };
-  };
-  # }}}
-  # {{{ lastplace 
-  satellite.neovim.lazy.lastplace = {
-    package = "ethanholz/nvim-lastplace";
-
-    env.blacklist = "vscode";
-    event = "BufReadPre";
-
-    opts.lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ];
-  };
-  # }}}
-  # {{{ undotree
-  satellite.neovim.lazy.undotree = {
-    package = "mbbill/undotree";
-
-    env.blacklist = "vscode";
-    cmd = "UndotreeToggle";
-    keys = {
-      mapping = "<leader>u";
-      action = "<cmd>UndoTreeToggle<cr>";
-      desc = "[U]ndo tree";
-    };
-  };
-  # }}}
-  # {{{ ssr (structured search & replace)
-  satellite.neovim.lazy.ssr = {
-    package = "cshuaimin/ssr.nvim";
-
-    env.blacklist = "vscode";
-    keys = {
-      mode = "nx";
-      mapping = "<leader>rt";
-      action = nlib.thunk /* lua */ ''require("ssr").open()'';
-      desc = "[r]eplace [t]emplate";
-    };
-
-    opts.keymaps.replace_all = "<s-cr>";
-  };
-  # }}}
-  # {{{ edit-code-block (edit injections in separate buffers)
-  satellite.neovim.lazy.edit-code-block = {
-    package = "dawsers/edit-code-block.nvim";
-    dependencies.lua = [ lazy.treesitter.name ];
-    main = "ecb";
-
-    env.blacklist = "vscode";
-    setup = true;
-    keys = {
-      mapping = "<leader>e";
-      action = "<cmd>EditCodeBlock<cr>";
-      desc = "[e]dit injection";
-    };
-  };
-  # }}}
-  # {{{ mini.comment 
-  satellite.neovim.lazy.mini-comment = {
-    package = "echasnovski/mini.comment";
-    name = "mini.comment";
-
-    setup = true;
-    keys = [
-      { mapping = "gc"; mode = "nxv"; }
-      "gcc"
-    ];
-  };
-  # }}}
-  # {{{ mini.surround
-  satellite.neovim.lazy.mini-surround = {
-    package = "echasnovski/mini.surround";
-    name = "mini.surround";
-
-    keys = lib.flatten [
-      # ^ doing the whole `flatten` thing to lie to my formatter
-      { mapping = "<tab>s"; mode = "nv"; }
-      [ "<tab>d" "<tab>f" "<tab>F" "<tab>h" "<tab>r" ]
-    ];
-
-    # {{{ Keymaps
-    opts.mappings = {
-      add = "<tab>s"; # Add surrounding in Normal and Visul modes
-      delete = "<tab>d"; # Delete surrounding
-      find = "<tab>f"; # Find surrounding (to the right)
-      find_left = "<tab>F"; # Find surrounding (to the left)
-      highlight = "<tab>h"; # Highlight surrounding
-      replace = "<tab>r"; # Replace surrounding
-      update_n_lines = ""; # Update `n_lines`
-    };
-    # }}}
-    # {{{ Custom surroundings
-    opts.custom_surroundings =
-      let mk = balanced: input: left: right: {
-        input = [
-          input
-          (if balanced
-          then "^.%s*().-()%s*.$"
-          else "^.().*().$")
-        ];
-        output = { inherit left right; };
-      };
-      in
-      {
-        b = mk true "%b()" "(" ")";
-        B = mk true "%b{}" "{" "}";
-        r = mk true "%b[]" "[" "]";
-        q = mk false "\".-\"" "\"" "\"";
-        a = mk false "'.-'" "'" "'";
-      };
-    # }}}
-  };
-  # }}}
-  # {{{ mini.operators
-  satellite.neovim.lazy.mini-operators = {
-    package = "echasnovski/mini.operators";
-    name = "mini.operators";
-
-    setup = true;
-    keys =
-      let operator = key: [
-        { mapping = "g${key}"; mode = "nv"; }
-        "g${key}${key}"
-      ];
-      in
-      lib.flatten [
-        (operator "=")
-        (operator "x")
-        (operator "r")
-        (operator "s")
-      ];
-  };
-  # }}}
-  # {{{ luasnip
-  # snippeting engine
-  satellite.neovim.lazy.luasnip =
-    let reload = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()'';
-    in
-    {
-      package = "L3MON4D3/LuaSnip";
-      version = "v2";
-
-      env.blacklist = "vscode";
-      setup.callback = nlib.thunk reload;
-
-      # {{{ Keybinds
-      keys = [
-        {
-          mapping = "<leader>rs";
-          action = nlib.thunk reload;
-          desc = "[R]eload [s]nippets";
-        }
-        {
-          mode = "i";
-          expr = true;
-          mapping = "<tab>";
-          action = nlib.thunk /* lua */ ''
-            local luasnip = require("luasnip")
-
-            if not luasnip.jumpable(1) then
-              return "<tab>"
-            end
-
-            vim.schedule(function()
-              luasnip.jump(1)
-            end)
-
-            return "<ignore>"
-          '';
-          desc = "Jump to next snippet tabstop";
-        }
-        {
-          mode = "i";
-          mapping = "<s-tab>";
-          action = nlib.thunk /* lua */ ''
-            require("luasnip").jump(-1)
-          '';
-          desc = "Jump to previous snippet tabstop";
-        }
-      ];
-      # }}}
-    };
-  # }}}
-  # }}}
-  # {{{ ide
-  # {{{ conform
-  satellite.neovim.lazy.conform = {
-    package = "stevearc/conform.nvim";
-
-    env.blacklist = "vscode";
-    event = "BufReadPost";
-
-    opts.format_on_save.lsp_fallback = true;
-    opts.formatters_by_ft = let prettier = [ [ "prettierd" "prettier" ] ]; in
-      {
-        lua = [ "stylua" ];
-        python = [ "ruff_format" ];
-
-        javascript = prettier;
-        typescript = prettier;
-        javascriptreact = prettier;
-        typescriptreact = prettier;
-        html = prettier;
-        css = prettier;
-        markdown = prettier;
-      };
-  };
-  # }}}
-  # {{{ neoconf
-  satellite.neovim.lazy.neoconf = {
-    package = "folke/neoconf.nvim";
-
-    cmd = "Neoconf";
-
-    opts.import = {
-      vscode = true; # local .vscode/settings.json
-      coc = false; # global/local coc-settings.json
-      nlsp = false; # global/local nlsp-settings.nvim json settings
-    };
-  };
-  # }}}
-  # {{{ null-ls
-  satellite.neovim.lazy.null-ls = {
-    package = "jose-elias-alvarez/null-ls.nvim";
-    dependencies.lua = [ "neovim/nvim-lspconfig" ];
-
-    env.blacklist = "vscode";
-    event = "BufReadPre";
-
-    opts = nlib.thunk /* lua */ ''
-      local p = require("null-ls")
-      return {
-        on_attach = require("my.plugins.lspconfig").on_attach, 
-        sources = {
-          p.builtins.diagnostics.ruff
-        }
-      }
-    '';
-  };
-  # }}}
-  # {{{ gitsigns
-  satellite.neovim.lazy.gitsigns = {
-    package = "lewis6991/gitsigns.nvim";
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    event = "BufReadPost";
-
-    opts.on_attach = nlib.tempest {
-      mkContext = /* lua */ ''function(bufnr) return { bufnr = bufnr } end'';
-      keys =
-        let
-          prefix = m: "<leader>h${m}";
-          gs = "package.loaded.gitsigns";
-
-          # {{{ nmap helper
-          nmap = mapping: action: desc: {
-            inherit desc;
-            mapping = prefix "mapping";
-            action = "${gs}.action";
-          };
-          # }}}
-          # {{{ exprmap helper
-          exprmap = mapping: action: desc: {
-            inherit mapping desc;
-            action = nlib.thunk /* lua */ ''
-              if vim.wo.diff then
-                return "${mapping}"
-              end
-
-              vim.schedule(function()
-                ${gs}.${action}()
-              end)
-
-              return "<ignore>"
-            '';
-            expr = true;
-          };
-          # }}}
-        in
-        [
-          # {{{ navigation
-          (exprmap "]c" "next_hunk" "Navigate to next hunk")
-          (exprmap "[c" "prev_hunk" "Navigate to previous hunk")
-          # }}}
-          # {{{ actions
-          (nmap "s" "stage_hunk" "[s]tage hunk")
-          (nmap "r" "reset_hunk" "[s]tage hunk")
-          (nmap "S" "stage_buffer" "[s]tage hunk")
-          (nmap "u" "undo_stage_hunk" "[s]tage hunk")
-          (nmap "R" "reset_buffer" "[s]tage hunk")
-          (nmap "p" "preview_hunk" "[s]tage hunk")
-          (nmap "d" "diffthis" "[s]tage hunk")
-          {
-            mapping = prefix "D";
-            action = nlib.thunk ''
-              ${gs}.diffthis("~")
-            '';
-            desc = "[d]iff file (?)";
-          }
-          {
-            mapping = prefix "b";
-            action = nlib.thunk ''
-              ${gs}.blame_line({ full = true })
-            '';
-            desc = "[b]lame line";
-          }
-          # }}}
-          # {{{ Toggles
-          (nmap "tb" "toggle_current_line_blame" "[t]oggle line [b]laming")
-          (nmap "td" "toggle_deleted" "[t]oggle [d]eleted")
-          # }}}
-          # {{{ visual mappings
-          {
-            mode = "v";
-            mapping = prefix "s";
-            action = nlib.thunk /* lua */ ''
-              ${gs}.stage_hunk({ vim.fn.line("."), vim.fn.line("v") })
-            '';
-            desc = "stage visual hunk";
-          }
-          {
-            mode = "v";
-            mapping = prefix "r";
-            action = nlib.thunk /* lua */ ''
-              ${gs}.reset_hunk({ vim.fn.line("."), vim.fn.line("v") })
-            '';
-            desc = "reset visual hunk";
-          }
-          # }}}
-        ];
-    };
-  };
-  # }}}
-  # {{{ cmp
-  satellite.neovim.lazy.cmp = {
-    package = "hrsh7th/nvim-cmp";
-    dependencies.lua = [
-      # {{{ Completion sources
-      "hrsh7th/cmp-nvim-lsp"
-      "hrsh7th/cmp-buffer"
-      "hrsh7th/cmp-emoji"
-      "hrsh7th/cmp-cmdline"
-      "hrsh7th/cmp-path"
-      "saadparwaiz1/cmp_luasnip"
-      "dmitmel/cmp-digraphs"
-      # }}}
-      "onsails/lspkind.nvim" # show icons in lsp completion menus
-      lazy.luasnip.package
-    ];
-
-    env.blacklist = "vscode";
-    event = [ "InsertEnter" "CmdlineEnter" ];
-    setup = (nlib.import ./plugins/cmp.lua "config").value;
-  };
-  # }}}
-  # }}}
-  # {{{ language support 
-  # {{{ haskell support
-  satellite.neovim.lazy.haskell-tools = {
-    package = "mrcjkb/haskell-tools.nvim";
-    dependencies.lua = [ lazy.plenary.package ];
-    version = "^2";
-
-    env.blacklist = "vscode";
-    ft = [ "haskell" "lhaskell" "cabal" "cabalproject" ];
-
-    setup.vim.g.haskell_tools = {
-      hls = {
-        on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach'';
-        settings.haskell = {
-          formattingProvider = "fourmolu";
-
-          # This seems to work better with custom preludes
-          # See this issue https://github.com/fourmolu/fourmolu/issues/357
-          plugin.fourmolu.config.external = true;
-        };
-      };
-
-      # I think this wasn't showing certain docs as I expected (?)
-      tools.hover.enable = false;
-    };
-  };
-  # }}}
-  # {{{ rust support
-  # {{{ rust-tools 
-  satellite.neovim.lazy.rust-tools = {
-    package = "simrat39/rust-tools.nvim";
-    dependencies.nix = [ pkgs.rust-analyzer pkgs.rustfmt ];
-
-    env.blacklist = "vscode";
-    ft = "rust";
-
-    opts.server.on_attach = nlib.languageServerOnAttach {
-      keys = {
-        mapping = "<leader>lc";
-        action = "<cmd>RustOpenCargo<cr>";
-        desc = "Open [c]argo.toml";
-      };
-    };
-  };
-  # }}}
-  # {{{ crates 
-  satellite.neovim.lazy.crates = {
-    package = "saecki/crates.nvim";
-    dependencies.lua = [ lazy.plenary.package ];
-
-    env.blacklist = "vscode";
-    event = "BufReadPost Cargo.toml";
-
-    # {{{ Set up null_ls source
-    opts.null_ls = {
-      enabled = true;
-      name = "crates";
-    };
-    # }}}
-
-    setup.autocmds = [
-      # {{{ Load cmp source on insert 
-      {
-        event = "InsertEnter";
-        group = "CargoCmpSource";
-        pattern = "Cargo.toml";
-        action = nlib.thunkString /* lua */ ''
-          require("cmp").setup.buffer({ sources = { { name = "crates" } } })
-        '';
-      }
-      # }}}
-      # {{{ Load keybinds on attach
-      {
-        event = "BufReadPost";
-        group = "CargoKeybinds";
-        pattern = "Cargo.toml";
-        # # {{{ Register which-key info
-        # action.callback = nlib.contextThunk /* lua */ ''
-        #  require("which-key").register({
-        #    ["<leader>lc"] = {
-        #      name = "[l]ocal [c]rates",
-        #      bufnr = context.bufnr
-        #    },
-        #  })
-        # '';
-        # }}}
-
-        action.keys =
-          let
-            # {{{ Keymap helpers 
-            keymap = mapping: action: desc: {
-              inherit mapping desc;
-              action = nlib.lua /* lua */ ''require("crates").${action}'';
-            };
-
-            keyroot = "<leader>lc";
-            # }}}
-          in
-          # {{{ Keybinds
-          [
-            (keymap "${keyroot}t" "toggle" "[c]rates [t]oggle")
-            (keymap "${keyroot}r" "reload" "[c]rates [r]efresh")
-
-            (keymap "${keyroot}H" "open_homepage" "[c]rate [H]omephage")
-            (keymap "${keyroot}R" "open_repository" "[c]rate [R]epository")
-            (keymap "${keyroot}D" "open_documentation" "[c]rate [D]ocumentation")
-            (keymap "${keyroot}C" "open_crates_io" "[c]rate [C]rates.io")
-
-            (keymap "${keyroot}v" "show_versions_popup" "[c]rate [v]ersions")
-            (keymap "${keyroot}f" "show_features_popup" "[c]rate [f]eatures")
-            (keymap "${keyroot}d" "show_dependencies_popup" "[c]rate [d]eps")
-            (keymap "K" "show_popup" "[c]rate popup")
-          ];
-        # }}}
-      }
-      # }}}
-    ];
-  };
-  # }}}
-  # }}}
-  # {{{ lean support
-  satellite.neovim.lazy.lean = {
-    package = "Julian/lean.nvim";
-    name = "lean";
-    dependencies.lua = [
-      lazy.plenary.package
-      "neovim/nvim-lspconfig"
-    ];
-
-    env.blacklist = "vscode";
-    ft = "lean";
-
-    opts = {
-      abbreviations = {
-        builtin = true;
-        cmp = true;
-      };
-
-      lsp = {
-        on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach'';
-        capabilites = nlib.lua /* lua */ ''require("my.plugins.lspconfig").capabilities'';
-      };
-
-      lsp3 = false; # We don't want the lean 3 language server!
-      mappings = true;
-    };
-  };
-  # }}}
-  # {{{ idris support
-  satellite.neovim.lazy.idris = {
-    package = "ShinKage/idris2-nvim";
-    name = "idris";
-    dependencies.lua = [
-      lazy.nui.package
-      "neovim/nvim-lspconfig"
-    ];
-
-    env.blacklist = "vscode";
-    ft = [ "idris2" "lidris2" "ipkg" ];
-
-    opts = {
-      client.hover.use_split = true;
-      serve.on_attach = nlib.languageServerOnAttach {
-        # {{{ Keymaps
-        keys =
-          let keymap = mapping: action: desc: {
-            inherit desc;
-            mapping = "<leader>i${mapping}";
-            action = nlib.lua /* lua */ ''require("idris2.code_action").${action}'';
-          };
-          in
-          [
-            (keymap "C" "make_case" "Make [c]ase")
-            (keymap "L" "make_lemma" "Make [l]emma")
-            (keymap "c" "add_clause" "Add [c]lause")
-            (keymap "e" "expr_search" "[E]xpression search")
-            (keymap "d" "generate_def" "Generate [d]efinition")
-            (keymap "s" "case_split" "Case [s]plit")
-            (keymap "h" "refine_hole" "Refine [h]ole")
-          ];
-        # }}}
-      };
-    };
-  };
-  # }}}
-  # {{{ github actions
-  satellite.neovim.lazy.github-actions = {
-    package = "yasuhiroki/github-actions-yaml.vim";
-
-    env.blacklist = "vscode";
-    ft = [ "yml" "yaml" ];
-  };
-  # }}}
-  # {{{ typst support
-  satellite.neovim.lazy.typst = {
-    package = "kaarmu/typst.vim";
-    dependencies.nix = [ pkgs.typst-lsp pkgs.typst-fmt ];
-
-    env.blacklist = "vscode";
-    ft = "typst";
-  };
-  # }}}
-  # {{{ hyprland
-  satellite.neovim.lazy.hyprland = {
-    package = "theRealCarneiro/hyprland-vim-syntax";
-
-    env.blacklist = "vscode";
-    ft = "hypr";
-
-    setup.autocmds = {
-      event = "BufRead";
-      group = "DetectHyprlandConfig";
-      pattern = "hyprland.conf";
-      action.vim.opt.ft = "hypr";
-    };
-  };
-  # }}}
-  # }}}
-  # {{{ external
-  # These plugins integrate neovim with external services
-  # {{{ wakatime
-  satellite.neovim.lazy.wakatime = {
-    package = "wakatime/vim-wakatime";
-    dependencies.nix = [ pkgs.wakatime ];
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    event = "BufReadPost";
-  };
-  # }}}
-  # {{{ discord rich presence 
-  satellite.neovim.lazy.discord-rich-presence = {
-    package = "andweeb/presence.nvim";
-    main = "presence";
-
-    env.blacklist = [ "vscode" "firenvim" ];
-    event = "BufReadPost";
-    setup = true;
-  };
-  # }}}
-  # {{{ gitlinker 
-  # generate permalinks for code
-  satellite.neovim.lazy.gitlinker =
-    let mapping = "<leader>yg";
-    in
-    {
-      package = "ruifm/gitlinker.nvim";
-      dependencies.lua = [ lazy.plenary.package ];
-
-      env.blacklist = [ "vscode" "firenvim" ];
-      opts.mappings = mapping;
-      keys = mapping;
-    };
-  # }}}
-  # {{{ paperplanes
-  # export to pastebin like services
-  satellite.neovim.lazy.paperlanes = {
-    package = "rktjmp/paperplanes.nvim";
-    cmd = "PP";
-    opts.provider = "paste.rs";
-  };
-  # }}}
-  # {{{ obsidian
-  satellite.neovim.lazy.obsidian =
-    let vault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
-    in
-    {
-      package = "epwalsh/obsidian.nvim";
-      dependencies.lua = [ lazy.plenary.package ];
-
-      env.blacklist = [ "vscode" "firenvim" ];
-      cond = nlib.lua /* lua */ "vim.loop.cwd() == ${nlib.encode vault}";
-      event = "VeryLazy";
-
-      keys.mapping = "<C-O>";
-      keys.action = "<cmd>ObsidianQuickSwitch<cr>";
-
-      opts = {
-        dir = vault;
-        notes_subdir = "chaos";
-        daily_notes = {
-          folder = "daily";
-          date_format = "%Y-%m-%d";
-        };
-
-        completion = {
-          nvim_cmp = true;
-          min_chars = 2;
-          new_notes_location = "current_dir";
-          prepend_note_id = true;
-        };
-
-        mappings = { };
-        disable_frontmatter = true;
-      };
-    };
-  # }}}
-  # }}}
-  # }}}
   # {{{ Persistence
   satellite.persistence.at.state.apps.neovim.directories = [
     ".local/state/nvim"
diff --git a/modules/common/korora-lua.nix b/modules/common/korora-lua.nix
index 205a0a9..6cc4b65 100644
--- a/modules/common/korora-lua.nix
+++ b/modules/common/korora-lua.nix
@@ -2,52 +2,78 @@
 let
   k = korora;
 
-  # {{{ Lua encoders
   # {{{ Helpers 
   helpers = rec {
-    xor = a: b: (a || b) && (!a || !b);
-    implies = a: b: !a || b;
-    hasProp = obj: p: (obj.${p} or null) != null;
-    propXor = a: b: obj: xor (hasProp obj a) (hasProp obj b);
+    removeEmptyLines = str:
+      lib.pipe str [
+        (lib.splitString "\n")
+        (lib.lists.filter
+          (line: lib.any
+            (c: c != " ")
+            (lib.stringToCharacters line)))
+        (lib.concatStringsSep "\n")
+      ];
+
+    # {{{ Verification helpers 
+    toPretty = lib.generators.toPretty { indent = "    "; };
+    withError = cond: err: if cond then null else err;
+    hasProp = obj: p: obj ? ${p};
+    propExists = p: obj:
+      helpers.withError
+        (helpers.hasProp obj p)
+        "Expected property ${p}";
+    propXor = a: b: obj:
+      helpers.withError
+        ((hasProp obj a) != (hasProp obj b))
+        "Expected only one of the properties ${a} and ${b} in object ${toPretty obj}";
     propOnlyOne = props: obj:
-      1 == lib.count (prop: obj ? prop);
-    propImplies = a: b: obj: implies (hasProp obj a) (hasProp obj b);
+      helpers.withError
+        (1 == lib.count (hasProp obj) props)
+        "Expected exactly one property from the list ${toPretty props} in object ${toPretty obj}";
+    propImplies = a: b: obj:
+      helpers.withError
+        ((hasProp obj a) -> (hasProp obj b))
+        "Property ${a} should imply property ${b} in object ${toPretty obj}";
     mkVerify = checks: obj:
+      assert lib.all lib.isFunction checks;
       let
-        results = lib.lists.map checks obj;
+        results = lib.lists.map (c: c obj) checks;
         errors = lib.lists.filter (v: v != null) results;
       in
+      assert lib.all lib.isString errors;
       if errors == [ ]
       then null
       else
         let prettyErrors =
           lib.lists.map (s: "\n- ${s}") errors;
         in
-        "Multiple errors occured: ${prettyErrors}";
-
+        "Multiple errors occured: ${lib.concatStrings prettyErrors}";
+    # }}}
+    # {{{ Custom types
     intersection = l: r:
       k.typedef'
         "${l.name} ∧ ${r.name}"
         (helpers.mkVerify [ l r ]);
 
-    dependentAttrsOf =
-      name: mkType:
-      let
-        typeError = name: v: "Expected type '${name}' but value '${toPretty v}' is of type '${typeOf v}'";
-        addErrorContext = context: error: if error == null then null else "${context}: ${error}";
-
-        withErrorContext = addErrorContext "in ${name} value";
-      in
-      k.typedef' name
-        (v:
-        if ! lib.isAttrs v then
-          typeError name v
-        else
-          withErrorContext
-            (mkVerify
-              (lib.mapAttrsToList (k: _: mkType k) v)
-              v));
-
+    # dependentAttrsOf =
+    #   name: mkType:
+    #   let
+    #     typeError = name: v: "Expected type '${name}' but value '${toPretty v}' is of type '${typeOf v}'";
+    #     addErrorContext = context: error: if error == null then null else "${context}: ${error}";
+    #
+    #     withErrorContext = addErrorContext "in ${name} value";
+    #   in
+    #   k.typedef' name
+    #     (v:
+    #     if ! lib.isAttrs v then
+    #       typeError name v
+    #     else
+    #       withErrorContext
+    #         (mkVerify
+    #           (lib.mapAttrsToList (k: _: mkType k) v)
+    #           v));
+    # }}}
+    # {{{ Encoding helpers
     mkRawLuaObject = chunks:
       ''
         {
@@ -55,238 +81,83 @@ let
         }
       '';
 
+    encodeString = given: ''"${lib.escape ["\"" "\\"] (toString given)}"'';
+
     mkAttrName = s:
       let
         # These list *are* incomplete
-        forbiddenChars = lib.stringToCharacters "<>[]{}()'\".,;";
+        forbiddenChars = lib.stringToCharacters "<>[]{}()'\".,:;";
         keywords = [ "if" "then" "else" "do" "for" "local" "" ];
       in
       if lib.any (c: lib.hasInfix c s) forbiddenChars || lib.elem s keywords then
-        "[${m.string s}]"
+        "[${helpers.encodeString s}]"
       else s;
-
+    # }}}
   };
   # }}}
-
-  # We provide a custom set of helpers for generating lua code for nix.enable
-  #
-  # An encoder is a function from some nix value to a string containing lua code. 
-  # This object provides combinators for writing such encoders.
-  m = {
-    # {{{ General helpers 
-    typed = type: toLua: type // {
-      unsafeToLua = toLua;
-      toLua = v: toLua (type.check v);
-      override = a: m.typed (type.override a) toLua;
-    };
-    withDefault = type: default: type // {
-      default.value = default;
-    };
-    typedWithDefault = type: toLua: default:
-      m.withDefault (m.typed type toLua) default;
-    unsafe = type: type // { toLua = type.unsafeToLua; };
-    untyped = m.typed k.any;
-    untype = type: m.untyped type.toLua;
-    withName = name: type: type // { inherit name; }; # TODO: should we use override here?
-    # `const` is mostly useful together with `bind`. See the lua encoder for 
-    # lazy modules for example usage.
-    const = code: m.untyped (_: code);
-    # Conceptually, this is the monadic bind operation for encoders.
-    # This implementation is isomoprhic to that of the reader monad in haskell.
-    bind = name: higherOrder:
-      m.typed
-        (k.typedef' name (v: (higherOrder v).verify v))
-        (given: (higherOrder given).toLua given);
-    # This is probably the most useful combinnator defined in this entire object.
-    # Most of the combinators in the other categories are based on this.
-    conditional = predicate: caseTrue: caseFalse:
-      let base = m.bind
-        m.bind
-        "${caseTrue.name} ∨ ${caseFalse.name}"
-        (given: if predicate given then caseTrue else caseFalse);
+  # {{{ This function takes a nix value and encodes it to a lua string.
+  isLuaLiteral = given: lib.isAttrs given && given.__luaEncoderTag or null == "lua";
+  encodeWithDepth = depth: given:
+    let recurse = encodeWithDepth depth; in
+    if lib.isString given || lib.isDerivation given || lib.isPath given then
+      helpers.encodeString given
+    else if lib.isInt given || lib.isFloat given then
+      toString given
+    else if lib.isBool given then
+      if given then "true" else "false"
+    else if given == null then
+      "nil"
+    else if lib.isList given then
+      helpers.mkRawLuaObject (lib.lists.map recurse given)
+    else if lib.isAttrs given && given.__luaEncoderTag or null == "foldedList" then
+      let
+        makeFold = name: value: ''
+          -- {{{ ${name}
+          ${recurse value},
+          -- }}}'';
+        folds = lib.mapAttrsToList makeFold given.value;
       in
-      if caseTrue ? default then
-        m.withDefault base caseTrue.default
-      else if caseFalse ? default then
-        m.withDefault base caseFalse.default
-      else
-        base;
-    try = caseTrue: caseFalse:
-      let base = m.bind
-        "${caseTrue.name} ∨ ${caseFalse.name}"
-        (given: if caseTrue.verify given == null then m.unsafe caseTrue else caseFalse);
-      in
-      if caseTrue ? default then
-        m.withDefault base caseTrue.default
-      else if caseFalse ? default then
-        m.withDefault base caseFalse.default
-      else
-        base;
-    oneOf = lib.foldr m.try
-      (m.bottom (v: "No variants matched for value ${builtins.toJSON v}"));
-    # This is simply left-composition of functions
-    cmap = f: t:
-      m.typed
-        (lib.typedef' t.name (v: t.verify (f v)))
-        (given: t.toLua (f given));
-    # This is simply right-composition of functions
-    map = f: t: m.typed t (given: f (t.toLua given));
-    filter = predicate: type: given:
-      m.conditional predicate type (m.untype m.nil);
-    # This is mostly useful for debugging
-    trace = message: m.cmap (f: lib.traceSeq message (lib.traceVal f));
-    bottom = mkMessage: m.typed (m.typedef "⊥" mkMessage) lib.id;
-    # }}}
-    # {{{ Base types
-    string = m.typed k.string (given: ''"${lib.escape ["\"" "\\"] (toString given)}"'');
-    bool = m.typed k.bool (bool: if bool then "true" else "false");
-    integer = m.typed k.int toString;
-    float = m.typed k.float toString;
-    number = m.typed k.number toString;
-    ignored = type: m.typed type (_: "nil");
-    nil = m.typedWithDefault
-      (k.typedef "null" (v: v == null))
-      (_: "nil")
-      null;
-    stringOr = m.try m.string;
-    boolOr = m.try m.bool;
-    numberOr = m.try m.number;
-    nullOr = m.try m.nil;
-    anything = m.withName "⊤" (m.oneOf [
-      m.markedLuaCode # Lua code expressions have priority over attrsets
-      m.string
-      m.number
-      m.bool
-      m.null
-      (m.listOf m.anything)
-      (m.attrsetOf m.anything)
-    ]);
-    # }}}
-    # {{{ Lua code
-    identity = m.typed k.string lib.id;
-    markedLuaCode =
-      m.typed
-        (k.struct "marked lua code" {
-          value = k.string;
-          __luaEncoderTag = k.enum "lua encoder tag" [ "lua" ];
-        })
-        (obj: obj.value);
-    # This is the most rudimentary (and currently only) way of handling paths.
-    luaImport = tag:
-      m.typed (k.typedef "path" lib.isPath)
-        (path: "dofile(${m.string "${path}"}).${tag}");
-    # Accepts both tagged and untagged strings of lua code.
-    luaString = m.try m.markedLuaCode m.identity;
-    # This simply combines the above combinators into one.
-    luaCode = tag: m.try (m.luaImport tag) m.luaString;
-    # }}}
-    # {{{ Operators
-    conjunction = left: right: given:
-      m.typed (helpers.intersection left right) (
-        let
-          l = left.toLua given;
-          r = right.toLua given;
-        in
-        if l == "nil" then r
-        else if r == "nil" then l
-        else "${l} and ${r}"
-      );
-    all = lib.foldr m.conjunction m.nil;
-    # Similar to `all` but takes in a list and
-    # treats every element as a condition.
-    allIndices = name: type: 
-      m.bind name 
-        (g: lib.pipe g [
-          (lib.lists.imap0
-            (i: _:
-              m.cmap 
-                (builtins.elemAt i) 
-                type))
-          m.all
-        ]);
-    # }}}
-    # {{{ Lists
-    listOf = type: list:
-      m.typedWithDefault
-        (k.listOf type)
-        (helpers.mkRawLuaObject (lib.lists.map type.toLua list))
-        [ ];
-    listOfOr = type: m.try (m.listOf type);
-    # Returns nil when given empty lists
-    tryNonemptyList = type:
-      m.typedWithDefault
-        (k.listOf type)
-        (m.filter
-          (l: l != [ ])
-          (m.listOf type))
-        [ ];
-    oneOrMany = type: m.listOfOr type type;
-    # Can encode:
-    # - zero values as nil
-    # - one value as itself
-    # - multiple values as a list
-    zeroOrMany = type: m.nullOr (m.oneOrMany type);
-    # Coerces non list values to lists of one element.
-    oneOrManyAsList = type: m.listOfOr type (m.map (e: [ e ]) type);
-    # Coerces lists of one element to said element.
-    listAsOneOrMany = type:
-      m.cmap
-        (l: if lib.length l == 1 then lib.head l else l)
-        (m.oneOrMany type);
-    # }}}
-    # {{{ Attrsets
-    attrsetOf = type:
-      m.typed (k.attrsOf type)
-        (object:
-          helpers.mkRawLuaObject (lib.mapAttrsToList
-            (name: value:
-              let result = type.toLua value;
-              in
-              lib.optionalString (result != "nil")
-                "${helpers.mkAttrName name} = ${result}"
-            )
-            object
+      ''
+        {
+          ${lib.concatStringsSep "\n" folds}
+        }''
+    else if isLuaLiteral given then
+      given.value
+    else if lib.isAttrs given then
+      helpers.mkRawLuaObject
+        (lib.mapAttrsToList
+          (name: value:
+            let result = recurse value;
+            in
+            lib.optionalString (result != "nil")
+              "${helpers.mkAttrName name} = ${result}"
           )
-        );
-    # This is the most general combinator provided in this section.
-    #
-    # We accept:
-    # - order of props that should be interpreted as list elements
-    # - spec of props that should be interpreted as list elements
-    # - record of props that should be interpreted as attribute props
-    attrset = name: listOrder: spec: attrset:
-      m.cmap
-        (given: lib.mapAttrs
-          (key: type:
-            if given ? ${key} then
-              given.${key}
-            else
-              type.default or null)
-          spec)
-        (m.typed (k.struct name spec) (
-          let
-            listChunks = lib.lists.map
-              (attr:
-                let result = spec.${attr}.toLua (attrset.${attr} or null);
-                in
-                lib.optionalString (result != "nil") result
-              )
-              listOrder;
-            objectChunks = lib.mapAttrsToList
-              (attr: type:
-                let result = type.toLua (attrset.${attr} or null);
-                in
-                lib.optionalString (!(lib.elem attr listOrder) && result != "nil")
-                  "${helpers.mkAttrName attr} = ${result}"
-              )
-              spec;
-          in
-          helpers.mkRawLuaObject (listChunks ++ objectChunks)
-        ));
-    withAttrsCheck = type: verify:
-      type.override { inherit verify; };
-    # }}}
-  };
+          given)
+    else if lib.isFunction given then
+      let
+        argNames = [ "context" "inner_context" "local_context" ];
+        secretArg =
+          if depth >= builtins.length argNames
+          then "arg_${depth}"
+          else builtins.elemAt argNames depth;
+        body = given secretArg;
+        encoded = encodeWithDepth (depth + 1) body;
+        encodedBody =
+          if isLuaLiteral body
+          then encoded
+          else "return ${encoded}";
+      in
+      if lib.hasInfix secretArg encoded
+      then ''
+        function(${secretArg})
+          ${encodedBody}
+        end''
+      else ''
+        function()
+          ${encodedBody}
+        end''
+    else builtins.throw "Cannot encode value ${helpers.toPretty given}";
   # }}}
+  encode = encodeWithDepth 0;
 in
-m // { inherit helpers; }
+{ inherit encode helpers; }
diff --git a/modules/common/korora-neovim.nix b/modules/common/korora-neovim.nix
index 6a07d68..d5c1a02 100644
--- a/modules/common/korora-neovim.nix
+++ b/modules/common/korora-neovim.nix
@@ -1,36 +1,234 @@
-attrs@{ lib, ... }:
+attrs@{ lib, korora, ... }:
 let
   e = import ./korora-lua.nix attrs;
+  k = korora;
   h = e.helpers;
-  m = {
-    lazyModule = e.withAttrsCheck
-      (e.attrset "lazy module" [ "package" ] {
-        package = e.nullOr e.string;
-        dir = e.nullOr e.type;
-        version = e.nullOr e.string;
-        tag = e.nullOr e.string;
-        name = e.nullOr e.string;
-        main = e.nullOr e.string;
-        lazy = e.nullOr e.bool;
-        dependencies = e.tryNonemptyList (e.stringOr m.lazyModule);
-        config = e.anything;
-        cond = e.nullOr (e.bind (value: e.all [
-          # TODO: we want a zip here
-          (e.nullOr (e.luaCode "cond"))
-        ]));
-        init = e.nullOr (e.luaCode "init");
-        event = e.zeroOrMany e.string;
-        cmd = e.zeroOrMany e.string;
-        ft = e.zeroOrMany e.string;
-        keys = e.listOf e.anything;
-        passthrough = e.anything;
-        opts = e.anything;
-      })
-      (h.mkVerify [
+  struct = name: props: verify: (k.struct name props).override {
+    total = false;
+    unknown = false;
+    verify = h.mkVerify verify;
+  };
+
+  lazyType = name: mkType: k.typedef' name (v: (mkType true).verify v);
+
+  types = {
+    # {{{ Helper types
+    oneOrMany = type: k.union [ type (k.listOf type) ];
+    luaValue = k.any;
+    strictLuaLiteral = (k.struct "lua literal" {
+      value = k.string;
+      __luaEncoderTag = k.enum "lua literal tag" [ "lua" ];
+    }).override { unknown = false; };
+    derivation = k.typedef "derivation" lib.isDerivation;
+    path = k.typedef "path" lib.isPath;
+    functionCheckedWith = arg: type:
+      k.typedef'
+        "${h.toPretty arg} -> ${type.name}"
+        (f:
+          if lib.isFunction f
+          then type.verify (f arg)
+          else "Expected function, but got ${h.toPretty f} instead");
+    luaEagerOrLazy = type: k.union [ type (types.functionCheckedWith "" type) ];
+    luaLiteral = types.luaEagerOrLazy types.strictLuaLiteral;
+    # }}}
+    # {{{ Lazy key 
+    lazyKey = struct "lazy key"
+      {
+        mapping = k.string;
+        action = k.union [ types.luaLiteral k.string ];
+        mode = k.string;
+        desc = k.string;
+        expr = k.bool;
+        ft = types.oneOrMany k.string;
+      }
+      [ (h.propExists "mapping") ];
+    # }}}
+    # {{{ Lazy module 
+    lazyModule = lazyType "actually lazy lazy module" (_: struct "lazy module"
+      {
+        package = k.string;
+        dir = k.union [ k.string types.derivation types.path ];
+        version = k.string;
+        tag = k.string;
+        name = k.string;
+        main = k.string;
+        lazy = k.bool;
+        dependencies = struct "lazy dependencies"
+          {
+            lua = k.listOf (k.union [ k.string types.lazyModule ]);
+            nix = k.listOf types.derivation;
+          }
+          [ ];
+        cond = types.oneOrMany types.luaLiteral;
+        init = types.luaLiteral;
+        config = k.union [ types.luaLiteral k.bool types.tempestConfig ];
+        event = types.oneOrMany k.string;
+        cmd = types.oneOrMany k.string;
+        ft = types.oneOrMany k.string;
+        keys = types.oneOrMany (k.union [ k.string types.lazyKey ]);
+        passthrough = types.luaValue;
+        opts = types.luaValue;
+      }
+      [
         (h.propOnlyOne [ "dir" "package" ])
         (h.propImplies "tag" "package")
         (h.propImplies "version" "package")
       ]);
+    # }}}
+    # {{{ Tempest key 
+    tempestKey = struct "tempest key"
+      {
+        mapping = k.string;
+        action = k.union [ types.luaLiteral k.string ];
+        mode = k.string;
+        desc = k.string;
+        expr = k.bool;
+        silent = k.bool;
+        ft = types.oneOrMany k.string;
+        buffer = k.union [ k.bool k.number types.luaLiteral ];
+      }
+      [
+        (h.propExists "mapping")
+        (h.propExists "action")
+      ];
+    # }}}
+    # {{{ Tempest autocmd 
+    tempestAutocmd = struct "tempest autocommand"
+      {
+        event = types.oneOrMany k.string;
+        pattern = types.oneOrMany k.string;
+        group = k.string;
+        action = k.union [ types.tempestConfig types.luaLiteral ];
+      }
+      [
+        (h.propExists "event")
+        (h.propExists "group")
+        (h.propExists "action")
+      ];
+    # }}}
+    # {{{ Tempest config
+    tempestConfig = lazyType "lazy tempest config" (_: struct "tempest config"
+      {
+        vim = types.luaValue;
+        callback = k.union [ k.function types.luaLiteral ];
+        setup = k.attrsOf types.luaValue;
+        keys = types.luaEagerOrLazy (types.oneOrMany types.tempestKey);
+        autocmds = types.luaEagerOrLazy (types.oneOrMany types.tempestAutocmd);
+        mkContext = types.luaLiteral;
+      }
+      [ ]);
+    # }}}
+    # {{{ Neovim env 
+    neovimEnv = k.enum "neovim env"
+      [ "neovide" "firenvim" "vscode" ];
+    # }}}
+    # {{{ Neovim config 
+    neovimConfig = struct "neovim configuration"
+      {
+        pre = k.attrsOf types.tempestConfig;
+        lazy = k.attrsOf types.lazyModule;
+        post = k.attrsOf types.tempestConfig;
+      } [ ];
+    # }}}
   };
+
+  hasType = type: value:
+    let err = type.verify value; in
+    lib.assertMsg (err == null) err;
+
+  mkLib = { tempestModule, languageServerModule }:
+    assert hasType k.string tempestModule;
+    assert hasType k.string languageServerModule;
+    rec {
+      inherit (e) encode;
+      # {{{ Common generation helpers 
+      lua = value: assert hasType k.string value;
+        { inherit value; __luaEncoderTag = "lua"; };
+      import = path: tag:
+        assert lib.isPath path;
+        assert hasType k.string tag;
+        lua "dofile(${encode (toString path)}).${tag}";
+      foldedList = value: assert hasType k.attrs value;
+        { inherit value; __luaEncoderTag = "foldedList"; };
+      thunk = code: _: lua code;
+      tempest = given: context: lua ''
+        D.tempest.configure(
+          ${encode given},
+          ${context}
+        )
+      '';
+      customLanguageServerOnAttach = given:
+        assert hasType types.tempestConfig given;
+        lua /* lua */ ''
+          function(client, bufnr)
+            D.tempest.configure(${encode given}, 
+              { client = client; bufnr = bufnr; })
+
+            D.language_server.on_attach(client, bufnr)
+          end
+        '';
+      blacklist = given:
+        assert hasType (types.oneOrMany types.neovimEnv) given;
+        lua /* lua */  ''
+          D.tempest.blacklist(${encode given})
+        '';
+      whitelist = given:
+        assert hasType (types.oneOrMany types.neovimEnv) given;
+        lua /* lua */  ''
+          D.tempest.whitelist(${encode given})
+        '';
+      # }}}
+      # {{{ Main config generation entrypoint
+      generateConfig = rawConfig:
+        assert hasType types.neovimConfig rawConfig;
+        let
+          config = { lazy = { }; pre = { }; post = { }; } // rawConfig;
+          collectNixDeps = lazyModule:
+            if lazyModule ? dependencies then
+              let
+                nix = lazyModule.dependencies.nix or [ ];
+                other = lib.pipe (lazyModule.dependencies.lua or [ ]) [
+                  (lib.lists.map collectNixDeps)
+                  lib.lists.flatten
+                ];
+              in
+              nix ++ other
+            else
+              [ ];
+          dependencies = lib.pipe config.lazy [
+            (lib.mapAttrsToList (_: collectNixDeps))
+            lib.lists.flatten
+          ];
+          processedLazyModules =
+            lib.mapAttrs
+              (name: module: { inherit name; } // module // {
+                dependencies = (module.dependencies or { }).lua or null;
+              })
+              config.lazy;
+
+          luaConfig = ''
+            local M = {}
+            local D = {
+              tempest = require(${encode tempestModule}),
+              langauge_server = require(${encode languageServerModule})
+            }
+
+            -- {{{ Pre-plugin config
+            M.pre = ${encode (foldedList config.pre)}
+            -- }}}
+            -- {{{ Lazy modules 
+            M.lazy = ${encode (foldedList processedLazyModules)}
+            D.tempest.prepareLazySpec(M.lazy)
+            -- }}}
+            -- {{{ Post-plugin config
+            M.post = ${encode (foldedList config.post)}
+            -- }}}
+
+            return M
+          '';
+        in
+        { inherit dependencies; lua = luaConfig; };
+      # }}}
+    };
 in
-m
+mkLib
diff --git a/modules/common/lua-encoders.nix b/modules/common/lua-encoders.nix
index d621bb3..e40abed 100644
--- a/modules/common/lua-encoders.nix
+++ b/modules/common/lua-encoders.nix
@@ -196,7 +196,7 @@ in
       let
         destination = "${path}/${name}.lua";
         unformatted = pkgs.writeText "raw-lua-${name}" ''
-          -- ❄️ This file was generated using nix ^~^
+          -- ❄️ I was generated using nix ^~^
           ${text}
         '';
       in