about summary refs log tree commit diff stats
path: root/modules/by-name/nv/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/nv/nvim')
-rw-r--r--modules/by-name/nv/nvim/autocmds/default.nix133
-rw-r--r--modules/by-name/nv/nvim/clipboard/default.nix13
-rw-r--r--modules/by-name/nv/nvim/files/default.nix15
-rw-r--r--modules/by-name/nv/nvim/files/ftplugin/tex.lua60
-rw-r--r--modules/by-name/nv/nvim/mappings/default.nix306
-rw-r--r--modules/by-name/nv/nvim/module.nix69
-rw-r--r--modules/by-name/nv/nvim/options/default.nix110
-rw-r--r--modules/by-name/nv/nvim/plgs/colorscheme/default.nix20
-rw-r--r--modules/by-name/nv/nvim/plgs/colorscheme/lua/mk_todos_readable.lua16
-rw-r--r--modules/by-name/nv/nvim/plgs/colorscheme/lua/nightfox.lua44
-rw-r--r--modules/by-name/nv/nvim/plgs/comment-nvim/default.nix47
-rw-r--r--modules/by-name/nv/nvim/plgs/debugprint/default.nix73
-rw-r--r--modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua3
-rw-r--r--modules/by-name/nv/nvim/plgs/default.nix33
-rw-r--r--modules/by-name/nv/nvim/plgs/femaco/default.nix26
-rw-r--r--modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua51
-rw-r--r--modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix23
-rw-r--r--modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua104
-rw-r--r--modules/by-name/nv/nvim/plgs/goto-preview/default.nix50
-rw-r--r--modules/by-name/nv/nvim/plgs/goto-preview/lua/goto-preview.lua21
-rw-r--r--modules/by-name/nv/nvim/plgs/harpoon/default.nix100
-rw-r--r--modules/by-name/nv/nvim/plgs/leap/default.nix65
-rw-r--r--modules/by-name/nv/nvim/plgs/lf-nvim/default.nix21
-rw-r--r--modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua43
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix53
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua146
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/default.nix35
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/keymaps/default.nix76
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/default.nix15
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/bashls.nix11
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/ccls.nix11
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/ltex.nix45
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/lua-ls.nix14
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/nil-ls.nix16
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/openscad.nix24
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix19
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/quick-lint-js.nix22
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/ruff-lsp.nix17
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/rust-analyzer.nix23
-rw-r--r--modules/by-name/nv/nvim/plgs/lsp/servers/servers/texlab.nix13
-rw-r--r--modules/by-name/nv/nvim/plgs/lspkind/default.nix12
-rw-r--r--modules/by-name/nv/nvim/plgs/ltex_extra/default.nix16
-rw-r--r--modules/by-name/nv/nvim/plgs/ltex_extra/lua/ltex_extra.lua16
-rw-r--r--modules/by-name/nv/nvim/plgs/lualine/default.nix128
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/default.nix23
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/luasnip.lua7
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua211
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/html/html.lua102
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua28
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/greek.lua37
-rw-r--r--modules/by-name/nv/nvim/plgs/neorg/default.nix70
-rw-r--r--modules/by-name/nv/nvim/plgs/nvim-cmp/default.nix53
-rw-r--r--modules/by-name/nv/nvim/plgs/nvim-lint/default.nix18
-rw-r--r--modules/by-name/nv/nvim/plgs/nvim-lint/lua/nvim-lint.lua18
-rw-r--r--modules/by-name/nv/nvim/plgs/raw_plugins/default.nix17
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/default.nix23
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/defaults/default.nix36
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix24
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/default.nix9
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/frecency/default.nix28
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/fzy-native/default.nix11
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/default.nix13
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/lua/rooter.lua76
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/symbols/default.nix59
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/keymaps/default.nix16
-rw-r--r--modules/by-name/nv/nvim/plgs/todo-comments/default.nix57
-rw-r--r--modules/by-name/nv/nvim/plgs/treesitter/default.nix63
-rw-r--r--modules/by-name/nv/nvim/plgs/vim-tex/default.nix75
-rw-r--r--modules/by-name/nv/nvim/plgs/which-key/default.nix11
69 files changed, 3243 insertions, 0 deletions
diff --git a/modules/by-name/nv/nvim/autocmds/default.nix b/modules/by-name/nv/nvim/autocmds/default.nix
new file mode 100644
index 00000000..54fd6831
--- /dev/null
+++ b/modules/by-name/nv/nvim/autocmds/default.nix
@@ -0,0 +1,133 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  config.home-manager.users.soispha = lib.mkIf cfg.enable {
+    programs.nixvim = {
+      autoGroups = {
+        cursor_off = {clear = true;};
+        colorcolumn_toggle = {clear = true;};
+        numbertoggle = {clear = true;};
+        coloroverride = {clear = true;};
+        highlight_on_yank = {clear = true;};
+        create_dir = {clear = true;};
+      };
+
+      autoCmd = [
+        {
+          # Taken from: https://github.com/jghauser/mkdir.nvim
+          event = ["BufWritePre"];
+          pattern = ["*"];
+          callback = {
+            __raw = ''
+              function()
+                -- Get current filename, get full path (:p) and leave only the head (:h)
+                local dir = vim.fn.expand('<afile>:p:h')
+
+                -- This handles URLs using netrw. See ':help netrw-transparent' for details.
+                if dir:find('%l+://') == 1 then
+                  return
+                end
+
+                if vim.fn.isdirectory(dir) == 0 then
+                  vim.fn.mkdir(dir, 'p')
+                end
+              end
+            '';
+          };
+          group = "create_dir";
+          desc = "Create the directory of the target file on write";
+        }
+        {
+          event = ["TextYankPost"];
+          pattern = ["*"];
+          callback = {
+            __raw = ''
+              function()
+                vim.highlight.on_yank()
+              end
+            '';
+          };
+          group = "highlight_on_yank";
+          desc = "Highlight the yanked text";
+        }
+        {
+          event = ["BufWritePre"];
+          pattern = ["*"];
+          command = ''
+            ks | if search("\\s\\+$", 'n') != 0 | :%s/\s\+$// | endif | 's
+          '';
+          desc = ''
+            Remove trailing whitespace on safe
+            :%s/\s\+$\| \+\ze\t//g >> For trailing spaces and spaces before tabstops
+          '';
+        }
+
+        {
+          event = ["WinLeave"];
+          pattern = ["*"];
+          command = "set nocursorline"; # TODO: possible also nocursorcolumn
+          group = "cursor_off";
+          desc = "Display cursorline and cursorcolumn ONLY in active window.";
+        }
+        {
+          event = ["WinEnter"];
+          pattern = ["*"];
+          command = "set cursorline"; # TODO: possible also cursorcolumn
+          group = "cursor_off";
+          desc = "Display cursorline and cursorcolumn ONLY in active window.";
+        }
+
+        {
+          event = ["InsertEnter"];
+          pattern = ["*"];
+          command = "set colorcolumn=${config.home-manager.users.soispha.programs.nixvim.opts.colorcolumn}";
+          group = "colorcolumn_toggle";
+          desc = "Only activate the colorcolumn when focused";
+        }
+        {
+          event = ["BufLeave" "FocusLost" "InsertLeave" "WinLeave"];
+          pattern = ["*"];
+          command = "set colorcolumn=0";
+          group = "colorcolumn_toggle";
+          desc = "Only activate the colorcolumn when focused";
+        }
+
+        {
+          event = ["BufEnter" "FocusGained" "InsertLeave" "WinEnter"];
+          pattern = ["*"];
+          command = "if &nu && mode() != \"i\" | set rnu   | endif";
+          group = "numbertoggle";
+          desc = "Change line numbers, when not focused";
+        }
+        {
+          event = ["BufLeave" "FocusLost" "InsertEnter" "WinLeave"];
+          pattern = ["*"];
+          command = "if &nu | set nornu | endif";
+          group = "numbertoggle";
+          desc = "Change line numbers, when not focused";
+        }
+
+        {
+          # Override LineNr
+          event = ["ColorScheme"];
+          pattern = ["*"];
+          command = "highlight LineNr  ctermfg=DarkGrey guifg=DarkGrey ";
+          group = "coloroverride";
+          desc = "Changes Line number colors";
+        }
+        {
+          # Override CursorLineNr
+          event = ["ColorScheme"];
+          pattern = ["*"];
+          command = "highlight CursorLineNr  ctermfg=White guifg=White ";
+          group = "coloroverride";
+          desc = "Changes Line number colors";
+        }
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/clipboard/default.nix b/modules/by-name/nv/nvim/clipboard/default.nix
new file mode 100644
index 00000000..4cc3bd8a
--- /dev/null
+++ b/modules/by-name/nv/nvim/clipboard/default.nix
@@ -0,0 +1,13 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    clipboard.providers = {
+      wl-copy.enable = true;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/files/default.nix b/modules/by-name/nv/nvim/files/default.nix
new file mode 100644
index 00000000..ef8afa1a
--- /dev/null
+++ b/modules/by-name/nv/nvim/files/default.nix
@@ -0,0 +1,15 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraFiles = {
+      "ftplugin/tex.lua".text = ''
+        ${lib.strings.fileContents ./ftplugin/tex.lua}
+      '';
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/files/ftplugin/tex.lua b/modules/by-name/nv/nvim/files/ftplugin/tex.lua
new file mode 100644
index 00000000..4107a7c5
--- /dev/null
+++ b/modules/by-name/nv/nvim/files/ftplugin/tex.lua
@@ -0,0 +1,60 @@
+-- local used = false;
+-- vim.keymap.set('n', '<leader>t', function()
+--     used = not used;
+--     if used then
+--         require('nvim-treesitter.configs').setup {
+--             highlight = {
+--                 additional_vim_regex_highlighting = { "latex", "markdown" },
+--             },
+--         }
+--     else
+--         require('nvim-treesitter.configs').setup {
+--             highlight = {
+--                 additional_vim_regex_highlighting = { "" },
+--             },
+--         }
+--     end
+-- end
+-- );
+--
+--
+
+-- Set tex specific telescope extension
+require("telescope").setup({
+  extensions = {
+    bibtex = {
+      -- Depth for the *.bib file
+      depth = 1,
+      -- Path to global bibliographies (placed outside of the project)
+      global_files = {},
+      -- Define the search keys to use in the picker
+      search_keys = { "author", "year", "title" },
+      -- Template for the formatted citation
+      citation_format = "{{author}} ({{year}}), {{title}}.",
+      -- Only use initials for the authors first name
+      citation_trim_firstname = true,
+      -- Max number of authors to write in the formatted citation
+      -- following authors will be replaced by "et al."
+      citation_max_auth = 2,
+      -- Wrapping in the preview window is disabled by default
+      wrap = false,
+      -- Custom format for citation label
+      custom_formats = {
+        { id = "tex_autocite", cite_marker = "\\autocite{%s}" },
+      },
+      format = "tex_autocite",
+      -- Use context awareness
+      context = true,
+      -- Fallback to global/directory .bib files if context not found
+      -- This setting has no effect if context = false
+      context_fallback = true,
+    },
+  },
+})
+require("telescope").load_extension("bibtex")
+vim.keymap.set(
+  "n",
+  "<leader>ib",
+  function() require("telescope").extensions.bibtex.bibtex() end,
+  { noremap = true, silent = true, desc = "list bibtex entries in telescope" }
+)
diff --git a/modules/by-name/nv/nvim/mappings/default.nix b/modules/by-name/nv/nvim/mappings/default.nix
new file mode 100644
index 00000000..4b6344c2
--- /dev/null
+++ b/modules/by-name/nv/nvim/mappings/default.nix
@@ -0,0 +1,306 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  config.home-manager.users.soispha = lib.mkIf cfg.enable {
+    programs.nixvim = {
+      globals = {
+        mapleader = " ";
+        maplocalleader = " ";
+      };
+      keymaps = [
+        {
+          mode = ["n" "i"];
+          key = "<Esc>";
+          action = "<cmd>noh<CR><Esc>";
+          options.desc = "Disable the search highlighting and send Escape";
+        }
+        {
+          key = "hh";
+          mode = ["i"];
+          action.__raw = ''
+            function()
+              local cmp = require('cmp');
+              local luasnip = require('luasnip');
+
+              if cmp.visible() then
+                  cmp.select_next_item()
+              elseif luasnip.expand_or_locally_jumpable() then
+                  luasnip.expand_or_jump()
+              end
+            end
+          '';
+          options.desc = "completion trigger/ forward in completen menu";
+        }
+        {
+          key = "uu";
+          mode = ["i"];
+          action.__raw = ''
+            function()
+              local cmp = require('cmp');
+              cmp.confirm()
+            end
+          '';
+          options.desc = "confirm the selected item";
+        }
+
+        {
+          key = "<C-Tab>";
+          action = "<cmd>tabnext<CR>";
+          options.desc = "cycle to the next tab";
+        }
+        {
+          key = "<S-C-Tab>";
+          action = "<cmd>tabprevious<CR>";
+          options.desc = "cycle to the previous tab";
+        }
+
+        # yank/ cut to the system clipboard
+        {
+          key = "<leader>y";
+          action = "\"+y";
+          options.desc = "yank to the system clipboard";
+        }
+        {
+          key = "<leader>Y";
+          action = "\"+Y";
+          options.desc = "yank until the end of the line to the system clipboard";
+        }
+
+        # Unmap some old keys
+        #{key = "s"; action = "'<Nop>'";}
+        #{key = "t"; action = "'<Nop>'";}
+        {
+          key = "<Up>";
+          action = "<Nop>";
+        }
+        {
+          key = "<Down>";
+          action = "<Nop>";
+        }
+        {
+          key = "<Left>";
+          action = "<Nop>";
+        }
+        {
+          key = "<Right>";
+          action = "<Nop>";
+        }
+
+        # Center the cursor vertically when moving to the next word during a search.
+        {
+          key = "l";
+          action = "nzzzv";
+          options.desc = "Center the cursor vertically when moving to the next word during a search.";
+        }
+        {
+          key = "L";
+          action = "Nzzzv";
+          options.desc = "Center the cursor vertically when moving to the next word during a search.";
+        }
+        # remap the other keys to dvorak
+        {
+          key = "k";
+          action = "t";
+          options.desc = "go the the right on char";
+        }
+        {
+          key = "K";
+          action = "T";
+          options.desc = "go to the left on char";
+        }
+        {
+          key = "j";
+          action = "k";
+          options.desc = "go to the right before the char";
+        }
+        {
+          key = "J";
+          action = "K";
+          options.desc = "go to the left before the char";
+        }
+
+        # Change Vim-keys
+        {
+          key = "h";
+          action = "<left>";
+          options.desc = "go left";
+        }
+        {
+          key = "t";
+          action = "g<down>";
+          options.desc = "go down, with displaylines";
+        }
+        {
+          key = "n";
+          action = "g<up>";
+          options.desc = "go up, with displaylines";
+        }
+        {
+          key = "s";
+          action = "<right>";
+          options.desc = "go right";
+        }
+
+        # Move display lines
+        {
+          key = "0";
+          action = "g0";
+          options.desc = "go to the leftmost character in the screen line";
+        }
+        {
+          key = "$";
+          action = "g$";
+          options.desc = "go to the rightmost character in the screen line";
+        }
+        {
+          mode = ["n"];
+          key = "<Enter>";
+          action = "gf";
+          options.desc = "open file/url under cursor";
+        }
+        {
+          mode = ["n"];
+          key = "<Tab>";
+          action = ":";
+          options.desc = "jump to command line";
+        }
+
+        {
+          mode = ["n"];
+          key = "\\f";
+          action.__raw = "function() require('lf').start() end";
+          options.desc = "open lf in a floating window";
+        }
+
+        # Splits
+        {
+          mode = ["n"];
+          key = "<C-t>";
+          action = "<C-w>p";
+          options.desc = "go to previous split";
+        }
+        {
+          mode = ["n"];
+          key = "<C-n>";
+          action = "<C-w>w";
+          options.desc = "go to next split";
+        }
+        {
+          mode = ["n"];
+          key = "<leader>-";
+          action = "<C-W>s";
+          options.desc = "New horizontal split";
+        }
+        {
+          mode = ["n"];
+          key = "<leader>|";
+          action = "<C-W>v";
+          options.desc = "New vertical split";
+        }
+
+        {
+          mode = ["n"];
+          key = "<leader>p";
+          action = "\"_dP";
+          options.desc = "keep the cut thing in the base register";
+        }
+        {
+          mode = ["n"];
+          key = "<leader>c";
+          action = "\"_c";
+          options.desc = "change without saving to register";
+        }
+
+        {
+          mode = ["n"];
+          key = "<leader>d";
+          action = "\"_d";
+          options.desc = "delete without saving to register";
+        }
+        {
+          key = "x";
+          mode = ["n"];
+          action.__raw = ''
+            function()
+              local col = vim.api.nvim_win_get_cursor(0)[2]
+              local char = vim.api.nvim_get_current_line():sub(col+1,col+1)
+              if char:match("%s") then
+                return '"_x'
+              else
+                return "x"
+              end
+            end
+          '';
+          options = {
+            desc = "Pipe all space only deletions to the blackhole register";
+            expr = true;
+            silent = true;
+          };
+        }
+        {
+          key = "dd";
+          mode = ["n"];
+          action.__raw = ''
+            function()
+              if vim.api.nvim_get_current_line():match("^%s*$") then
+                return '"_dd'
+              else
+                return "dd"
+              end
+            end
+          '';
+          options = {
+            desc = "Pipe all blank line deletions to the blackhole register";
+            expr = true;
+            silent = true;
+          };
+        }
+
+        {
+          mode = ["n"];
+          key = "<leader>s";
+          action = ":%s/\\<<C-r><C-w>\\>/<C-r><C-w>/gI<Left><Left><Left>";
+          options.desc = "replace for the word under the cursor";
+        }
+
+        {
+          mode = ["n"];
+          key = "<C-s>";
+          action = "<cmd>mksession! <CR>";
+          options.desc = "overwrite/create a session";
+        }
+
+        {
+          mode = ["n"];
+          key = "<leader>X";
+          action = "!!$SHELL <CR>";
+          options.desc = "Read the current line and execute that line in your $SHELL. The resulting output will replace the curent line that was being executed.";
+        }
+        {
+          mode = ["t"];
+          key = "<Esc><Esc>";
+          action = "<C-\\><C-n>";
+          options.desc = "Exit terminal mode with <Esc><Esc>";
+        }
+
+        # move selected lines in visual mode
+        {
+          mode = ["v"];
+          key = "T";
+          action = ":m '>+1<CR>gv=gv";
+          options.desc = "move selected lines in visual mode down";
+        }
+        {
+          mode = ["v"];
+          key = "N";
+          action = ":m '<-2<CR>gv=gv";
+          options.desc = "move selected lines in visual mode up";
+        }
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/module.nix b/modules/by-name/nv/nvim/module.nix
new file mode 100644
index 00000000..829a9c2b
--- /dev/null
+++ b/modules/by-name/nv/nvim/module.nix
@@ -0,0 +1,69 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  imports = [
+    ./autocmds
+    ./clipboard
+    ./files
+    ./mappings
+    ./options
+    ./plgs
+  ];
+
+  options.soispha.programs.nvim = {
+    enable = lib.mkEnableOption "custom nvim config";
+    shell = lib.mkOption {
+      type = lib.types.package;
+      description = "The package to use for the shell in :!";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        EDITOR = "nvim";
+        VISUAL = "nvim";
+        CODEEDITOR = "nvim";
+      };
+      programs.nixvim = {
+        enable = true;
+
+        # source: https://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Neovim
+        extraConfigLuaPre = lib.mkBefore ''
+          ---------------------------------------------------------------------------
+          --
+          --     ███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗
+          --     ████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║
+          --     ██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║
+          --     ██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║
+          --     ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║
+          --     ╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝
+          --
+          ---------------------------------------------------------------------------
+        '';
+
+        extraPackages = with pkgs; [
+          /*
+          These are mostly linters and formatters used for different file types.
+          Including them here is fine, as they are not necessarily-sync able to different people.
+          */
+          # nix
+          alejandra
+          statix
+
+          # yaml
+          yamllint
+
+          # shell
+          shellcheck
+          shfmt
+        ];
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/options/default.nix b/modules/by-name/nv/nvim/options/default.nix
new file mode 100644
index 00000000..72343b72
--- /dev/null
+++ b/modules/by-name/nv/nvim/options/default.nix
@@ -0,0 +1,110 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.opts = lib.mkIf cfg.enable {
+    autoindent = true; # copy indent from previous line
+    cindent = true; # use c like indenting rules
+    breakindent = true; # continue indent visually
+    showbreak = "↳ "; # downwards arrow with tip rightwards(U+21B3, UTF-8: E2 86 B3)
+    breakindentopt = {
+      shift = 2; # wrapped line's beginning will be shifted by the given number of
+    };
+
+    incsearch = true; # show search results while typing
+    inccommand = "split"; # line preview of :s results
+    ignorecase = true; # ignore case when searching
+    smartcase = true; # if a capital letter is used in search, overwrite ignorecase
+    showmatch = true; # show matching words during a search.
+    hlsearch = true; # highlight when searching
+
+    confirm = true; # confirm to save changes before closing modified buffer
+    colorcolumn = "+1"; # show a +1 before the 'textwidth'
+    completeopt = ["menuone" "noselect"]; # have a better completion experience
+
+    # https://www.compart.com/en/unicode/U+XXXX (unicode character code)
+    fillchars = {
+      fold = "·"; # MIDDLE DOT (U+00B7, UTF-8: C2 B7)
+      horiz = "━"; # BOX DRAWINGS HEAVY HORIZONTAL (U+2501, UTF-8: E2 94 81)
+      horizdown = "┳"; # BOX DRAWINGS HEAVY DOWN AND HORIZONTAL (U+2533, UTF-8: E2 94 B3)
+      horizup = "┻"; # BOX DRAWINGS HEAVY UP AND HORIZONTAL (U+253B, UTF-8: E2 94 BB)
+      vert = "┃"; # BOX DRAWINGS HEAVY VERTICAL (U+2503, UTF-8: E2 94 83)
+      vertleft = "┫"; # BOX DRAWINGS HEAVY VERTICAL AND LEFT (U+252B, UTF-8: E2 94 AB)
+      vertright = "┣"; # BOX DRAWINGS HEAVY VERTICAL AND RIGHT (U+2523, UTF-8: E2 94 A3)
+      verthoriz = "╋"; # BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL (U+254B, UTF-8: E2 95 8B)
+    };
+    listchars = builtins.concatStringsSep "," [
+      "nbsp:⦸" #  CIRCLED REVERSE SOLIDUS (U+29B8, UTF-8: E2 A6 B8)
+      "tab:▷┅" #  WHITE RIGHT-POINTING TRIANGLE (U+25B7, UTF-8: E2 96 B7)
+      "extends:»" #  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (U+00BB, UTF-8: C2 BB)
+      "precedes:«" #  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (U+00AB, UTF-8: C2 AB)
+      "trail:•" #  BULLET (U+2022, UTF-8: E2 80 A2)
+    ];
+
+    #  shell-like autocomplete to unambiguous portions
+    wildmode = builtins.concatStringsSep "," [
+      "longest"
+      "list"
+      "full"
+    ];
+
+    grepformat = "%f:%l:%c:%m"; # the default format for rg in vimgrep mode
+    grepprg = "rg --vimgrep"; # use rg as grep implementation in `:grep`
+
+    hidden = true; # allows you to hide buffers with unsaved changes without being prompted
+
+    laststatus = 3; # use global statusline # TODO:
+
+    list = true; # show whitespace
+
+    mouse = ""; # disables the mouse
+
+    number = true; # line numbers
+    relativenumber = true; # relative line numbers
+
+    # vim.opt.shada:append {'%'}; -- store buffers in the shada file and reopen them if nvim has been started without file name argument
+
+    shell = "${cfg.shell}";
+
+    spell = true; # activate spell checking
+    spelllang = "en_us,de_de"; # set spell languages
+    spelloptions = "camel"; # CamelCase check if both camel and case are correct words
+
+    syntax = "ON"; # use syntax highlighting and let nvim figure out which
+
+    shiftwidth = 0; # use tabstop setting as shiftwidth
+    tabstop = 4; # use 4 spaces in place of a tab
+    expandtab = true; # expand tabs to spaces
+
+    showtabline = 2; # always show the tabline
+
+    timeoutlen = 500; # wait 500 msec for the next char in an input sequence
+    ttyfast = true; # let vim know that I am using a fast term
+
+    undofile = true; # use a undofile, to save the undos
+    undolevels = 10000; # keep nearly all undo things stored
+
+    virtualedit = "block"; # allow the cursor to move beyond actual character in visual block mode
+
+    textwidth = 90; # automatically hard wrap at 90 columns by default
+
+    foldmethod = "marker"; # use markers to specify folds
+
+    termguicolors = true;
+    cursorline = true;
+    # vim.opt.cursorcolumn = true;
+
+    scrolloff = 999; # try to keep at least 999 lines above and below the cursor (this effectively keeps the screen centered)
+
+    linebreak = true; # break to long lines, but do only break them at [[::space::]]
+
+    showcmd = true; # show partial command, being typed
+    showmode = true; # show the mode (Visual, Insert, Command)
+
+    wildmenu = true; # shell completion
+    wildignore = "*.docx,*.jpg,*.png,*.gif,*.pdf,*.pyc,*.exe,*.flv,*.img,*.xlsx"; # ignore binary files
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/colorscheme/default.nix b/modules/by-name/nv/nvim/plgs/colorscheme/default.nix
new file mode 100644
index 00000000..ebc26826
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/colorscheme/default.nix
@@ -0,0 +1,20 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package nightfox though a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/nightfox.lua}
+      ${lib.strings.fileContents ./lua/mk_todos_readable.lua}
+    '';
+    colorscheme = "carbonfox";
+    extraPlugins = [
+      pkgs.vimPlugins.nightfox-nvim
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/colorscheme/lua/mk_todos_readable.lua b/modules/by-name/nv/nvim/plgs/colorscheme/lua/mk_todos_readable.lua
new file mode 100644
index 00000000..d02171b5
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/colorscheme/lua/mk_todos_readable.lua
@@ -0,0 +1,16 @@
+local opts = { bg = "NONE", bold = true }
+
+---@param hl_group string: The name of the hl group
+---@param extra_opts table: Extra options to pass to nvim_set_hl
+local set_hl = function(hl_group, extra_opts)
+  local local_opts = vim.deepcopy(opts)
+  for k, v in ipairs(extra_opts) do
+    local_opts[k] = v
+  end
+  vim.api.nvim_set_hl(0, hl_group, local_opts)
+end
+
+set_hl("@text.danger", { fg = "red" })
+set_hl("@text.note", { fg = "blue" })
+set_hl("@text.todo", { fg = "green" })
+set_hl("@text.warning", { fg = "yellow" })
diff --git a/modules/by-name/nv/nvim/plgs/colorscheme/lua/nightfox.lua b/modules/by-name/nv/nvim/plgs/colorscheme/lua/nightfox.lua
new file mode 100644
index 00000000..4c502153
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/colorscheme/lua/nightfox.lua
@@ -0,0 +1,44 @@
+require("nightfox").setup({
+  options = {
+    -- Compiled file's destination location
+    compile_path = vim.fn.stdpath("cache") .. "/nightfox",
+    compile_file_suffix = "_compiled", -- Compiled file suffix
+    transparent = true, -- Disable setting background
+    terminal_colors = true, -- Set terminal colors (vim.g.terminal_color_*) used in `:terminal`
+    dim_inactive = true, -- Non focused panes set to alternative background
+    module_default = true, -- Default enable value for modules
+    colorblind = {
+      enable = true, -- Enable colorblind support
+      simulate_only = false, -- Only show simulated colorblind colors and not diff shifted
+      severity = {
+        protan = 0.3, -- Severity [0,1] for protan (red)
+        deutan = 0.9, -- Severity [0,1] for deutan (green)
+        tritan = 0, -- Severity [0,1] for tritan (blue)
+      },
+    },
+    styles = { -- Style to be applied to different syntax groups
+      comments = "italic", -- Value is any valid attr-list value `:help attr-list`
+      conditionals = "NONE",
+      constants = "NONE",
+      functions = "bold",
+      keywords = "bold",
+      numbers = "NONE",
+      operators = "NONE",
+      strings = "NONE",
+      types = "NONE",
+      variables = "NONE",
+    },
+    inverse = { -- Inverse highlight for different types
+      match_paren = false,
+      visual = false,
+      search = false,
+    },
+    modules = { -- List of various plugins and additional options
+      diagnostic = { enable = true, background = false },
+      native_lsp = { enable = true, background = false },
+    },
+  },
+  palettes = {},
+  specs = {},
+  groups = {},
+})
diff --git a/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix b/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix
new file mode 100644
index 00000000..bd70c5c2
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix
@@ -0,0 +1,47 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.comment = {
+      enable = true;
+      settings = {
+        padding = true;
+        sticky = true;
+        mappings = {
+          basic = false;
+          extra = false;
+        };
+      };
+    };
+    keymaps = [
+      {
+        key = "gcc";
+        mode = "v";
+        action = "<Plug>(comment_toggle_linewise_visual)";
+        options.desc = "toggle the current line in a linewise comment";
+      }
+      {
+        key = "gbc";
+        mode = "v";
+        action = "<Plug>(comment_toggle_blockwise_visual)";
+        options.desc = "toggle the current line in a blockwise comment";
+      }
+      {
+        key = "gcc";
+        mode = "n";
+        action = "<Plug>(comment_toggle_linewise_current)";
+        options.desc = "toggle the current line in a linewise comment";
+      }
+      {
+        key = "gbc";
+        mode = "n";
+        action = "<Plug>(comment_toggle_blockwise_current)";
+        options.desc = "toggle the current line in a blockwise comment";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/debugprint/default.nix b/modules/by-name/nv/nvim/plgs/debugprint/default.nix
new file mode 100644
index 00000000..4a3af1c5
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/debugprint/default.nix
@@ -0,0 +1,73 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package debugprint though a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/debugprint.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimExtraPlugins.debugprint-nvim
+    ];
+
+    keymaps = [
+      {
+        key = "g?v";
+        mode = ["v" "n"];
+        action.__raw = ''
+          function()
+            return require('debugprint').debugprint({variable = true;});
+          end
+        '';
+        options.expr = true;
+        options.desc = ''
+          'variable' debug line below the current line
+        '';
+      }
+      {
+        key = "g?V";
+        mode = ["v" "n"];
+        action.__raw = ''
+          function()
+            return require('debugprint').debugprint({above = true; variable = true;}) ;
+          end
+        '';
+        options.expr = true;
+        options.desc = ''
+          'variable' debug line above the current line
+        '';
+      }
+      {
+        key = "g?p";
+        mode = "n";
+        action.__raw = ''
+          function()
+            return require('debugprint').debugprint();
+          end
+        '';
+        options.expr = true;
+        options.desc = ''
+          'plain' debug line below the current line
+        '';
+      }
+      {
+        key = "g?P";
+        mode = "n";
+        action.__raw = ''
+          function()
+            return require('debugprint').debugprint({above = true;});
+          end
+        '';
+        options.expr = true;
+        options.desc = ''
+          'plain' debug line above the current line
+        '';
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua b/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua
new file mode 100644
index 00000000..da7e1735
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua
@@ -0,0 +1,3 @@
+require("debugprint").setup({
+  create_keymaps = false,
+})
diff --git a/modules/by-name/nv/nvim/plgs/default.nix b/modules/by-name/nv/nvim/plgs/default.nix
new file mode 100644
index 00000000..991bc315
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/default.nix
@@ -0,0 +1,33 @@
+{...}: {
+  imports =
+    [
+      # Plugins not yet packaged in nixpkgs
+      # ./debugprint
+      ./lf-nvim
+      # ./lsp-progress-nvim
+    ]
+    ++ [
+      # Already packaged in nixpkgs
+      ./colorscheme
+      ./comment-nvim
+      ./femaco
+      ./flatten-nvim
+      ./goto-preview
+      ./harpoon
+      ./leap
+      ./lsp
+      ./lspkind
+      ./ltex_extra
+      ./lualine
+      ./luasnip
+      ./neorg
+      ./nvim-cmp
+      ./nvim-lint
+      ./raw_plugins
+      ./telescope
+      ./todo-comments
+      ./treesitter
+      ./vim-tex
+      ./which-key
+    ];
+}
diff --git a/modules/by-name/nv/nvim/plgs/femaco/default.nix b/modules/by-name/nv/nvim/plgs/femaco/default.nix
new file mode 100644
index 00000000..adf0ba63
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/femaco/default.nix
@@ -0,0 +1,26 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package femaco through a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/femaco.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimPlugins.nvim-FeMaco-lua
+    ];
+    keymaps = [
+      {
+        key = "<leader>cc";
+        mode = "n";
+        action.__raw = "require('femaco.edit').edit_code_block";
+        options.desc = "edit a [c]ode blo[c]k with femaco";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua b/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua
new file mode 100644
index 00000000..c113e4c7
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua
@@ -0,0 +1,51 @@
+local clip_val = require("femaco.utils").clip_val
+require("femaco").setup({
+  -- should prepare a new buffer and return the winid
+  -- by default opens a floating window
+  -- provide a different callback to change this behaviour
+  -- @param opts: the return value from float_opts
+  prepare_buffer = function(opts)
+    local buf = vim.api.nvim_create_buf(false, false)
+    return vim.api.nvim_open_win(buf, true, opts)
+  end,
+  -- should return options passed to nvim_open_win
+  -- @param code_block: data about the code-block with the keys
+  --   * range
+  --   * lines
+  --   * lang
+  float_opts = function(code_block)
+    return {
+      relative = "cursor",
+      width = clip_val(5, 120, vim.api.nvim_win_get_width(0) - 10), -- TODO: how to offset sign column etc?
+      height = clip_val(5, #code_block.lines, vim.api.nvim_win_get_height(0) - 6),
+      anchor = "NW",
+      row = 0,
+      col = 0,
+      style = "minimal",
+      border = "rounded",
+      zindex = 1,
+    }
+  end,
+  -- return filetype to use for a given lang
+  -- lang can be nil
+  ft_from_lang = function(lang) return lang end,
+  -- what to do after opening the float
+  post_open_float = function(winnr) vim.wo.signcolumn = "no" end,
+  -- create the path to a temporary file
+  create_tmp_filepath = function(filetype) return os.tmpname() end,
+  -- if a newline should always be used, useful for multiline injections
+  -- which separators needs to be on separate lines such as markdown, neorg etc
+  -- @param base_filetype: The filetype which FeMaco is called from, not the
+  -- filetype of the injected language (this is the current buffer so you can
+  -- get it from vim.bo.filetyp).
+  ensure_newline = function(base_filetype) return false end,
+  -- Return true if the indentation should be normalized. Useful when the
+  -- injected language inherits indentation from the construction scope (e.g. an
+  -- inline multiline sql string). If true, the leading indentation is detected,
+  -- stripped, and restored before/after editing.
+  --
+  -- @param base_filetype: The filetype which FeMaco is called from, not the
+  -- filetype of the injected language (this is the current buffer, so you can
+  -- get it from vim.bo.filetype).
+  normalize_indent = function(base_filetype) return false end,
+})
diff --git a/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix b/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix
new file mode 100644
index 00000000..c1ace4ac
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix
@@ -0,0 +1,23 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package flatten-nvim though a module
+
+    extraConfigLuaPre = ''
+      ${lib.strings.fileContents ./lua/flatten-nvim.lua}
+      if os.getenv("NVIM") ~= nil then
+        -- Avoid loading plugins because the host will take control of the instance anyways
+        return
+      end
+    '';
+    extraPlugins = [
+      pkgs.vimPlugins.flatten-nvim
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua b/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua
new file mode 100644
index 00000000..2cdbcdde
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua
@@ -0,0 +1,104 @@
+---Types:
+--
+-- Passed to callbacks that handle opening files
+---@alias BufInfo { fname: string, bufnr: buffer }
+--
+-- Needed aliases
+---@alias buffer integer: Buffer id
+---@alias window integer: Window id
+--
+-- The first argument is a list of BufInfo tables representing the newly opened files.
+-- The third argument is a single BufInfo table, only provided when a buffer is created from stdin.
+--
+-- IMPORTANT: For `block_for` to work, you need to return a buffer number OR a buffer number and a window number.
+--            The `winnr` return value is not required, `vim.fn.bufwinid(bufnr)` is used if it is not provided.
+--            The `filetype` of this buffer will determine whether block should happen or not.
+--
+---@alias OpenHandler fun(files: BufInfo[], argv: string[], stdin_buf: BufInfo, guest_cwd: string):window, buffer
+--
+require("flatten").setup({
+  callbacks = {
+    ---Called to determine if a nested session should wait for the host to close the file.
+    ---param argv: a list of all the arguments in the nested session
+    ---@type fun(argv: table): boolean
+    should_block = require("flatten").default_should_block,
+
+    ---If this returns true, the nested session will be opened.
+    ---If false, default behavior is used, and
+    ---config.nest_if_no_args is respected.
+    ---@type fun(host: channel):boolean
+    should_nest = require("flatten").default_should_nest,
+
+    ---Called before a nested session is opened.
+    pre_open = function() end,
+
+    ---Called after a nested session is opened.
+    ---@param bufnr buffer
+    ---@param winnr window
+    ---@param filetype string
+    ---@param is_blocking boolean
+    ---@param is_diff boolean
+    post_open = function(bufnr, winnr, filetype, is_blocking, is_diff)
+      -- If the file is a git commit, create one-shot autocmd to delete its buffer on write
+      if filetype == "gitcommit" or filetype == "gitrebase" then
+        vim.api.nvim_create_autocmd("BufWritePost", {
+          buffer = bufnr,
+          once = true,
+          callback = vim.schedule_wrap(function() vim.api.nvim_buf_delete(bufnr, {}) end),
+        })
+      end
+    end,
+
+    ---Called when a nested session is done waiting for the host.
+    ---@param filetype string
+    block_end = function(filetype) end,
+  },
+  -- <String, Bool> dictionary of filetypes that should be blocking
+  block_for = {
+    gitcommit = true,
+  },
+  -- Command passthrough
+  allow_cmd_passthrough = true,
+  -- Allow a nested session to open if Neovim is opened without arguments
+  nest_if_no_args = false,
+  -- Window options
+  window = {
+    -- Options:
+    -- current        -> open in current window (default)
+    -- alternate      -> open in alternate window (recommended)
+    -- tab            -> open in new tab
+    -- split          -> open in split
+    -- vsplit         -> open in vsplit
+    -- smart          -> smart open (avoids special buffers)
+    -- OpenHandler    -> allows you to handle file opening yourself (see Types)
+    --
+    -- TODO: Open gitcommit filetypes in the current buffer, everything else in a new tab <2023-08-29>
+    open = "split",
+
+    -- Options:
+    -- vsplit         -> opens files in diff vsplits
+    -- split          -> opens files in diff splits
+    -- tab_vsplit     -> creates a new tabpage, and opens diff vsplits
+    -- tab_split      -> creates a new tabpage, and opens diff splits
+    -- OpenHandler    -> allows you to handle file opening yourself (see Types)
+    diff = "tab_vsplit",
+
+    -- Affects which file gets focused when opening multiple at once
+    -- Options:
+    -- "first"        -> open first file of new files (default)
+    -- "last"         -> open last file of new files
+    focus = "first",
+  },
+  -- Override this function to use a different socket to connect to the host
+  -- On the host side this can return nil or the socket address.
+  -- On the guest side this should return the socket address
+  -- or a non-zero channel id from `sockconnect`
+  -- flatten.nvim will detect if the address refers to this instance of nvim, to determine if this is a host or a guest
+  pipe_path = require("flatten").default_pipe_path,
+  -- The `default_pipe_path` will treat the first nvim instance within a single kitty/wezterm session as the host
+  -- You can configure this behaviour using the following:
+  one_per = {
+    kitty = true, -- Flatten all instance in the current Kitty session
+    wezterm = true, -- Flatten all instance in the current Wezterm session
+  },
+})
diff --git a/modules/by-name/nv/nvim/plgs/goto-preview/default.nix b/modules/by-name/nv/nvim/plgs/goto-preview/default.nix
new file mode 100644
index 00000000..5c56fe8c
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/goto-preview/default.nix
@@ -0,0 +1,50 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package goto-preview though a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/goto-preview.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimPlugins.goto-preview
+    ];
+    keymaps = [
+      {
+        key = "<space>gd";
+        mode = "n";
+        action.__raw = "require('goto-preview').goto_preview_definition";
+        options.desc = "[G]oto [D]efinition";
+      }
+      {
+        key = "<space>gtd";
+        mode = "n";
+        action.__raw = "require('goto-preview').goto_preview_type_definition";
+        options.desc = "[G]oto the [t]ype [D]efinition";
+      }
+      {
+        key = "<space>gi";
+        mode = "n";
+        action.__raw = "require('goto-preview').goto_preview_implementation";
+        options.desc = "[G]oto [I]mplementations";
+      }
+      {
+        key = "<space>gr";
+        mode = "n";
+        action.__raw = "require('goto-preview').goto_preview_references";
+        options.desc = "[G]o to all [R]eferences of the symbol";
+      }
+      {
+        key = "\\<space>";
+        mode = "n";
+        action.__raw = "require('goto-preview').close_all_win";
+        options.desc = "close all preview windows";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/goto-preview/lua/goto-preview.lua b/modules/by-name/nv/nvim/plgs/goto-preview/lua/goto-preview.lua
new file mode 100644
index 00000000..9687a5a0
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/goto-preview/lua/goto-preview.lua
@@ -0,0 +1,21 @@
+require("goto-preview").setup({
+  width = 120, -- Width of the floating window
+  height = 15, -- Height of the floating window
+  border = { "↖", "─", "┐", "│", "┘", "─", "└", "│" }, -- Border characters of the floating window
+  default_mappings = false, -- Bind default mappings
+  debug = false, -- Print debug information
+  opacity = nil, -- 0-100 opacity level of the floating window where 100 is fully transparent.
+  resizing_mappings = false, -- Binds arrow keys to resizing the floating window.
+  post_open_hook = nil, -- A function taking two arguments, a buffer and a window to be ran as a hook.
+  post_close_hook = nil, -- A function taking two arguments, a buffer and a window to be ran as a hook.
+  references = { -- Configure the telescope UI for slowing the references cycling window.
+    telescope = {}, -- require("telescope.themes").get_dropdown({ hide_preview = false })
+  },
+  -- These two configs can also be passed down to the goto-preview definition and implementation calls for one off "peak" functionality.
+  focus_on_open = true, -- Focus the floating window when opening it.
+  dismiss_on_move = false, -- Dismiss the floating window when moving the cursor.
+  force_close = true, -- passed into vim.api.nvim_win_close's second argument. See :h nvim_win_close
+  bufhidden = "wipe", -- the bufhidden option to set on the floating window. See :h bufhidden
+  stack_floating_preview_windows = true, -- Whether to nest floating windows
+  preview_window_title = { enable = true, position = "left" }, -- Whether to set the preview window title as the filename
+})
diff --git a/modules/by-name/nv/nvim/plgs/harpoon/default.nix b/modules/by-name/nv/nvim/plgs/harpoon/default.nix
new file mode 100644
index 00000000..05a40d9f
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/harpoon/default.nix
@@ -0,0 +1,100 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  numbers = ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
+  mkNumberedCommand = {
+    command_template,
+    prefix,
+    number,
+    desc_template,
+  }: {
+    key = "${prefix}${number}";
+    action.__raw = ''
+      function()
+        ${command_template number}
+      end
+    '';
+    options.desc = "${desc_template number}";
+  };
+  mkGotoTerminalCommand = number: let
+    desc_template = number: "Goto terminal number ${number}";
+    command_template = number: ''require("harpoon.term").gotoTerminal(${number})'';
+    prefix = "gt";
+  in
+    mkNumberedCommand {inherit desc_template command_template prefix number;};
+  mkGotoFileCommand = number: let
+    desc_template = number: "Goto Buffer number ${number}";
+    command_template = number: ''require("harpoon.ui").nav_file(${number})'';
+    prefix = "gf";
+  in
+    mkNumberedCommand {inherit desc_template command_template prefix number;};
+
+  gotoTerminalMappings = builtins.map mkGotoTerminalCommand numbers;
+  gotoFileMappings = builtins.map mkGotoFileCommand numbers;
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.harpoon = {
+      enable = true;
+      package = pkgs.vimPlugins.harpoon;
+      enableTelescope = true;
+      # menu.width = "vim.api.nvim_win_get_width(0) - 4"; # TODO: integrate that
+      keymaps = {
+        tmuxGotoTerminal = null; # TODO:
+      };
+    };
+    keymaps =
+      [
+        {
+          key = "-";
+          action.__raw = ''
+            function()
+              require("harpoon.ui").nav_next()
+             end
+          '';
+          options.desc = "go to the next marked file";
+        }
+        {
+          key = "_";
+          action.__raw = ''
+            function()
+              require("harpoon.ui").nav_prev()
+             end
+          '';
+          options.desc = "go to the previous marked file";
+        }
+        {
+          key = "<leader><leader>";
+          action.__raw = ''
+            function()
+              require("harpoon.mark").add_file()
+            end
+          '';
+          options.desc = "add a mark to the open file in harpoon.";
+        }
+        {
+          key = "gqc";
+          action.__raw = ''
+            function()
+              require("harpoon.cmd-ui").toggle_quick_menu()
+            end
+          '';
+          options.desc = "toggle the harpoon command quick menu to see all commands.";
+        }
+        {
+          key = "<leader>q";
+          action.__raw = ''
+            function()
+              require("harpoon.ui").toggle_quick_menu()
+            end
+          '';
+          options.desc = "toggle the harpoon normal quick menu to see all marks.";
+        }
+      ]
+      ++ gotoFileMappings
+      ++ gotoTerminalMappings;
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/leap/default.nix b/modules/by-name/nv/nvim/plgs/leap/default.nix
new file mode 100644
index 00000000..57e78879
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/leap/default.nix
@@ -0,0 +1,65 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.leap = {
+      enable = true;
+      addDefaultMappings = false; # They don't work with dvorak.
+      safeLabels = [
+        "f"
+        "j"
+        "k"
+        "l"
+        "/"
+        "z"
+        "S"
+        "F"
+        "J"
+        "K"
+        "L"
+        "H"
+        "W"
+        "E"
+        "M"
+        "B"
+        "U"
+        "X"
+        "?"
+        "Z"
+      ];
+    };
+    keymaps = [
+      {
+        key = "j";
+        action = "<Plug>(leap-forward-to)";
+        options.desc = "jump forward to";
+      }
+      {
+        key = "J";
+        action = "<Plug>(leap-backward-to)";
+        options.desc = "jump backward to";
+      }
+      {
+        key = "gj";
+        action = "<Plug>(leap-from-window)";
+        options.desc = "jump to enterable windows";
+      }
+      /*
+            {key= "x";
+              mode = "v";
+              action = "<Plug>(leap-forward-till)";
+      options.desc = "leap forward till";
+            }
+            {key= "X";
+              mode = "v";
+              action = "<Plug>(leap-backward-till)";
+      options.desc = "leap backward till";
+            }
+      */
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix
new file mode 100644
index 00000000..5e2836b0
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix
@@ -0,0 +1,21 @@
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package lf-nvim though a module
+    # FIXME: change the nvim path, when I change the path with lf
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/lf-nvim.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimExtraPlugins.lf-nvim
+
+      pkgs.vimPlugins.toggleterm-nvim # required by lf-nvim
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua b/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua
new file mode 100644
index 00000000..1eadf375
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua
@@ -0,0 +1,43 @@
+local fn = vim.fn
+
+-- Defaults
+require("lf").setup({
+  default_action = "drop", -- default action when `Lf` opens a file
+  -- TODO: what do these mappings do?
+  default_actions = { -- default action keybindings
+    ["<C-t>"] = "tabedit",
+    ["<C-x>"] = "split",
+    ["<C-v>"] = "vsplit",
+    ["<C-o>"] = "tab drop",
+  },
+
+  winblend = 10, -- psuedotransparency level
+  dir = "", -- directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
+  direction = "float", -- window type: float horizontal vertical
+  border = "rounded", -- border kind: single double shadow curved
+  height = fn.float2nr(fn.round(0.75 * vim.o.lines)), -- height of the *floating* window
+  width = fn.float2nr(fn.round(0.75 * vim.o.columns)), -- width of the *floating* window
+  escape_quit = true, -- map escape to the quit command (so it doesn't go into a meta normal mode)
+  focus_on_open = true, -- focus the current file when opening Lf (experimental)
+  mappings = true, -- whether terminal buffer mapping is enabled
+  tmux = false, -- tmux statusline can be disabled on opening of Lf
+  default_file_manager = true, -- make lf default file manager
+  disable_netrw_warning = true, -- don't display a message when opening a directory with `default_file_manager` as true
+  highlights = { -- highlights passed to toggleterm
+    Normal = { link = "Normal" },
+    NormalFloat = { link = "Normal" },
+    FloatBorder = { guifg = "#cdcbe0", guibg = "#191726" },
+  },
+
+  -- Layout configurations
+  layout_mapping = "<M-u>", -- resize window with this key
+  views = { -- window dimensions to rotate through
+    { width = 0.800, height = 0.800 },
+    { width = 0.600, height = 0.600 },
+    { width = 0.950, height = 0.950 },
+    { width = 0.500, height = 0.500, col = 0, row = 0 },
+    { width = 0.500, height = 0.500, col = 0, row = 0.5 },
+    { width = 0.500, height = 0.500, col = 0.5, row = 0 },
+    { width = 0.500, height = 0.500, col = 0.5, row = 0.5 },
+  },
+})
diff --git a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix
new file mode 100644
index 00000000..1a2fb6eb
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix
@@ -0,0 +1,53 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package lsp-progress-nvim though a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/lsp-progress-nvim.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimExtraPlugins.lsp-progress-nvim
+    ];
+
+    # Status line setup
+    autoGroups.lsp_refresh.clear = true;
+    autoCmd = [
+      {
+        event = ["User LspProgressStatusUpdated"];
+        pattern = ["*"];
+        callback =
+          /*
+          lua
+          */
+          {
+            __raw = ''
+              require("lualine").refresh
+            '';
+          };
+        group = "lsp_refresh";
+        description = "Refresh the statusbar when the lsp status was updated.";
+      }
+    ];
+    plugins.lualine = let
+      get_lsp_progress = {
+        __raw =
+          /*
+          lua
+          */
+          ''
+            require('lsp-progress').progress
+          '';
+      };
+    in {
+      sections = {
+        lualine_c = [{name = get_lsp_progress;}];
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua
new file mode 100644
index 00000000..5a2cff26
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua
@@ -0,0 +1,146 @@
+--- @type table<string, any>
+require("lsp-progress").setup({
+  -- Spinning icons.
+  --
+  --- @type string[]
+  spinner = { "⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷" },
+
+  -- Spinning update time in milliseconds.
+  --
+  --- @type integer
+  spin_update_time = 200,
+
+  -- Last message cached decay time in milliseconds.
+  --
+  -- Message could be really fast(appear and disappear in an
+  -- instant) that user cannot even see it, thus we cache the last message
+  -- for a while for user view.
+  --
+  --- @type integer
+  decay = 700,
+
+  -- User event name.
+  --
+  --- @type string
+  event = "LspProgressStatusUpdated",
+
+  -- Event update time limit in milliseconds.
+  --
+  -- Sometimes progress handler could emit many events in an instant, while
+  -- refreshing statusline cause too heavy synchronized IO, so we limit the
+  -- event rate to reduce this cost.
+  --
+  --- @type integer
+  event_update_time_limit = 100,
+
+  -- Max progress string length, by default -1 is unlimited.
+  --
+  --- @type integer
+  max_size = -1,
+
+  -- Regular internal update time.
+  --
+  -- Emit user event to update the lsp progress status, even there's no new
+  -- message.
+  --
+  --- @type integer
+  regular_internal_update_time = 500,
+
+  -- Disable emitting events on specific mode/filetype.
+  -- User events would interrupt insert mode, thus break which-key like plugins behaviour.
+  -- See:
+  --  * https://github.com/linrongbin16/lsp-progress.nvim/issues/50
+  --  * https://neovim.io/doc/user/builtin.html#mode()
+  --
+  --- @type table[]
+  disable_events_opts = { { mode = "i", filetype = "TelescopePrompt" } },
+
+  -- Format series message.
+  --
+  -- By default it looks like: `formatting isort (100%) - done`.
+  --
+  --- @param title string|nil
+  ---     Message title.
+  --- @param message string|nil
+  ---     Message body.
+  --- @param percentage number|nil
+  ---     Progress in percentage numbers: 0-100.
+  --- @param done boolean
+  ---     Indicate whether this series is the last one in progress.
+  --- @return string|nil messages
+  ---     The returned value will be passed to function `client_format` as
+  ---     one of the `series_messages` array, or ignored if return nil.
+  series_format = function(title, message, percentage, done)
+    local builder = {}
+    local has_title = false
+    local has_message = false
+    if title and title ~= "" then
+      table.insert(builder, title)
+      has_title = true
+    end
+    if message and message ~= "" then
+      table.insert(builder, message)
+      has_message = true
+    end
+    if percentage and (has_title or has_message) then table.insert(builder, string.format("(%.0f%%%%)", percentage)) end
+    if done and (has_title or has_message) then table.insert(builder, "- done") end
+    return table.concat(builder, " ")
+  end,
+
+  -- Format client message.
+  --
+  -- By default it looks like:
+  -- `[null-ls] ⣷ formatting isort (100%) - done, formatting black (50%)`.
+  --
+  --- @param client_name string
+  ---     Client name.
+  --- @param spinner string
+  ---     Spinner icon.
+  --- @param series_messages string[]|table[]
+  ---     Messages array.
+  --- @return string|nil messages
+  ---     The returned value will be passed to function `format` as one of the
+  ---     `client_messages` array, or ignored if return nil.
+  client_format = function(client_name, spinner, series_messages)
+    return #series_messages > 0
+        and ("[" .. client_name .. "] " .. spinner .. " " .. table.concat(series_messages, ", "))
+      or nil
+  end,
+
+  -- Format (final) message.
+  --
+  -- By default it looks like:
+  -- ` LSP [null-ls] ⣷ formatting isort (100%) - done, formatting black (50%)`
+  --
+  --- @param client_messages string[]|table[]
+  ---     Client messages array.
+  --- @return nil|string message
+  ---     The returned value will be returned from `progress` API.
+  format = function(client_messages)
+    local sign = " LSP" -- nf-fa-gear \uf013
+    return #client_messages > 0 and (sign .. " " .. table.concat(client_messages, " ")) or sign
+  end,
+
+  -- Enable debug.
+  --
+  --- @type boolean
+  debug = false,
+
+  -- Print log to console(command line).
+  --
+  --- @type boolean
+  console_log = false,
+
+  -- Print log to file.
+  --
+  --- @type boolean
+  file_log = true,
+
+  -- Log file to write, work with `file_log=true`.
+  --
+  -- For Windows: `$env:USERPROFILE\AppData\Local\nvim-data\lsp-progress.log`.
+  -- For *NIX: `~/.local/share/nvim/lsp-progress.log`.
+  --
+  --- @type string
+  file_log_name = "lsp-progress.log",
+})
diff --git a/modules/by-name/nv/nvim/plgs/lsp/default.nix b/modules/by-name/nv/nvim/plgs/lsp/default.nix
new file mode 100644
index 00000000..d97f2f0a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/default.nix
@@ -0,0 +1,35 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  imports = [
+    ./keymaps
+    ./servers
+  ];
+  home-manager.users.soispha.programs.nixvim.plugins.lsp = lib.mkIf cfg.enable {
+    enable = true;
+    onAttach =
+      ""
+      #     + ''
+      #        function(client, bufnr)
+      #            -- Enable completion triggered by <c-x><c-o>
+      #            -- vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
+      #        end
+      #      ''
+      ;
+    preConfig = ''
+      vim.diagnostic.config({
+          underline = true,
+          -- virtual_text = true,
+          virtual_text = {
+              source = "always", -- Or "if_many"
+          },
+          update_in_insert = true,
+          severity_sort = true,
+      }, nil);
+    '';
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/keymaps/default.nix b/modules/by-name/nv/nvim/plgs/lsp/keymaps/default.nix
new file mode 100644
index 00000000..903e8c17
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/keymaps/default.nix
@@ -0,0 +1,76 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.lsp.keymaps = {
+      diagnostic = {
+        "N" = {
+          action = "goto_prev";
+          desc = "go to previous diagnostic message";
+        };
+        "T" = {
+          action = "goto_next";
+          desc = "go to next diagnostic message";
+        };
+        "<space>e" = {
+          action = "open_float";
+          desc = "open float for the symbol";
+        };
+        "<space>gq" = {
+          action = "setloclist";
+          desc = "add buffer diagnostic to the location list (quick-fix)";
+        };
+      };
+      lspBuf = {
+        "<space>gD" = {
+          action = "declaration";
+          desc = "[G]o to [d]eclaration";
+        };
+        "<space>hi" = {
+          action = "hover";
+          desc = "Display [h]over [i]nformation";
+        };
+        "<space>sh" = {
+          action = "signature_help";
+          desc = "Display [s]ignature [h]elp";
+        };
+        "<space>wa" = {
+          action = "add_workspace_folder";
+          desc = "[W]orkspace folder [a]dd";
+        };
+        "<space>wr" = {
+          action = "remove_workspace_folder";
+          desc = "[W]orkspace folder [r]emove";
+        };
+        "<space>rn" = {
+          action = "rename";
+          desc = "[R]e[n]ame the item under the cursor";
+        };
+        "<space>ca" = {
+          action = "code_action";
+          desc = "Open the [c]ode [a]ction menu";
+        };
+      };
+    };
+    keymaps = [
+      {
+        key = "<space>f";
+        action.__raw = "function() vim.lsp.buf.format { async = true } end";
+        options.desc = "[F]ormat the current buffer (asynchronously)";
+      }
+      {
+        key = "<space>wl";
+        action.__raw = ''
+          function()
+            print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
+          end
+        '';
+        options.desc = "[W]orkspace folders [l]ist";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix
new file mode 100644
index 00000000..605046d4
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix
@@ -0,0 +1,15 @@
+{...}: {
+  imports = [
+    # ./servers/pylyzer.nix
+    ./servers/bashls.nix
+    ./servers/ccls.nix
+    ./servers/quick-lint-js.nix
+    ./servers/ltex.nix
+    ./servers/lua-ls.nix
+    ./servers/nil-ls.nix
+    ./servers/openscad.nix
+    ./servers/ruff-lsp.nix
+    ./servers/rust-analyzer.nix
+    ./servers/texlab.nix
+  ];
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/bashls.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/bashls.nix
new file mode 100644
index 00000000..7d036a13
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/bashls.nix
@@ -0,0 +1,11 @@
+{
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    bashls.enable = true;
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ccls.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ccls.nix
new file mode 100644
index 00000000..cd7229bc
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ccls.nix
@@ -0,0 +1,11 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    ccls.enable = true;
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ltex.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ltex.nix
new file mode 100644
index 00000000..c89e0790
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ltex.nix
@@ -0,0 +1,45 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    ltex = let
+      filetypes = [
+        "java"
+        "cpp"
+        "shell"
+        "bash"
+
+        "bibtex"
+        "context"
+        "context.tex"
+        "latex"
+        "tex"
+
+        "markdown"
+        "org"
+        "restructuredtext"
+        "rsweave"
+
+        "git-commit"
+        "gitcommit"
+
+        "mail"
+      ];
+    in {
+      enable = true;
+      inherit filetypes;
+      settings = {
+        enabled = filetypes;
+        completionEnabled = false;
+        language = "en-CA";
+        additionalRules = {
+          enablePickyRules = true;
+        };
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/lua-ls.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/lua-ls.nix
new file mode 100644
index 00000000..f2e553f1
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/lua-ls.nix
@@ -0,0 +1,14 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    lua_ls = {
+      enable = true;
+      settings.telemetry.enable = false;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/nil-ls.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/nil-ls.nix
new file mode 100644
index 00000000..9c760345
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/nil-ls.nix
@@ -0,0 +1,16 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    nil_ls = {
+      enable = true;
+      settings = {
+        formatting.command = ["alejandra"];
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/openscad.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/openscad.nix
new file mode 100644
index 00000000..94f7b067
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/openscad.nix
@@ -0,0 +1,24 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraConfigLuaPost =
+      /*
+      lua
+      */
+      ''
+        require('lspconfig').openscad_lsp.setup{
+          cmd = {"openscad-lsp", "--stdio", "--fmt-style", "WebKit"},
+        }
+      '';
+    extraPackages = with pkgs; [
+      openscad-lsp
+      clang-tools # Need to satisfy `clang-format` (which is used by openscad-lsp)
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix
new file mode 100644
index 00000000..3ac66102
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix
@@ -0,0 +1,19 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraConfigLuaPost =
+      /*
+      lua
+      */
+      ''
+        require('lspconfig').pylyzer.setup{}
+      '';
+    extraPackages = with pkgs; [pylyzer];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/quick-lint-js.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/quick-lint-js.nix
new file mode 100644
index 00000000..48a3a71c
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/quick-lint-js.nix
@@ -0,0 +1,22 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraConfigLuaPost =
+      /*
+      lua
+      */
+      ''
+        require('lspconfig').quick_lint_js.setup{
+        }
+      '';
+    extraPackages = with pkgs; [
+      quick-lint-js
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ruff-lsp.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ruff-lsp.nix
new file mode 100644
index 00000000..41b3118a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/ruff-lsp.nix
@@ -0,0 +1,17 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.lsp.servers = {
+      ruff_lsp = {
+        enable = true;
+      };
+    };
+    extraPackages = with pkgs; [ruff];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/rust-analyzer.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/rust-analyzer.nix
new file mode 100644
index 00000000..01cd11f4
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/rust-analyzer.nix
@@ -0,0 +1,23 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    rust_analyzer = {
+      enable = true;
+      settings = {
+        typing.autoClosingAngleBrackets.enable = true;
+
+        # Check with `cargo clippy` instead of just `cargo check`
+        check.command = "clippy";
+      };
+      # NOTE: These should be provided by the devenv, to support nightly and
+      # such things <2023-11-25>
+      installCargo = false;
+      installRustc = false;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/texlab.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/texlab.nix
new file mode 100644
index 00000000..3f91beb5
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lsp/servers/servers/texlab.nix
@@ -0,0 +1,13 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lsp.servers = lib.mkIf cfg.enable {
+    texlab = {
+      enable = true;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/lspkind/default.nix b/modules/by-name/nv/nvim/plgs/lspkind/default.nix
new file mode 100644
index 00000000..078d607d
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lspkind/default.nix
@@ -0,0 +1,12 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lspkind = lib.mkIf cfg.enable {
+    enable = true;
+    preset = "default"; # "codicons" is only for a font patched with vscode-codeicons.
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/ltex_extra/default.nix b/modules/by-name/nv/nvim/plgs/ltex_extra/default.nix
new file mode 100644
index 00000000..c37a7591
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/ltex_extra/default.nix
@@ -0,0 +1,16 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package ltex_extra though a module
+    extraPlugins = [
+      pkgs.vimPlugins.ltex_extra-nvim
+    ];
+    plugins.lsp.servers.ltex.onAttach.function = builtins.readFile ./lua/ltex_extra.lua;
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/ltex_extra/lua/ltex_extra.lua b/modules/by-name/nv/nvim/plgs/ltex_extra/lua/ltex_extra.lua
new file mode 100644
index 00000000..d532428a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/ltex_extra/lua/ltex_extra.lua
@@ -0,0 +1,16 @@
+require("ltex_extra").setup({
+  -- table <string> : languages for witch dictionaries will be loaded, e.g. { "es-AR", "en-US" }
+  -- https://valentjn.github.io/ltex/supported-languages.html#natural-languages
+  load_langs = { "en-CA", "de-DE", "sv-SE" }, -- en-US as default
+  -- boolean : whether to load dictionaries on startup
+  init_check = true,
+  -- string : relative or absolute path to store dictionaries
+  -- e.g. subfolder in the project root or the current working directory: ".ltex"
+  -- e.g. shared files for all projects:  vim.fn.expand("~") .. "/.local/share/ltex"
+  path = vim.fn.expand("~") .. "/.local/state/nvim/ltex", -- project root or current working directory
+  -- string : "none", "trace", "debug", "info", "warn", "error", "fatal"
+  log_level = "warn",
+  -- table : configurations of the ltex language server.
+  -- Only if you are calling the server from ltex_extra
+  server_opts = nil,
+})
diff --git a/modules/by-name/nv/nvim/plgs/lualine/default.nix b/modules/by-name/nv/nvim/plgs/lualine/default.nix
new file mode 100644
index 00000000..2f3bb552
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/lualine/default.nix
@@ -0,0 +1,128 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.lualine = let
+    get_location_of_file = {
+      __raw = ''
+        function()
+            local file_lines = vim.fn.line('$');
+            local file_current_cursor_positon = vim.fn.getcurpos();
+            return file_current_cursor_positon[3] .. ":" .. file_current_cursor_positon[2] .. "/" .. file_lines
+        end
+      '';
+    };
+
+    get_trailing_whitespace = {
+      __raw = ''
+        function()
+            local space = vim.fn.search([[\s\+$]], 'nwc')
+            return space ~= 0 and "TW:" .. space or ""
+        end
+      '';
+    };
+    get_mixed_indent = {
+      __raw =
+        /*
+        lua
+        */
+        ''
+          function()
+              local space_pat = [[\v^ +]]
+              local tab_pat = [[\v^\t+]]
+              local space_indent = vim.fn.search(space_pat, 'nwc')
+              local tab_indent = vim.fn.search(tab_pat, 'nwc')
+              local mixed = (space_indent > 0 and tab_indent > 0)
+              local mixed_same_line
+              if not mixed then
+                  mixed_same_line = vim.fn.search([[\v^(\t+ | +\t)]], 'nwc')
+                  mixed = mixed_same_line > 0
+              end
+              if not mixed then return "" end
+              if mixed_same_line ~= nil and mixed_same_line > 0 then
+                  return 'MI:' .. mixed_same_line
+              end
+              local space_indent_cnt = vim.fn.searchcount({ pattern = space_pat, max_count = 1e3 }).total
+              local tab_indent_cnt = vim.fn.searchcount({ pattern = tab_pat, max_count = 1e3 }).total
+              if space_indent_cnt > tab_indent_cnt then
+                  return 'MI:' .. tab_indent
+              else
+                  return 'MI:' .. space_indent
+              end
+          end
+        '';
+    };
+  in
+    lib.mkIf cfg.enable {
+      enable = true;
+
+      settings = {
+        options = {
+          iconsEnabled = true;
+          theme = "nightfox";
+        };
+
+        # TODO: add all installed and supported extensions here
+        extensions = [
+          "toggleterm"
+          #"fugitive" # TODO: maybe add this?
+        ];
+
+        componentSeparators = {
+          left = "";
+          right = "";
+        };
+        sectionSeparators = {
+          left = "";
+          right = "";
+        };
+        disabledFiletypes = {
+          statusline = [];
+          winbar = [];
+        };
+        ignoreFocus = [];
+        alwaysDivideMiddle = true;
+        globalstatus = false;
+        refresh = {
+          statusline = 1000;
+          tabline = 1000;
+          winbar = 1000;
+        };
+        sections = {
+          lualine_a = ["mode"];
+          lualine_b = [
+            {
+              __raw = ''
+                {'FugitiveHead',  icon = ""}
+              '';
+            }
+            "diff"
+            "diagnostics"
+          ];
+          lualine_c = ["filename"];
+          lualine_x = ["searchcount" "filetype"];
+          lualine_y = [
+            "encoding"
+            "fileformat"
+            get_mixed_indent
+            get_trailing_whitespace
+          ];
+          lualine_z = [get_location_of_file];
+        };
+        inactiveSections = {
+          lualine_a = [];
+          lualine_b = [];
+          lualine_c = ["filename"];
+          lualine_x = [get_location_of_file];
+          lualine_y = [];
+          lualine_z = [];
+        };
+        tabline = {};
+        winbar = {};
+        inactiveWinbar = {};
+      };
+    };
+}
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/default.nix b/modules/by-name/nv/nvim/plgs/luasnip/default.nix
new file mode 100644
index 00000000..f67c9899
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/default.nix
@@ -0,0 +1,23 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    plugins.luasnip = {
+      enable = true;
+    };
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/luasnip.lua};
+      require("luasnip.loaders.from_lua").load({paths = "${./lua/snippets}"});
+      require("luasnip.loaders.from_lua").lazy_load({paths = "${./lua/snippets}"});
+    '';
+    extraPlugins = [
+      # needed for the todo-comments snippets
+      pkgs.vimPlugins.comment-nvim
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/luasnip.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/luasnip.lua
new file mode 100644
index 00000000..a05fa57f
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/luasnip.lua
@@ -0,0 +1,7 @@
+require("luasnip").config.set_config({
+  -- Enable auto triggered snippets
+  enable_autosnippets = true,
+
+  -- Use Tab (or some other key if you prefer) to trigger visual selection
+  store_selection_keys = "<Tab>",
+})
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua
new file mode 100644
index 00000000..2b923f20
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua
@@ -0,0 +1,211 @@
+local ls = require("luasnip")
+-- auto_pairs  {{{
+local get_visual = function(args, parent)
+  if #parent.snippet.env.SELECT_RAW > 0 then
+    return sn(nil, i(1, parent.snippet.env.SELECT_RAW))
+  else
+    return sn(nil, i(1, ""))
+  end
+end
+local function char_count_same(c1, c2)
+  local line = vim.api.nvim_get_current_line()
+  -- '%'-escape chars to force explicit match (gsub accepts patterns).
+  -- second return value is number of substitutions.
+  local _, ct1 = string.gsub(line, "%" .. c1, "")
+  local _, ct2 = string.gsub(line, "%" .. c2, "")
+  return ct1 == ct2
+end
+
+local function even_count(c, ...)
+  local line = vim.api.nvim_get_current_line()
+  local _, ct = string.gsub(line, c, "")
+  return ct % 2 == 0
+end
+
+-- This makes creation of pair-type snippets easier.
+local function pair(pair_begin, pair_end, file_types, condition_function)
+  -- FIXME(@Soispha): This only works if file_types == nil, otherwise the snippet does not expand.
+  -- It would be nice, if it would support both an empty array (`{}`) and nil <2023-08-27>
+  -- file_types = file_types or {};
+
+  return s(
+    { trig = pair_begin, wordTrig = false, snippetType = "autosnippet" },
+    { t({ pair_begin }), d(1, get_visual), t({ pair_end }) },
+    {
+      condition = function()
+        local filetype_check = true
+        if file_types ~= nil then filetype_check = file_types[vim.bo.filetype] or false end
+        return (not condition_function(pair_begin, pair_end)) and filetype_check
+      end,
+    }
+  )
+end
+
+local auto_pairs = {
+  pair("(", ")", nil, char_count_same),
+  pair("{", "}", nil, char_count_same),
+  pair("[", "]", nil, char_count_same),
+  pair("<", ">", { ["rust"] = true, ["tex"] = true }, char_count_same),
+  pair("'", "'", nil, even_count),
+  pair("\"", "\"", nil, even_count),
+  pair("`", "`", nil, even_count),
+}
+
+ls.add_snippets("all", auto_pairs, { type = "snippets", key = "auto_pairs" })
+-- }}}
+
+-- todo_comments {{{
+local calculate_comment_string = require("Comment.ft").calculate
+local utils = require("Comment.utils")
+
+local read_git_config = function(config_value)
+  local command = string.format("git config \"%s\"", config_value)
+  local handle = io.popen(command)
+  if handle == nil then return error(string.format("Failed to call `%s`.", command)) end
+  local result = handle:read("*a")
+  handle:close()
+  -- stripped = string.gsub(str, '%s+', '')
+  return string.gsub(result, "\n", "")
+end
+
+local name_to_handle = function(name)
+  -- from: https://stackoverflow.com/a/7615129
+  local split = function(inputstr, sep)
+    local t = {}
+    for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
+      table.insert(t, str)
+    end
+    return t
+  end
+
+  local parts = split(name, "%s")
+
+  local output_name = ""
+  if #parts > 2 then
+    for _, val in ipairs(parts) do
+      output_name = string.format("%s%s", output_name, val:sub(1, 1))
+    end
+  elseif #parts == 2 then
+    output_name = string.format("%s%s", parts[1]:sub(1, 1), parts[2])
+  elseif #parts == 1 then
+    output_name = parts[1]
+  else
+    -- parts is 0
+    output_name = "<NoName>"
+  end
+  return string.format("@%s", output_name:lower())
+end
+
+_G.luasnip = {}
+_G.luasnip.vars = {
+  username = function() return name_to_handle(read_git_config("user.name")) end,
+  email = function() return read_git_config("user.email") end,
+}
+
+--- Get the comment string {beg,end} table
+---@param ctype integer 1 for `line`-comment and 2 for `block`-comment
+---@return table comment_strings {begcstring, endcstring}
+local get_cstring = function(ctype)
+  -- use the `Comments.nvim` API to fetch the comment string for the region (eq. '--%s' or '--[[%s]]' for `lua`)
+  local cstring = calculate_comment_string({ ctype = ctype, range = utils.get_region() }) or vim.bo.commentstring
+  -- as we want only the strings themselves and not strings ready for using `format` we want to split the left and right side
+  local left, right = utils.unwrap_cstr(cstring)
+  -- create a `{left, right}` table for it
+  return { left, right }
+end
+
+--- Options for marks to be used in a TODO comment
+---@return table,table: The first table contains a node for the date, the second for the signature
+local marks = {
+  signature = function() return t("(" .. _G.luasnip.vars:username() .. ")"), t("") end,
+  date_signature = function() return t("<" .. os.date("%Y-%m-%d") .. ">"), t("(" .. _G.luasnip.vars:username() .. ")") end,
+  date = function() return t("<" .. os.date("%Y-%m-%d") .. ">"), t("") end,
+  empty = function() return t(""), t("") end,
+}
+
+---@param alias string
+---@param opts table
+---@param mark_function function: This function should return two nodes
+---@return table: Returns the comment node
+local todo_snippet_nodes = function(alias, opts, mark_function)
+  local date_node, signature_node = mark_function()
+  -- format them into the actual snippet
+  local comment_node = fmta("<> <><>: <> <> <>", {
+    f(function()
+      return get_cstring(opts.ctype)[1] -- get <comment-string[1]>
+    end),
+    t(alias), -- [name-of-comment]
+    signature_node,
+    i(0), -- {comment-text}
+    date_node,
+    f(function()
+      return get_cstring(opts.ctype)[2] -- get <comment-string[2]>
+    end),
+  })
+  return comment_node
+end
+
+--- Generate a TODO comment snippet with an automatic description and docstring
+---@param context table merged with the generated context table `trig` must be specified
+---@param alias string of aliases for the todo comment (ex.: {FIX, ISSUE, FIXIT, BUG})
+---@param opts table merged with the snippet opts table
+---@param mark_function function: The function used to get the marks
+local todo_snippet = function(context, alias, opts, mark_function)
+  opts = opts or {}
+  context = context or {}
+  if not context.trig then
+    return error("context doesn't include a `trig` key which is mandatory", 2) -- all we need from the context is the trigger
+  end
+  opts.ctype = opts.ctype or 1 -- comment type can be passed in the `opts` table, but if it is not, we have to ensure, it is defined
+  local alias_string = alias -- `choice_node` documentation
+  context.name = context.name or (alias_string .. " comment") -- generate the `name` of the snippet if not defined
+  context.dscr = context.dscr or (alias_string .. " comment with a signature-mark") -- generate the `dscr` if not defined
+  context.docstring = context.docstring or (" {1:" .. alias_string .. "}: {3} <{2:mark}>{0} ") -- generate the `docstring` if not defined
+  local comment_node = todo_snippet_nodes(alias, opts, mark_function)
+  return s(context, comment_node, opts) -- the final todo-snippet constructed from our parameters
+end
+
+---@param context table: The luasnip context
+---@param opts table: The luasnip opts table, needs to have a ctype set
+---@param aliases string: All aliases for a name
+---@param marks table: Possible marks to account in snipped generation
+---@return table: All possible snippets build from the marks
+local process_marks = function(context, aliases, opts, marks)
+  local output = {}
+  for mark_name, mark_function in pairs(marks) do
+    local contex_trig_local = context.trig
+    context.trig = context.trig .. "-" .. mark_name
+    output[#output + 1] = todo_snippet(context, aliases, opts, mark_function)
+    context.trig = contex_trig_local
+  end
+  return output
+end
+
+local todo_snippet_specs = {
+  { { trig = "todo" }, { "TODO" }, { ctype = 1 } },
+  { { trig = "fix" }, { "FIXME", "ISSUE" }, { ctype = 1 } },
+  { { trig = "hack" }, { "HACK" }, { ctype = 1 } },
+  { { trig = "warn" }, { "WARNING" }, { ctype = 1 } },
+  { { trig = "perf" }, { "PERFORMANCE", "OPTIMIZE" }, { ctype = 1 } },
+  { { trig = "note" }, { "NOTE", "INFO" }, { ctype = 1 } },
+
+  -- NOTE: Block commented todo-comments
+  { { trig = "todob" }, { "TODO" }, { ctype = 2 } },
+  { { trig = "fixb" }, { "FIXME", "ISSUE" }, { ctype = 2 } },
+  { { trig = "hackb" }, { "HACK" }, { ctype = 2 } },
+  { { trig = "warnb" }, { "WARNING" }, { ctype = 2 } },
+  { { trig = "perfb" }, { "PERF", "PERFORMANCE", "OPTIM", "OPTIMIZE" }, { ctype = 2 } },
+  { { trig = "noteb" }, { "NOTE", "INFO" }, { ctype = 2 } },
+}
+
+local todo_comment_snippets = {}
+for _, v in ipairs(todo_snippet_specs) do
+  local snippets = process_marks(v[1], v[2][1], v[3], marks)
+  for _, value in pairs(snippets) do
+    table.insert(todo_comment_snippets, value)
+  end
+end
+
+ls.add_snippets("all", todo_comment_snippets, { type = "snippets", key = "todo_comments" })
+
+-- }}}
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/html/html.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/html/html.lua
new file mode 100644
index 00000000..568c97ec
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/html/html.lua
@@ -0,0 +1,102 @@
+local get_visual = function(args, parent)
+  if #parent.snippet.env.SELECT_RAW > 0 then
+    return sn(nil, i(1, parent.snippet.env.SELECT_RAW))
+  else
+    return sn(nil, i(1))
+  end
+end
+
+local line_begin = require("luasnip.extras.expand_conditions").line_begin
+
+return {
+  -- HEADER
+  s(
+    {
+      trig = "h([123456])",
+      regTrig = true,
+      wordTrig = false,
+      snippetType = "autosnippet",
+    },
+    fmt(
+      [[
+          <h{}>{}</h{}>
+        ]],
+      {
+        f(function(_, snip) return snip.captures[1] end),
+        d(1, get_visual),
+        f(function(_, snip) return snip.captures[1] end),
+      }
+    ),
+    { condition = line_begin }
+  ), -- PARAGRAPH
+  s(
+    { trig = "pp", snippetType = "autosnippet" },
+    fmt(
+      [[
+          <p>{}</p>
+        ]],
+      { d(1, get_visual) }
+    ),
+    { condition = line_begin }
+  ), -- UNORDERED LIST
+  s(
+    { trig = "itt", snippetType = "autosnippet" },
+    fmt(
+      [[
+          <ul>
+            <li>{}</li>{}
+          </ul>
+        ]],
+      { i(1), i(0) }
+    ),
+    { condition = line_begin }
+  ), -- LIST ITEM
+  s(
+    { trig = "ii", snippetType = "autosnippet" },
+    fmt(
+      [[
+            <li>{}</li>
+        ]],
+      { d(1, get_visual) }
+    ),
+    { condition = line_begin }
+  ),
+  -- DOCUMENT TEMPLATE
+  s(
+    { trig = "base" },
+    fmt(
+      [[
+        <!doctype HTML>
+        <html lang="en">
+        <head>
+          <meta charset="UTF-8">
+          <title>{}</title>
+        </head>
+        <body>
+          {}
+        </body>
+        </html>
+        ]],
+      { i(1, "FooBar"), i(0) }
+    ),
+    { condition = line_begin }
+  ), -- ANCHOR TAG
+  s(
+    {
+      trig = "([^%l])aa",
+      regTrig = true,
+      wordTrig = false,
+      snippetType = "autosnippet",
+    },
+    fmt(
+      [[
+          {}<a href="{}">{}</a>
+        ]],
+      {
+        f(function(_, snip) return snip.captures[1] end),
+        i(1),
+        d(2, get_visual),
+      }
+    )
+  ),
+}
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua
new file mode 100644
index 00000000..ef453973
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua
@@ -0,0 +1,28 @@
+local get_visual = function(args, parent)
+  if #parent.snippet.env.SELECT_RAW > 0 then
+    return sn(nil, i(1, parent.snippet.env.SELECT_RAW))
+  else
+    return sn(nil, i(1, ""))
+  end
+end
+
+local translation_table = { ["("] = ")", ["{"] = "}", ["["] = "]" }
+
+-- Return snippet tables
+return {
+  -- LEFT/RIGHT ALL BRACES
+  s(
+    {
+      trig = "([^%a])l([%(%[%{])",
+      regTrig = true,
+      wordTrig = false,
+      snippetType = "autosnippet",
+    },
+    fmta("<>\\left<><>\\right<>", {
+      f(function(_, snip) return snip.captures[1] end),
+      f(function(_, snip) return snip.captures[2] end),
+      d(1, get_visual),
+      f(function(_, snip) return translation_table[snip.captures[2]] end),
+    })
+  ),
+}
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/greek.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/greek.lua
new file mode 100644
index 00000000..ebf4f9d7
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/tex/greek.lua
@@ -0,0 +1,37 @@
+-- Return snippet tables
+return {
+  s({ trig = ";a", snippetType = "autosnippet" }, { t("\\alpha") }),
+  s({ trig = ";b", snippetType = "autosnippet" }, { t("\\beta") }),
+  s({ trig = ";g", snippetType = "autosnippet" }, { t("\\gamma") }),
+  s({ trig = ";G", snippetType = "autosnippet" }, { t("\\Gamma") }),
+  s({ trig = ";d", snippetType = "autosnippet" }, { t("\\delta") }),
+  s({ trig = ";D", snippetType = "autosnippet" }, { t("\\Delta") }),
+  s({ trig = ";e", snippetType = "autosnippet" }, { t("\\epsilon") }),
+  s({ trig = ";ve", snippetType = "autosnippet" }, { t("\\varepsilon") }),
+  s({ trig = ";z", snippetType = "autosnippet" }, { t("\\zeta") }),
+  s({ trig = ";h", snippetType = "autosnippet" }, { t("\\eta") }),
+  s({ trig = ";o", snippetType = "autosnippet" }, { t("\\theta") }),
+  s({ trig = ";vo", snippetType = "autosnippet" }, { t("\\vartheta") }),
+  s({ trig = ";O", snippetType = "autosnippet" }, { t("\\Theta") }),
+  s({ trig = ";k", snippetType = "autosnippet" }, { t("\\kappa") }),
+  s({ trig = ";l", snippetType = "autosnippet" }, { t("\\lambda") }),
+  s({ trig = ";L", snippetType = "autosnippet" }, { t("\\Lambda") }),
+  s({ trig = ";m", snippetType = "autosnippet" }, { t("\\mu") }),
+  s({ trig = ";n", snippetType = "autosnippet" }, { t("\\nu") }),
+  s({ trig = ";x", snippetType = "autosnippet" }, { t("\\xi") }),
+  s({ trig = ";X", snippetType = "autosnippet" }, { t("\\Xi") }),
+  s({ trig = ";i", snippetType = "autosnippet" }, { t("\\pi") }),
+  s({ trig = ";I", snippetType = "autosnippet" }, { t("\\Pi") }),
+  s({ trig = ";r", snippetType = "autosnippet" }, { t("\\rho") }),
+  s({ trig = ";s", snippetType = "autosnippet" }, { t("\\sigma") }),
+  s({ trig = ";S", snippetType = "autosnippet" }, { t("\\Sigma") }),
+  s({ trig = ";t", snippetType = "autosnippet" }, { t("\\tau") }),
+  s({ trig = ";f", snippetType = "autosnippet" }, { t("\\phi") }),
+  s({ trig = ";vf", snippetType = "autosnippet" }, { t("\\varphi") }),
+  s({ trig = ";F", snippetType = "autosnippet" }, { t("\\Phi") }),
+  s({ trig = ";c", snippetType = "autosnippet" }, { t("\\chi") }),
+  s({ trig = ";p", snippetType = "autosnippet" }, { t("\\psi") }),
+  s({ trig = ";P", snippetType = "autosnippet" }, { t("\\Psi") }),
+  s({ trig = ";w", snippetType = "autosnippet" }, { t("\\omega") }),
+  s({ trig = ";W", snippetType = "autosnippet" }, { t("\\Omega") }),
+}
diff --git a/modules/by-name/nv/nvim/plgs/neorg/default.nix b/modules/by-name/nv/nvim/plgs/neorg/default.nix
new file mode 100644
index 00000000..cf046e06
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/neorg/default.nix
@@ -0,0 +1,70 @@
+{
+  config,
+  lib,
+  pkgsStable,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins = lib.mkIf cfg.enable {
+    cmp.settings.sources = [
+      {name = "neorg";}
+    ];
+
+    neorg = {
+      package = pkgsStable.vimPlugins.neorg;
+      enable = true;
+      lazyLoading = true;
+
+      modules = {
+        "core.defaults" = {
+          __empty = null;
+        };
+        "core.esupports.metagen".config = {
+          type = "auto";
+        };
+        "core.journal".config = {
+          workspace = "journal";
+        };
+        "core.keybinds".config = {
+          hook = {
+            __raw = ''
+              function(keybinds)
+                  -- remap the looking glas to the same key, femaco is also mapped to.
+                  keybinds.remap_event("norg", "n", "<space>cc", "core.looking-glass.magnify-code-block")
+
+                  keybinds.remap_event("norg", "n", "<C-s>", "core.integrations.telescope.find_linkable")
+                  keybinds.remap_event("norg", "i", "<C-i>", "core.integrations.telescope.insert_link")
+              end,
+            '';
+          };
+        };
+        "core.completion".config = {
+          engine = "nvim-cmp";
+        };
+        "core.concealer".config = {
+          __empty = null;
+        };
+        "core.dirman".config = {
+          workspaces = {
+            general = "~/repos/notes/general";
+            journal = "~/repos/notes/journal";
+            projects = "~/repos/notes/projects";
+          };
+        };
+        "core.export".config = {
+          __empty = null;
+        };
+        "core.integrations.telescope".config = {
+          __empty = null;
+        };
+
+        # TODO: Add this when the nvim version in nixpkgs is >= 0.10 <2023-08-29>
+        #
+        # "core.ui.calendar".config = {
+        #   __empty = null;
+        # };
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/nvim-cmp/default.nix b/modules/by-name/nv/nvim/plgs/nvim-cmp/default.nix
new file mode 100644
index 00000000..8d61dbd7
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/nvim-cmp/default.nix
@@ -0,0 +1,53 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.cmp = lib.mkIf cfg.enable {
+    /*
+    TODO: integrate this:
+    ```lua
+      enabled = {
+      function()
+          -- disable completion in comments
+          local context = require 'cmp.config.context'
+          -- keep command mode completion enabled when cursor is in a comment
+          -- te
+          if vim.api.nvim_get_mode().mode == 'c' then
+              return true
+          else
+              return not context.in_treesitter_capture("comment")
+                  and not context.in_syntax_group("Comment")
+          end
+      end
+      },
+    ```
+    */
+    enable = true;
+    autoEnableSources = true;
+    settings = {
+      mapping = {
+        # TODO: add support for desc and which key here
+        "<C-d>" = "cmp.mapping.scroll_docs(-4)"; # desc = "Scroll up by four lines"
+        "<C-f>" = "cmp.mapping.scroll_docs(4)"; # desc = "Scroll down by four lines"
+        "HH" = "cmp.mapping.complete()"; # desc = "Confirm snipped"
+      };
+
+      snippet.expand = "function(args) require('luasnip').lsp_expand(args.body) end";
+
+      sources = [
+        {name = "nvim_lsp";}
+        {name = "luasnip";}
+        {name = "path";}
+        {name = "git";} # TODO: I might want to add config to allow all issues/prs <2023-10-16>
+        # {name = "convertionalcommits";} # TODO: Useless without commitlint [https://commitlint.js.org/] <2023-10-16>
+        # {name = "rg";} # TODO: This might really RIP-grep my system <2023-10-16>
+        # {name = "buffer";}
+        # {name = "digraphs";}
+        {name = "calc";}
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/nvim-lint/default.nix b/modules/by-name/nv/nvim/plgs/nvim-lint/default.nix
new file mode 100644
index 00000000..ee057a9b
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/nvim-lint/default.nix
@@ -0,0 +1,18 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # TODO: package nvim-lint though a module
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/nvim-lint.lua}
+    '';
+    extraPlugins = [
+      pkgs.vimPlugins.nvim-lint
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/nvim-lint/lua/nvim-lint.lua b/modules/by-name/nv/nvim/plgs/nvim-lint/lua/nvim-lint.lua
new file mode 100644
index 00000000..770c3bb5
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/nvim-lint/lua/nvim-lint.lua
@@ -0,0 +1,18 @@
+require("lint").linters_by_ft = {
+  -- text
+  markdown = {},
+  -- tex = {'chktex'}, -- maybe add some text linters ?
+
+  -- shell (already covered by the bash language sever)
+  --  sh = { "shellcheck"; };
+  --  bash = { "shellcheck"; };
+  --  zsh = { "shellcheck"; };
+  --  dash = { "shellcheck"; };
+
+  yaml = { "yamllint" },
+  nix = { "nix", "statix" },
+}
+
+vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, {
+  callback = function() require("lint").try_lint() end,
+})
diff --git a/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix b/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix
new file mode 100644
index 00000000..e5d401a0
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix
@@ -0,0 +1,17 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    # Not all plugins have own modules
+    # You can add missing plugins here
+    # `pkgs.vimExtraPlugins` is added by the overlay you added at the beginning
+    # For a list of available plugins, look here:
+    # https://github.com/jooooscha/nixpkgs-vim-extra-plugins/blob/main/plugins.md
+    extraPlugins = [
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/default.nix b/modules/by-name/nv/nvim/plgs/telescope/default.nix
new file mode 100644
index 00000000..193ee1ac
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/default.nix
@@ -0,0 +1,23 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  imports = [
+    ./defaults
+    ./keymaps
+    ./extensions
+  ];
+  home-manager.users.soispha.programs.nixvim.plugins = lib.mkIf cfg.enable {
+    telescope = {
+      enable = true;
+    };
+
+    # This is a dependency of telescope
+    web-devicons = {
+      enable = true;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/defaults/default.nix b/modules/by-name/nv/nvim/plgs/telescope/defaults/default.nix
new file mode 100644
index 00000000..11d04304
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/defaults/default.nix
@@ -0,0 +1,36 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.telescope.settings.defaults = lib.mkIf cfg.enable {
+    mappings = let
+      insert_and_normal_mappings = {
+        # map actions.which_key to <c-h> (default: <c-/>)
+        # actions.which_key shows the mappings for your picker,
+        # e.g. git_{create, delete, ...}_branch for the git_branches picker
+        "<C-h>" = "which_key";
+      };
+    in {
+      i =
+        insert_and_normal_mappings;
+      n =
+        {
+          "t" = "move_selection_next";
+          "n" = "move_selection_previous";
+          "<Space>" = "toggle_all";
+
+          "<C-d>" = "preview_scrolling_up";
+          "<C-u>" = "preview_scrolling_down";
+          "<Left>" = "preview_scrolling_left";
+          "<Right>" = "preview_scrolling_right";
+
+          "<Esc>" = "close";
+          "q" = "close";
+        }
+        // insert_and_normal_mappings;
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
new file mode 100644
index 00000000..e263cfdc
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
@@ -0,0 +1,24 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  # WARNING: This is only activated in tex files via the ftplugin.
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraPlugins = [
+      pkgs.vimExtraPlugins.telescope-bibtex-nvim
+    ];
+    keymaps = [
+      {
+        key = "<space>ib";
+        # This is registered in the ftplugin file, so we set this to null here
+        action = "<Nop>";
+        mode = "n";
+        options.desc = "[i]nsert a [b]atex citation";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/default.nix
new file mode 100644
index 00000000..0b1e033a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/default.nix
@@ -0,0 +1,9 @@
+{...}: {
+  imports = [
+    ./bibtex
+    ./frecency
+    ./fzy-native
+    ./rooter
+    ./symbols
+  ];
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/frecency/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/frecency/default.nix
new file mode 100644
index 00000000..f4e3d116
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/frecency/default.nix
@@ -0,0 +1,28 @@
+{
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    keymaps = [
+      {
+        key = "gff";
+        mode = "n";
+        action.__raw = "function() require('telescope').extensions.frecency.frecency() end";
+        options.desc = "activate the frecency file selection";
+      }
+    ];
+    plugins.telescope = {
+      extensions.frecency = {
+        enable = true;
+        settings = {
+          show_scores = true;
+          db_safe_mode = false;
+          default_workspace = "CWD"; # or 'LSP'
+        };
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/fzy-native/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/fzy-native/default.nix
new file mode 100644
index 00000000..4194e688
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/fzy-native/default.nix
@@ -0,0 +1,11 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.telescope.extensions.fzy-native = lib.mkIf cfg.enable {
+    enable = true;
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/default.nix
new file mode 100644
index 00000000..6153b063
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/default.nix
@@ -0,0 +1,13 @@
+{
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraConfigLuaPost = ''
+      ${lib.strings.fileContents ./lua/rooter.lua}
+    '';
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/lua/rooter.lua b/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/lua/rooter.lua
new file mode 100644
index 00000000..48a8588d
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/rooter/lua/rooter.lua
@@ -0,0 +1,76 @@
+-- Taken from: https://github.com/desdic/telescope-rooter.nvim/blob/69423216c75a5f1f1477bbf8faf6b0dc8af04099/lua/telescope/_extensions/rooter.lua
+local has_telescope, telescope = pcall(require, "telescope")
+if not has_telescope then
+  error("This extension requires telescope.nvim")
+  return
+end
+
+local has_plenary, plenary = pcall(require, "plenary")
+if not has_plenary then
+  error("This extension requires plenary")
+  return
+end
+
+local log = plenary.log.new({ plugin = "telescope_rooter", level = "info" })
+
+-- TODO: expose this function
+local toggle = function(_)
+  vim.g["Telescope#rooter#enabled"] = not vim.g["Telescope#rooter#enabled"]
+  print("Telescope#rooter#enabled=" .. vim.inspect(vim.g["Telescope#rooter#enabled"]))
+end
+
+local config = { patterns = { ".git" }, enable = true, debug = false }
+
+-- default enabled
+vim.g["Telescope#rooter#enabled"] = vim.F.if_nil(config.enable, true)
+
+-- redefine log if debug enabled
+if vim.F.if_nil(config.debug, false) then log = plenary.log.new({ plugin = "telescope_rooter", level = "debug" }) end
+
+local group = vim.api.nvim_create_augroup("TelescopeRooter", { clear = true })
+
+vim.api.nvim_create_autocmd({ "DirChangedPre" }, {
+  callback = function()
+    if vim.g["Telescope#rooter#enabled"] ~= true then return end
+
+    if vim.g["Telescope#rooter#oldpwd"] == nil then
+      vim.g["Telescope#rooter#oldpwd"] = vim.loop.cwd()
+      log.debug("before " .. vim.inspect(vim.loop.cwd()))
+    end
+  end,
+  group = group,
+})
+
+vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
+  callback = function()
+    if vim.g["Telescope#rooter#enabled"] ~= true then return end
+
+    vim.schedule(function()
+      if vim.bo.filetype == "TelescopePrompt" then
+        local rootdir = vim.fs.dirname(vim.fs.find(config.patterns, { upward = true })[1])
+        if rootdir ~= nil then
+          vim.api.nvim_set_current_dir(rootdir)
+          log.debug("changing dir to " .. rootdir)
+        end
+      end
+    end)
+  end,
+  group = group,
+})
+
+vim.api.nvim_create_autocmd({ "BufWinLeave" }, {
+  callback = function()
+    if vim.g["Telescope#rooter#enabled"] ~= true then return end
+
+    vim.schedule(function()
+      if vim.bo.filetype ~= "TelescopePrompt" then
+        if vim.g["Telescope#rooter#oldpwd"] ~= nil then
+          log.debug("restoring " .. vim.g["Telescope#rooter#oldpwd"])
+          vim.api.nvim_set_current_dir(vim.g["Telescope#rooter#oldpwd"])
+          vim.g["Telescope#rooter#oldpwd"] = nil
+        end
+      end
+    end)
+  end,
+  group = group,
+})
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/symbols/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/symbols/default.nix
new file mode 100644
index 00000000..adbb466a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/symbols/default.nix
@@ -0,0 +1,59 @@
+{
+  pkgs,
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    extraPlugins = [
+      # Source of symbols for telescope symbols
+      pkgs.vimPlugins.telescope-symbols-nvim
+    ];
+    keymaps = [
+      {
+        key = "<space>il";
+        mode = "n";
+        action.__raw = ''
+          function()
+            require('telescope.builtin').symbols{ sources = {
+              'latex'
+            }}
+          end
+        '';
+        options.desc = "[i]nsert a [l]atex symbol";
+      }
+      {
+        key = "<space>ie";
+        mode = "n";
+        action.__raw = ''
+          function()
+            require('telescope.builtin').symbols{ sources = {
+                'emoji',
+            }}
+          end
+        '';
+        options.desc = "[i]nsert a [e]moji";
+      }
+      {
+        key = "<space>is";
+        mode = "n";
+        action.__raw = ''
+          function()
+            require('telescope.builtin').symbols{ sources = {
+                'emoji',
+                'gitmoji',
+                'julia',
+                'kaomoji',
+                'latex',
+                'math',
+                'nerd',
+            }}
+          end
+        '';
+        options.desc = "[i]nsert a [s]ymbol (like emojis)";
+      }
+    ];
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/telescope/keymaps/default.nix b/modules/by-name/nv/nvim/plgs/telescope/keymaps/default.nix
new file mode 100644
index 00000000..a474f097
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/telescope/keymaps/default.nix
@@ -0,0 +1,16 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.telescope.keymaps = lib.mkIf cfg.enable {
+    "<space>rg" = {
+      action = "live_grep";
+      options = {
+        desc = "[rg] in a live session";
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/todo-comments/default.nix b/modules/by-name/nv/nvim/plgs/todo-comments/default.nix
new file mode 100644
index 00000000..ddbe367d
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/todo-comments/default.nix
@@ -0,0 +1,57 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.todo-comments = lib.mkIf cfg.enable {
+    enable = true;
+    settings = {
+      guiStyle = {
+        fg = "BOLD";
+        bg = "NONE";
+      };
+      highlight = {
+        keyword = "wide_fg";
+      };
+      keywords = {
+        /*
+        # Defaults:
+        FIX = {
+          icon = " "; # Icon used for the sign, and in search results.
+          color = "error"; # Can be a hex color, or a named color.
+          alt = ["FIXME" "BUG" "FIXIT" "ISSUE"]; # A set of other keywords that all map to this FIX keywords.
+        };
+        TODO = {
+          icon = " ";
+          color = "info";
+        };
+        HACK = {
+          icon = " ";
+          color = "warning";
+        };
+        WARN = {
+          icon = " ";
+          color = "warning";
+          alt = ["WARNING" "XXX"];
+        };
+        PERF = {
+          icon = "󰅒 ";
+          alt = ["OPTIM" "PERFORMANCE" "OPTIMIZE"];
+        };
+        NOTE = {
+          icon = "󰍨 ";
+          color = "hint";
+          alt = ["INFO"];
+        };
+        TEST = {
+          icon = "⏲ ";
+          color = "test";
+          alt = ["TESTING" "PASSED" "FAILED"];
+        };
+        */
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/treesitter/default.nix b/modules/by-name/nv/nvim/plgs/treesitter/default.nix
new file mode 100644
index 00000000..02088d0a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/treesitter/default.nix
@@ -0,0 +1,63 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.  programs.nixvim = lib.mkIf cfg.enable {
+    plugins.treesitter = {
+      enable = true;
+
+      # NOTE: These are required to build grammars, but I already use the nix grammars <2024-07-13>
+      gccPackage = null;
+      nodejsPackage = null;
+      treesitterPackage = null;
+
+      # inject nixvim specific highlighting (eg in extraConfigLua).
+      nixvimInjections = true;
+
+      nixGrammars = true;
+      grammarPackages =
+        # Append the `tree-sitter-yts` grammar to all the other grammars.
+        # TODO: Find a better way to do this. <2024-11-08>
+        config.home-manager.users.soispha.programs.nixvim.plugins.treesitter.package.passthru.allGrammars
+        ++ [pkgs.tree-sitter-yts];
+
+      settings = {
+        auto_install = false;
+        ensureInstalled = "all";
+        indent.enable = true;
+        disabledLanguages = [];
+
+        highlight = {
+          enable = true;
+          disable = [];
+
+          #  Setting this to true will run `:h syntax` and tree-sitter at the same time.
+          #  Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
+          #  Using this option may slow down your editor; and you may see some duplicate highlights.
+          #  Instead of true it can also be a list of languages
+          additionalVimRegexHighlighting = ["latex"];
+        };
+
+        incrementalSelection = {
+          enable = true;
+          keymaps = {
+            # TODO: include these in the which-key description
+            initSelection = "gnn"; #  set to `false` to disable one of the mappings
+            nodeIncremental = "grn";
+            scopeIncremental = "grc";
+            nodeDecremental = "grm";
+          };
+        };
+      };
+    };
+    extraFiles = {
+      "queries/yts/highlights.scm".text = ''
+        ${lib.strings.fileContents "${pkgs.tree-sitter-yts}/queries/highlights.scm"}
+      '';
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/vim-tex/default.nix b/modules/by-name/nv/nvim/plgs/vim-tex/default.nix
new file mode 100644
index 00000000..680f169a
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/vim-tex/default.nix
@@ -0,0 +1,75 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+    opts.conceallevel = 0;
+
+    plugins.vimtex = {
+      enable = true;
+      settings = {
+        view_method = "zathura";
+        quickfix_mode = -1;
+        view_enabled = -1;
+        tex_conceal = "abdmg";
+        tex_flavor = "latex";
+
+        # Useful if treesitter is the highlighter
+        syntax_enabled = 0;
+        syntax_conceal_disable = 1;
+
+        mappings_disable = {
+          n = [
+            "ts$"
+            "tsD"
+            "tsb"
+            "tsc"
+            "tsd"
+            "tse"
+            "tsf"
+          ];
+          x = [
+            "tsD"
+            "tsd"
+            "tsf"
+          ];
+        };
+
+        toc_config = {
+          name = "TOC";
+          layers = ["content" "todo" "include"];
+          resize = false;
+          split_width = 49;
+          todo_sorted = -1;
+          show_help = false;
+          show_numbers = false;
+          mode = true;
+          layer_keys = {
+            content = "C";
+            label = "L";
+            todo = "j";
+            include = "I";
+          };
+        };
+
+        compiler_latexmk = {
+          build_dir = "build";
+          callback = false;
+          continuous = true;
+          executable = "latexmk";
+          hooks = [];
+          options = [
+            "-verbose"
+            "-file-line-error"
+            "-synctex=0"
+            "-interaction=nonstopmode"
+            "-outdir=build"
+          ];
+        };
+      };
+    };
+  };
+}
diff --git a/modules/by-name/nv/nvim/plgs/which-key/default.nix b/modules/by-name/nv/nvim/plgs/which-key/default.nix
new file mode 100644
index 00000000..20004bb1
--- /dev/null
+++ b/modules/by-name/nv/nvim/plgs/which-key/default.nix
@@ -0,0 +1,11 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.nvim;
+in {
+  home-manager.users.soispha.programs.nixvim.plugins.which-key = lib.mkIf cfg.enable {
+    enable = true;
+  };
+}