diff --git a/common/icons/github.png b/common/icons/github.png
new file mode 100644
index 0000000..3c60c49
Binary files /dev/null and b/common/icons/github.png differ
diff --git a/common/icons/porkbun.png b/common/icons/porkbun.png
new file mode 100644
index 0000000..a6ec4fa
Binary files /dev/null and b/common/icons/porkbun.png differ
diff --git a/common/icons/tailscale.png b/common/icons/tailscale.png
new file mode 100644
index 0000000..e1659e6
Binary files /dev/null and b/common/icons/tailscale.png differ
diff --git a/flake.lock b/flake.lock
index 1fc40ac..a2f5281 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1278,11 +1278,11 @@
         "purifix": "purifix"
       },
       "locked": {
-        "lastModified": 1713302426,
-        "narHash": "sha256-29m8oM9CtmvHKzfK1xfz2R7/Ae1GimmRyb3i27oIOw0=",
+        "lastModified": 1713852340,
+        "narHash": "sha256-4H5l6Hsg6SzhZwB8ikphlJmLtyi3xeUcPPsVh3gVd/k=",
         "owner": "mateiadrielrafael",
         "repo": "miros",
-        "rev": "45b9ce1c3fedd548d824a01608e1a5c9570b8d95",
+        "rev": "80a1cd4726b6d1b7b9d9ee4cfe850d87d524090b",
         "type": "github"
       },
       "original": {
@@ -1502,8 +1502,8 @@
       },
       "original": {
         "owner": "NixOS",
+        "ref": "nixos-23.11",
         "repo": "nixpkgs",
-        "rev": "b8dd8be3c790215716e7c12b247f45ca525867e2",
         "type": "github"
       }
     },
diff --git a/home/features/desktop/firefox/default.nix b/home/features/desktop/firefox/default.nix
index e9ed0db..ec9a5e5 100644
--- a/home/features/desktop/firefox/default.nix
+++ b/home/features/desktop/firefox/default.nix
@@ -15,6 +15,7 @@ let
     localcdn # caches libraries locally
     privacy-badger # blocks some trackers
     privacy-pass # captcha stuff
+    privacy-redirect # allows redirecting to my own instances for certain apps
     skip-redirect # attempts to skip to the final reddirect for certain urls
     terms-of-service-didnt-read
     translate-web-pages
diff --git a/home/features/neovim/config/ftplugin/tex.lua b/home/features/neovim/config/ftplugin/tex.lua
index 7cfe11e..8f1eb93 100644
--- a/home/features/neovim/config/ftplugin/tex.lua
+++ b/home/features/neovim/config/ftplugin/tex.lua
@@ -22,25 +22,6 @@ local abbreviations = {
   { "spt", "\\supset" },
   { "sseq", "\\subseteq" },
   { "speq", "\\supseteq" },
-  { "nin", "\\not\\in" },
-  { "iin", "\\in" },
-  { "tto", "\\to" },
-  { "land", "\\land" },
-  { "lor", "\\lor" },
-  { "ssin", "\\sin" },
-  { "ccos", "\\cos" },
-  { "ttan", "\\ttan" },
-  { "ssec", "\\sec" },
-  { "lln", "\\ln" },
-  { "frl", "\\forall" },
-  { "exs", "\\exists" },
-  { "iinf", "\\infty" },
-  { "ninf", "-\\infty" },
-  { "nlnl", "\\pm" }, -- had this as npnp first but it was hard-ish to type
-  { "ccup", "\\cup" },
-  { "ccap", "\\cap" },
-  { "nope", "\\bot" },
-  { "yee", "\\top" },
   { "ccan", "\\cancel" },
   { "com", "\\circ" },
   { "mul", "\\cdot" },
@@ -57,24 +38,6 @@ local abbreviations = {
   { "sup", "\\sup" }, -- supremum
   { "limsup", "\\lim\\sup" }, -- Limit of the supremum
   { "cal", "\\mathcal" }, -- Limit of the supremum
-
-  -- Decorations
-  { "hat", "\\hat" },
-  { "bar", "\\bar" },
-
-  -- Custom commands
-  { "abs", "\\abs" }, -- custom abs command
-  { "norm", "\\norm" }, -- custom norm command
-  { "iprod", "\\iprod" }, -- custom inner product command
-  { "diprod", "\\dprod" }, -- custom self inner product command
-  { "prob", "\\prob" }, -- custom probability function
-  { "dist", "\\dist" }, -- custom dist function
-  { "oball", "\\ball" }, -- custom ball function
-  { "diam", "\\diam" }, -- custom diam operator
-  { "gen", "\\gen" }, -- custom command for group generated by element
-  { "ord", "\\ordop" }, -- order of a group
-  { "vsm", "\\vecspace" }, -- custom math vector space
-  { "half", "\\half" }, -- 1/2 fraction
 }
 
 local abolishAbbreviations = {
@@ -93,16 +56,6 @@ local abolishAbbreviations = {
     options = A.no_capitalization,
   },
   -- }}}
-  -- {{{ My own operator syntax:
-  --   - Any operator can be prefixed with "a" to
-  --     align in aligned mode
-  --   - Any operator can be prefixed with cr to
-  --     start a new line and align in aligned mode
-  {
-    "{cr,a,}{eq,neq,leq,geq,lt,gt,iff,iip,iib}",
-    "{\\\\\\&,&,}{=,\\neq,\\leq,\\geq,<,>,\\iff,\\implies,\\impliedby}",
-  },
-  -- }}}
   -- {{{ General function calls:
   --   {function-name}{modifier?}{argument}{argument-modifier?}
   --
diff --git a/home/features/neovim/config/init.lua b/home/features/neovim/config/init.lua
index 1e7853a..bba7b4b 100644
--- a/home/features/neovim/config/init.lua
+++ b/home/features/neovim/config/init.lua
@@ -1,21 +1,10 @@
--- enable experimental lua loader
+-- Enable experimental lua loader
 vim.loader.enable()
+vim.opt.runtimepath:prepend(vim.g.nix_extra_runtime)
 
--- bootstrap from github
-local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+local tempest = require("my.tempest")
+local nix = require("nix")
 
-if not vim.loop.fs_stat(lazypath) then
-  vim.fn.system({
-    "git",
-    "clone",
-    "--filter=blob:none",
-    "--single-branch",
-    "git@github.com:folke/lazy.nvim.git",
-    lazypath,
-  })
-end
-
-vim.opt.runtimepath:prepend(lazypath)
-
--- Start the actual init process
-require("my.init").setup()
+tempest.configureMany(nix.pre)
+require("my.lazy").setup()
+tempest.configureMany(nix.post)
diff --git a/home/features/neovim/config/lazy-lock.json b/home/features/neovim/config/lazy-lock.json
index c278273..5987fe1 100644
--- a/home/features/neovim/config/lazy-lock.json
+++ b/home/features/neovim/config/lazy-lock.json
@@ -1,11 +1,9 @@
 {
-  "alpha-nvim": { "branch": "main", "commit": "1356b9ef31b985d541d94314f2cf73c61124bf1d" },
   "catppuccin": { "branch": "main", "commit": "9703f227bfab20d04bcee62d2f08f1795723b4ae" },
   "clipboard-image": { "branch": "main", "commit": "485de5493d196154db30f85665f8ac480ce116a2" },
   "cmp": { "branch": "main", "commit": "04e0ca376d6abdbfc8b52180f8ea236cbfddf782" },
   "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
   "cmp-cmdline": { "branch": "main", "commit": "8ee981b4a91f536f52add291594e89fb6645e451" },
-  "cmp-digraphs": { "branch": "master", "commit": "5efc1f0078d7c5f3ea1c8e3aad04da3fd6e081a9" },
   "cmp-emoji": { "branch": "main", "commit": "19075c36d5820253d32e2478b6aaf3734aeaafa0" },
   "cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" },
   "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
@@ -27,16 +25,17 @@
   "inc-rename": { "branch": "main", "commit": "6f9b5f9cb237e12935144cdc535322b8c93c1b25" },
   "indent-blankline": { "branch": "master", "commit": "821a7acd88587d966f7e464b0b3031dfe7f5680c" },
   "lastplace": { "branch": "main", "commit": "0bb6103c506315044872e0f84b1f736c4172bb20" },
-  "lazy.nvim": { "branch": "main", "commit": "aedcd79811d491b60d0a6577a9c1701063c2a609" },
   "lean": { "branch": "main", "commit": "1a2a2dfbc7e6775e9ec8b84e5eadaf31fde1894e" },
   "live-command": { "branch": "main", "commit": "d460067d47948725a6f25b20f31ea8bbfdfe4622" },
   "lspconfig": { "branch": "master", "commit": "16295b79410f131c4fa7870c663b4ace6a761fb2" },
   "lspkind.nvim": { "branch": "master", "commit": "1735dd5a5054c1fb7feaf8e8658dbab925f4f0cf" },
   "luasnip": { "branch": "master", "commit": "8ae1dedd988eb56441b7858bd1e8554dfadaa46d" },
+  "mini.ai": { "branch": "main", "commit": "98e45e6832351354e41e82b32a80ce7537c20746" },
   "mini.comment": { "branch": "main", "commit": "a4b7e46deb9ad2feb8902cc5dbf087eced112ee5" },
   "mini.files": { "branch": "main", "commit": "eab771c69b787a3f042dc6505d15613c282aa786" },
   "mini.operators": { "branch": "main", "commit": "0765e4818086e96b8fb55d280e47af781a5bc56a" },
   "mini.pairs": { "branch": "main", "commit": "04f58f2545ed80ac3b52dd4826e93f33e15b2af6" },
+  "mini.starter": { "branch": "main", "commit": "4cfe09ee18390708fcdbe3bc6e7a4f4a06731db9" },
   "mini.statusline": { "branch": "main", "commit": "dfd3d2ba295473930f78f143852b9b53eb54ae2a" },
   "mini.surround": { "branch": "main", "commit": "a1b590cc3b676512de507328d6bbab5e43794720" },
   "navigator": { "branch": "master", "commit": "91d86506ac2a039504d5205d32a1d4bc7aa57072" },
@@ -44,7 +43,6 @@
   "neodev": { "branch": "main", "commit": "84e0290f5600e8b89c0dfcafc864f45496a53400" },
   "nui": { "branch": "main", "commit": "c3c7fd618dcb5a89e443a2e1033e7d11fdb0596b" },
   "null-ls": { "branch": "main", "commit": "0010ea927ab7c09ef0ce9bf28c2b573fc302f5a7" },
-  "nvim-treesitter-textobjects": { "branch": "master", "commit": "7f00d94543f1fd37cab2afa2e9a6cd54e1c6b9ef" },
   "plenary": { "branch": "master", "commit": "4f71c0c4a196ceb656c824a70792f3df3ce6bb6d" },
   "purescript": { "branch": "main", "commit": "82348352e6568fcc0385bd7c99a8ead3a479feea" },
   "rust-tools": { "branch": "master", "commit": "676187908a1ce35ffcd727c654ed68d851299d3e" },
diff --git a/home/features/neovim/config/lua/my/abbreviations/global.lua b/home/features/neovim/config/lua/my/abbreviations/global.lua
index f615b5b..c372b58 100644
--- a/home/features/neovim/config/lua/my/abbreviations/global.lua
+++ b/home/features/neovim/config/lua/my/abbreviations/global.lua
@@ -2,29 +2,12 @@ local A = require("my.abbreviations")
 local scrap = require("scrap")
 local M = {}
 
--- {{{ Ascii
-M.ascii = {
-  { "tto", "->" }, -- [t]o
-  { "ffrom", "<-" }, -- [f]rom
-  { "iip", "=>" }, -- [i]t [i]m[p]lies
-  { "iib", "<=" }, -- [i]t's [i]mplied [b]ly
-
-  { "leq", "<=" }, -- [l]ess than or [e][q]ual
-  { "geq", ">=" }, -- [g]reater than or [e][q]ual
-  { "seq", "=" }, -- [s]ingle [e][q]ual
-  { "deq", "==" }, -- [d]ouble [e][q]ual
-  { "land", "/\\" }, -- [l]ogial [a][n][d]
-  { "lor", "\\/" }, -- [l]ogial [o][r]
-}
--- }}}
-
 M.words = {
   { "thrf", "therefore" },
 }
 
 function M.setup()
   A.manyGlobalAbbr(scrap.expand_many(M.words))
-  A.manyGlobalAbbr(scrap.expand_many(M.ascii, { capitalized = false }))
 end
 
 return M
diff --git a/home/features/neovim/config/lua/my/abbreviations/math.lua b/home/features/neovim/config/lua/my/abbreviations/math.lua
index e51f0cd..5a3aa44 100644
--- a/home/features/neovim/config/lua/my/abbreviations/math.lua
+++ b/home/features/neovim/config/lua/my/abbreviations/math.lua
@@ -19,35 +19,6 @@ M.words = {
   { "cex{,s}", "counterexample{}" },
   { "er{t,s,r}", "{transitivity,symmetry,reflexivity}" },
   -- }}}
-  -- {{{ Special chars
-  -- System for writing special characters which need to also be easly
-  -- accessible as {sub/super}scripts.
-  --
-  -- The reason epsilon and lambda are separated out from everything else in
-  -- the pattern is because they are the only ones where `foo` doesn't expand
-  -- to `\\foo` directly (so I saved some keystrokes by letting scrap.nvim
-  -- repeat everything for me).
-  {
-    "{,e,s}{{eps,lam},{star,delta,Delta,pi,tau,psi,phi,rho,sigma,alpha,beta,theta,gamma,omega,Omega}}",
-    "{,^,_}\\\\{{epsilon,lambda},{}}",
-    options = A.no_capitalization,
-  },
-  -- }}}
-  -- {{{ Set symbols
-  --   - nats => naturals
-  --   - ints => integers
-  --   - rats => rationals
-  --   - irats => irationals
-  --   - rrea => reals
-  --   - comp => complex
-  --   - ppri => primes
-  --   - ffie => fields
-  {
-    "{nats,ints,rats,irats,rrea,comp,ppri,ffie}",
-    "\\mathbb\\{{N,Z,Q,I,R,C,P,F}\\}",
-    options = A.no_capitalization,
-  },
-  -- }}}
   -- {{{ Calculus & analysis
   { "ib{p,s}", "integration by {parts,substitution}" },
   { "{o,c,}nb{,h}{,s}", "{open,closed,} neighbour{,hood}{}" },
diff --git a/home/features/neovim/config/lua/my/init.lua b/home/features/neovim/config/lua/my/init.lua
deleted file mode 100644
index 9410b83..0000000
--- a/home/features/neovim/config/lua/my/init.lua
+++ /dev/null
@@ -1,22 +0,0 @@
-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
-  tempest.configureMany(nix.pre)
-  require("my.keymaps").setup()
-  require("my.lazy").setup()
-  tempest.configureMany(nix.post)
-
-  require("luasnip.loaders.from_lua").lazy_load({
-    fs_event_providers = {
-      libuv = true,
-    },
-  })
-end
-
-return M
diff --git a/home/features/neovim/config/lua/my/keymaps.lua b/home/features/neovim/config/lua/my/keymaps.lua
deleted file mode 100644
index 76faee8..0000000
--- a/home/features/neovim/config/lua/my/keymaps.lua
+++ /dev/null
@@ -1,65 +0,0 @@
--- TODO: operator for wrapping motion with fold
-local M = {}
-
--- {{{ Helpers
----Performs a basic move operation
----Moves a keybind to a different set of keys.
----Useful for moving built in keybinds out of the way.
----@param from string
----@param to string
----@param opts table|nil
-function M.move(from, to, opts)
-  vim.keymap.set("n", to, from, opts)
-  vim.keymap.set("n", from, "<Nop>")
-end
-
----Create a textobject defined by some delimiters
----@param from string
----@param to string
----@param name string
----@param opts table|nil
-function M.delimitedTextobject(from, to, name, opts)
-  opts = opts or {}
-
-  if opts.desc == nil then
-    opts.desc = name
-  end
-
-  vim.keymap.set({ "v", "o" }, "i" .. from, "i" .. to, opts)
-  vim.keymap.set({ "v", "o" }, "a" .. from, "a" .. to, opts)
-end
-
----Helper to create a normal mode mapping and give it some description.
----@param from string
----@param to string|function
----@param desc string
----@param silent boolean|nil
----@param isLocal boolean|nil
-function M.nmap(from, to, desc, silent, isLocal)
-  if silent == nil then
-    silent = true
-  end
-
-  if isLocal == nil then
-    isLocal = false
-  end
-
-  vim.keymap.set(
-    "n",
-    from,
-    to,
-    { desc = desc, silent = silent, buffer = isLocal }
-  )
-end
-
--- }}}
-
-function M.setup()
-  -- {{{ Text objects
-  M.delimitedTextobject("q", '"', "[q]uotes")
-  M.delimitedTextobject("a", "'", "[a]postrophes")
-  M.delimitedTextobject("r", "[", "squa[r]e brackets")
-  -- }}}
-end
-
-return M
diff --git a/home/features/neovim/config/lua/my/plugins/dashboard.lua b/home/features/neovim/config/lua/my/plugins/dashboard.lua
deleted file mode 100644
index d45ca71..0000000
--- a/home/features/neovim/config/lua/my/plugins/dashboard.lua
+++ /dev/null
@@ -1,70 +0,0 @@
-local runtime = require("my.tempest")
-
-local header_string = [[
-███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗       ██████╗
-████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║    ██╗╚════██╗
-██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║    ╚═╝ █████╔╝
-██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║    ██╗ ╚═══██╗
-██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║    ╚═╝██████╔╝
-╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝       ╚═════╝
-]]
-
-local header = runtime.helpers.split(header_string, "\n")
-
-local M = {
-  "goolord/alpha-nvim",
-  dependencies = { "web-devicons" },
-  config = function()
-    local theme = require("alpha.themes.dashboard")
-    theme.opts.width = 70
-    theme.opts.position = "center"
-    theme.section.buttons.val = {}
-
-    -- See [the header generator](https://patorjk.com/software/taag/#p=display&v=0&f=ANSI%20Shadow&t=NEOVim%20%3A3)
-    theme.section.header.opts.hl = "AlphaHeader"
-    theme.section.header.val = header
-    local version = vim.version()
-    local footer = function()
-      local versionString = "🚀 "
-        .. version.major
-        .. "."
-        .. version.minor
-        .. "."
-        .. version.patch
-      local lazy_ok, lazy = pcall(require, "lazy")
-      if lazy_ok then
-        local total_plugins = lazy.stats().count .. " Plugins"
-        local startuptime = (
-          math.floor(lazy.stats().startuptime * 100 + 0.5) / 100
-        )
-        return versionString
-          .. " —  🧰 "
-          .. total_plugins
-          .. " —  🕐 "
-          .. startuptime
-          .. "ms"
-      else
-        return version
-      end
-    end
-
-    vim.api.nvim_create_autocmd("User", {
-      pattern = "LazyVimStarted",
-      callback = function()
-        theme.section.footer.val = footer()
-        vim.cmd("AlphaRedraw")
-      end,
-      desc = "Footer for Alpha",
-    })
-
-    theme.section.footer.opts.hl = "AlphaFooter"
-    theme.section.header.opts.hl = "AlphaHeader"
-    theme.section.buttons.opts.hl = "AlphaButton"
-
-    require("alpha").setup(theme.config)
-  end,
-  lazy = false,
-  cond = runtime.blacklist({ "vscode", "firenvim" }),
-}
-
-return M
diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix
index f13683f..7c62ca1 100644
--- a/home/features/neovim/default.nix
+++ b/home/features/neovim/default.nix
@@ -75,7 +75,7 @@ let
             # }}}
             # {{{ Folding
             foldmethod = "marker"; # use {{{ }}} for folding
-            foldcolumn = "1"; # show column with folds on the left
+            foldcolumn = "0"; # show no column with folds on the left
             # }}}
           };
 
@@ -262,9 +262,10 @@ let
           };
         };
         # }}}
-        # {{{ Language specific settings
+        # {{{ Language specific overrides
         "5:language-specific-settings" = {
           autocmds = [
+            # {{{ Nix
             {
               event = "FileType";
               group = "UserNixSettings";
@@ -282,6 +283,8 @@ let
                 };
               };
             }
+            # }}}
+            # {{{ Purescript
             {
               event = "FileType";
               group = "UserPurescriptSettings";
@@ -291,6 +294,7 @@ let
                 commentstring = "-- %s";
               };
             }
+            # }}}
           ];
         };
         # }}}
@@ -589,7 +593,6 @@ let
           package = "nvim-treesitter/nvim-treesitter";
           main = "nvim-treesitter.configs";
 
-          dependencies.lua = [ "nvim-treesitter/nvim-treesitter-textobjects" ];
           dependencies.nix = [ pkgs.tree-sitter ];
 
           cond = blacklist "vscode";
@@ -602,45 +605,7 @@ let
             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;
         };
         # }}}
@@ -656,6 +621,24 @@ let
         #   opts.enable = true;
         # };
         # }}}
+        # {{{ mini.starter
+        mini-starter = {
+          package = "echasnovski/mini.starter";
+          name = "mini.starter";
+          cond = blacklist [ "vscode" "firenvim" ];
+          lazy = false;
+
+          opts = _: {
+            header = builtins.readFile ./header.txt;
+            footer = importFrom ./plugins/ministarter.lua "lazy_stats_item";
+            content_hooks = [
+              (lua ''require("mini.starter").gen_hook.adding_bullet()'')
+              (lua ''require("mini.starter").gen_hook.aligning('center', 'center')'')
+            ];
+            silent = true;
+          };
+        };
+        # }}}
         # }}}
         # {{{ editing 
         # {{{ text navigation
@@ -753,6 +736,29 @@ let
           opts.keymaps.replace_all = "<s-cr>";
         };
         # }}}
+        # {{{ mini.ai 
+        mini-ai = {
+          package = "echasnovski/mini.ai";
+          name = "mini.ai";
+          event = "VeryLazy";
+
+          opts = _: # lazy, as we import mini.ai inside
+            let balanced = from: [ "%b${from}" "^.().*().$" ];
+            in
+            {
+              custom_textobjects = {
+                b = balanced "()";
+                B = balanced "{}";
+                r = balanced "[]";
+                v = balanced "⟨⟩";
+                q = balanced "\"\"";
+                Q = balanced "``";
+                a = balanced "''";
+                A = lua "require('mini.ai').gen_spec.argument()";
+              };
+            };
+        };
+        # }}}
         # {{{ mini.comment 
         mini-comment = {
           package = "echasnovski/mini.comment";
@@ -805,6 +811,7 @@ let
               r = mk true "%b[]" "[" "]";
               v = mk true "%b⟨⟩" "⟨" "⟩";
               q = mk false "\".-\"" "\"" "\"";
+              Q = mk false "`.-`" "`" "`";
               a = mk false "'.-'" "'" "'";
             };
           # }}}
@@ -835,70 +842,72 @@ let
           package = "echasnovski/mini.pairs";
           name = "mini.pairs";
 
-          config = true;
           # We could specify all the generated bindings, but I don't think it's worth it
           event = [ "InsertEnter" "CmdlineEnter" ];
         };
         # }}}
         # {{{ luasnip
         # snippeting engine
-        luasnip =
-          {
-            package = "L3MON4D3/LuaSnip";
-            version = "v2";
+        luasnip = {
+          package = "L3MON4D3/LuaSnip";
+          version = "v2";
 
-            cond = blacklist "vscode";
-            config = thunk ''
-              require("luasnip").config.setup(${encode {
-                enable_autosnippets = true;
-                update_events = ["TextChanged" "TextChangedI"];
-              }})
-            '';
+          cond = blacklist "vscode";
+          config = thunk ''
+            require("luasnip").config.setup(${encode {
+              enable_autosnippets = true;
+              update_events = ["TextChanged" "TextChangedI"];
+            }})
 
-            # {{{ Keybinds
-            keys = [
-              {
-                mode = "i";
-                expr = true;
-                mapping = "<tab>";
-                action = thunk /* lua */ ''
-                  local luasnip = require("luasnip")
+            require("luasnip.loaders.from_lua").lazy_load(${encode {
+              fs_event_providers.libuv = true;
+            }})
+          '';
 
-                  if not luasnip.jumpable(1) then
-                    return "<tab>"
-                  end
+          # {{{ Keybinds
+          keys = [
+            {
+              mode = "i";
+              expr = true;
+              mapping = "<tab>";
+              action = thunk /* lua */ ''
+                local luasnip = require("luasnip")
 
-                  vim.schedule(function()
-                    luasnip.jump(1)
-                  end)
+                if not luasnip.jumpable(1) then
+                  return "<tab>"
+                end
 
-                  return "<ignore>"
-                '';
-                desc = "Jump to next snippet tabstop";
-              }
-              {
-                mode = "i";
-                mapping = "<s-tab>";
-                action = thunk /* lua */ ''
-                  require("luasnip").jump(-1)
-                '';
-                desc = "Jump to previous snippet tabstop";
-              }
-              {
-                mode = "is";
-                mapping = "<c-a>";
-                action = "<Plug>luasnip-prev-choice";
-                desc = "Previous snippet node choice";
-              }
-              {
-                mode = "is";
-                mapping = "<c-f>";
-                action = "<Plug>luasnip-next-choice";
-                desc = "Next snippet node choice";
-              }
-            ];
-            # }}}
-          };
+                vim.schedule(function()
+                  luasnip.jump(1)
+                end)
+
+                return "<ignore>"
+              '';
+              desc = "Jump to next snippet tabstop";
+            }
+            {
+              mode = "i";
+              mapping = "<s-tab>";
+              action = thunk /* lua */ ''
+                require("luasnip").jump(-1)
+              '';
+              desc = "Jump to previous snippet tabstop";
+            }
+            {
+              mode = "is";
+              mapping = "<c-a>";
+              action = "<Plug>luasnip-prev-choice";
+              desc = "Previous snippet node choice";
+            }
+            {
+              mode = "is";
+              mapping = "<c-f>";
+              action = "<Plug>luasnip-next-choice";
+              desc = "Next snippet node choice";
+            }
+          ];
+          # }}}
+        };
         # }}}
         # {{{ miros
         # snippeting generation language
@@ -1145,7 +1154,6 @@ let
             "hrsh7th/cmp-cmdline"
             "hrsh7th/cmp-path"
             "saadparwaiz1/cmp_luasnip"
-            "dmitmel/cmp-digraphs"
             # }}}
             "onsails/lspkind.nvim" # show icons in lsp completion menus
             "luasnip"
@@ -1522,7 +1530,12 @@ let
     "lua/nix" "init"
     generated.lua);
 
-  extraRuntime = lib.concatStringsSep "," [ generatedConfig mirosSnippetCache ];
+  extraRuntime = lib.concatStringsSep "," [
+    generatedConfig
+    mirosSnippetCache
+    "${pkgs.vimPlugins.lazy-nvim}"
+  ];
+
   # }}}
   # {{{ Client wrapper
   # Wraps a neovim client, providing the dependencies
diff --git a/home/features/neovim/header.txt b/home/features/neovim/header.txt
new file mode 100644
index 0000000..6a733c8
--- /dev/null
+++ b/home/features/neovim/header.txt
@@ -0,0 +1,6 @@
+███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗       ██████╗
+████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║    ██╗╚════██╗
+██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║    ╚═╝ █████╔╝
+██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║    ██╗ ╚═══██╗
+██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║    ╚═╝██████╔╝
+╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝       ╚═════╝
diff --git a/home/features/neovim/plugins/cmp.lua b/home/features/neovim/plugins/cmp.lua
index ae66de7..cde2f82 100644
--- a/home/features/neovim/plugins/cmp.lua
+++ b/home/features/neovim/plugins/cmp.lua
@@ -60,7 +60,6 @@ function M.config()
       { name = "buffers" },
       { name = "emoji" },
       { name = "path" },
-      { name = "digraphs" },
     }),
     -- }}}
   }
diff --git a/home/features/neovim/plugins/ministarter.lua b/home/features/neovim/plugins/ministarter.lua
new file mode 100644
index 0000000..61c6b66
--- /dev/null
+++ b/home/features/neovim/plugins/ministarter.lua
@@ -0,0 +1,40 @@
+local M = {}
+
+local version = vim.version()
+local version_string = "🚀 "
+  .. version.major
+  .. "."
+  .. version.minor
+  .. "."
+  .. version.patch
+local lazy_stats = nil
+
+vim.api.nvim_create_autocmd("User", {
+  pattern = "LazyVimStarted",
+  callback = function()
+    local lazy_ok, lazy = pcall(require, "lazy")
+    if lazy_ok then
+      lazy_stats = {
+        total_plugins = lazy.stats().count .. " Plugins",
+        startup_time = math.floor(lazy.stats().startuptime * 100 + 0.5) / 100,
+      }
+
+      require("mini.starter").refresh()
+    end
+  end,
+})
+
+function M.lazy_stats_item()
+  if lazy_stats ~= nil then
+    return version_string
+      .. " —  🧰 "
+      .. lazy_stats.total_plugins
+      .. " —  🕐 "
+      .. lazy_stats.startup_time
+      .. "ms"
+  else
+    return version_string
+  end
+end
+
+return M
diff --git a/home/features/neovim/snippets/all.miros b/home/features/neovim/snippets/all.miros
new file mode 100644
index 0000000..3733563
--- /dev/null
+++ b/home/features/neovim/snippets/all.miros
@@ -0,0 +1,9 @@
+block auto
+  abbr tto ->
+  abbr ffrom <-
+  abbr iip =>
+  abbr iib <=
+  abbr leq <=
+  abbr geq >=
+  abbr land /\
+  abbr lor /\
diff --git a/home/features/neovim/snippets/purescript.miros b/home/features/neovim/snippets/purescript.miros
index 54e5ea7..abb002c 100644
--- a/home/features/neovim/snippets/purescript.miros
+++ b/home/features/neovim/snippets/purescript.miros
@@ -10,7 +10,7 @@ block start auto
   string @kind
     name @kind definition
     desc Define a @⟨@kind:type,newtype,adt⟩
-    snip data $1 = $2
+    snip @kind $1 = $2
 
   string example
     name example docstring
@@ -44,18 +44,17 @@ block start auto
   string derive
     name derive typeclass instance
     desc Derive a typeclass instance
-    snip
-      derive $|1⟨$1,newtype $1⟩instance $0
+    snip derive instance $|1⟨$1,newtype $1⟩instance $0
 
   for typeclass <- @⟨Eq,Ord,Functor⟩
   string d@⟨@typeclass:eq,ord,functor⟩
     name derive @typeclass
-    snip derive @typeclass $0
+    snip derive instance @typeclass $0
 
   for typeclass <- @⟨Newtype,Generic⟩
   string d@⟨@typeclass:newtype,generic⟩
     name derive @typeclass
-    snip derive @typeclass $1 _
+    snip derive instance @typeclass $1 _
 
   for typeclass <- @⟨Show,Debug⟩
   for lower <- @⟨@typeclass:show,debug⟩
diff --git a/home/features/neovim/snippets/tex.miros b/home/features/neovim/snippets/tex.miros
index 09c81da..bbd7849 100644
--- a/home/features/neovim/snippets/tex.miros
+++ b/home/features/neovim/snippets/tex.miros
@@ -1,11 +1,19 @@
 for thmenv <- @⟨theorem,lemma,exercise,definition,corollary,example⟩
 for thmprefix <- @⟨@thmenv:thm,lem,exe,def,cor,exa⟩
 
-block auto !math start
-  for env <- @⟨$1,enumerate,itemize,align*⟩
+block auto start
+  string begin
+    name environment
+    snip
+      \begin{$1}
+        $0
+      \end{$1}
 
-  string @⟨@env:begin,olist,ulist,dm⟩
-    name @⟨@env:environment,ordered list,unordered list,display math⟩
+block auto !math start
+  for env <- @⟨enumerate,itemize,align*⟩
+
+  string @⟨@env:olist,ulist,dm⟩
+    name @⟨@env:ordered list,unordered list,display math⟩
     snip
       \begin{@env}
         $0
@@ -84,10 +92,12 @@ block math
         $7 & $8 & $9
       \end{@matenv}
 
-  for operator <- @⟨eq,neq,leq,geq,lt,gt⟩
-  for symbol <- @⟨@operator:=,\neq,\leq,\geq,<,>⟩
+  for operator <- @⟨eq,neq,defas,leq,geq,lt,gt,iip,iib⟩
+  for symbol <- @⟨@operator:=,\neq,\coloneq,\leq,\geq,<,>,\implies,\impliedby⟩
 
   block auto
+    abbr @operator @symbol
+
     string a@operator
       name align at @operator
       snip &@symbol $0
@@ -147,19 +157,45 @@ block math
         ⟩}}$0
 
   block auto
-    for constant <- @⟨star,delta,Delta,pi,tau,psi,phi,rho,sigma,alpha,beta,theta,gamma,omega,Omega⟩
-    string @constant
-      snip \\@constant
+    for constkind <- @⟨default,shortened⟩
+    for constant <- @⟨@constkind:
+      @⟨star,delta,Delta,pi,tau,psi,phi,rho,sigma,alpha,beta,theta,gamma,omega,Omega,half,ordop,land,lor⟩,
+      @⟨lam,eps,iinf⟩
+    ⟩
+    for expansion <- @⟨@constkind:
+      @constant,
+      @⟨@constant:lambda,epsilon,ifty⟩
+    ⟩
 
-    for shortconstant <- @⟨eps,lam⟩
-    string @shortconstant
-      snip \\@⟨@shortconstant:epsilon,lambda⟩
+    for operator <- @⟨,e,s⟩
+    string @operator@constant
+      snip @⟨@operator:,^,_⟩\\@expansion
 
-    for operator <- @⟨overline,hat,abs,norm,prob,diprod,sin,cos,sqrt,ln,lrb,zmod⟩
+    abbr niinf -\ifty
+    abbr eniinf ^{-\ifty}
+    abbr sniinf _{-\ifty}
+
+    abbr frl \forall
+    abbr exs \exists
+    abbr nin \not\in
+    abbr ccup \cup
+    abbr ccap \cap
+    abbr nope \bot
+    abbr yee \top
+
+    abbr nlnl \pm
+    abbr vsm \vecspace
+    abbr oball \ball
+
+    for noperator <- @⟨ordop,land,lor⟩
+    string @noperator
+      snip \\@noperator
+
+    for operator <- @⟨overline,hat,bar,abs,norm,prob,diprod,sin,cos,sqrt,ln,lrb,zmod,gen,diam,prob⟩
     string @operator
       snip \\@operator$|1⟨{$1}, $0⟩
 
-    for bioperator <- @⟨iprod,frac,binom⟩
+    for bioperator <- @⟨iprod,frac,binom,dist⟩
     string @bioperator
       snip \\@bioperator$|1⟨ $1,{$1}⟩$|2⟨ $2,{$2}⟩ $0
 
@@ -167,25 +203,33 @@ block math
       desc Create a set by escaping the brackets
       snip \{$1\}
 
-    pattern e([%a%d])
+    pattern (.*)e@⟨t(%a),(%d)⟩
       name auto exponent
-      snip ^@0
+      snip @0^@1 $0
 
-    pattern s([%a%d])
+    pattern (.*)so(%a)
       name auto subscript
-      snip _@0
+      snip @0_@1 $0
 
     pattern (\?[%a]+)(%d)
       name auto digt subscript
-      snip @0_@1
+      snip @0_@1 $0
 
     string ss
       name subscript
-      snip _{$1}$0
+      snip _{$1} $0
 
     string ee
       name exponent
-      snip ^{$1}$0
+      snip ^{$1} $0
+
+    pattern (%a)(.)pp
+      name auto parenthesis
+      snip @0(@1) $0
+
+    pattern (%a)d(.)p
+      name auto parenthesis
+      snip @0'(@1) $0
 
     for limtarget <- @⟨anything,zero,infinity,negative infinity⟩
     for prefix <- @⟨@limtarget:,z,i,n⟩
diff --git a/hosts/nixos/lapetus/services/homer.nix b/hosts/nixos/lapetus/services/homer.nix
index a3352df..3f21276 100644
--- a/hosts/nixos/lapetus/services/homer.nix
+++ b/hosts/nixos/lapetus/services/homer.nix
@@ -147,6 +147,32 @@ in
             ];
           }
           # }}}
+          # {{{ External
+          {
+            name = "External";
+            icon = fa "arrow-up-right-from-square";
+            items = [
+              {
+                name = "Dotfiles";
+                subtitle = "Configuration for all my machines";
+                logo = icon "github.png";
+                url = "https://github.com/mateiadrielrafael/everything-nix";
+              }
+              {
+                name = "Tailscale";
+                subtitle = "Access this homelab from anywhere";
+                logo = icon "tailscale.png";
+                url = "https://tailscale.com/";
+              }
+              {
+                name = "Porkbun";
+                subtitle = "Domain management";
+                logo = icon "porkbun.png";
+                url = "https://porkbun.com/account/domainsSpeedy";
+              }
+            ];
+          }
+          # }}}
         ];
       };
     });
diff --git a/hosts/nixos/lapetus/services/whoogle.nix b/hosts/nixos/lapetus/services/whoogle.nix
index bad9943..9bda465 100644
--- a/hosts/nixos/lapetus/services/whoogle.nix
+++ b/hosts/nixos/lapetus/services/whoogle.nix
@@ -29,6 +29,9 @@ in
       WHOOGLE_CONFIG_DISABLE = "0";
       WHOOGLE_CONFIG_BLOCK = lib.concatStringsSep "," websiteBlocklist;
       WHOOGLE_CONFIG_THEME = "system";
+      WHOOGLE_ALT_WIKI = ""; # disable redirecting wikipedia links
+      WHOOGLE_ALT_RD = "redlib.moonythm.dev";
+      WHOOGLE_ALT_YT = "yt.moonythm.dev";
     };
   };
 
diff --git a/modules/common/korora-lua.nix b/modules/common/korora-lua.nix
index a20f699..f95e1d8 100644
--- a/modules/common/korora-lua.nix
+++ b/modules/common/korora-lua.nix
@@ -81,21 +81,26 @@ let
         }
       '';
 
-    encodeString = given: ''"${lib.escape ["\"" "\\"] (toString given)}"'';
+    encodeString = given:
+      if lib.hasInfix "\n" given then
+        ''[[${(toString given)}]]'' # This is not perfect but oh well
+      else
+        ''"${lib.escape ["\"" "\\"] (toString given)}"'';
 
     mkAttrName = s:
       let
-        # These list *are* incomplete
-        forbiddenChars = lib.stringToCharacters "<>[]{}()'\".,:;\\/*_";
+        # A "good enough" approach to figuring out the correct encoding for attribute names
+        allowedStartingChars = lib.stringToCharacters "abcdefghijklmnopqrstuvwxyz_";
+        allowedChars = allowedStartingChars ++ lib.stringToCharacters "0123456789";
         keywords = [ "if" "then" "else" "do" "for" "local" "" ];
       in
-      if lib.any (c: lib.hasInfix c s) forbiddenChars || lib.elem s keywords then
+      if builtins.match "([a-zA-Z_][a-zA-Z_0-9]*)" s != [ s ] || lib.elem s keywords then
         "[${helpers.encodeString s}]"
       else s;
     # }}}
   };
   # }}}
-  # {{{ This function takes a nix value and encodes it to a lua string.
+  # {{{ Encoding
   isLuaLiteral = given: lib.isAttrs given && given.__luaEncoderTag or null == "lua";
   encodeWithDepth = depth: given:
     let recurse = encodeWithDepth depth; in