aboutsummaryrefslogtreecommitdiffstats
path: root/modules/development
diff options
context:
space:
mode:
Diffstat (limited to 'modules/development')
-rw-r--r--modules/development/bruno/default.nix22
-rw-r--r--modules/development/default.nix14
-rw-r--r--modules/development/delta/default.nix32
-rw-r--r--modules/development/git/assertions.nix13
-rw-r--r--modules/development/git/default.nix112
-rw-r--r--modules/development/lazygit/default.nix33
-rw-r--r--modules/development/nixvim/colorscheme.nix26
-rw-r--r--modules/development/nixvim/default.nix103
-rw-r--r--modules/development/nixvim/keymaps.nix41
-rw-r--r--modules/development/nixvim/plugins/cmp.nix37
-rw-r--r--modules/development/nixvim/plugins/comment.nix23
-rw-r--r--modules/development/nixvim/plugins/default.nix20
-rw-r--r--modules/development/nixvim/plugins/gitsigns.nix8
-rw-r--r--modules/development/nixvim/plugins/indent-blankline.nix14
-rw-r--r--modules/development/nixvim/plugins/lsp.nix234
-rw-r--r--modules/development/nixvim/plugins/lualine.nix90
-rw-r--r--modules/development/nixvim/plugins/luasnip.nix8
-rw-r--r--modules/development/nixvim/plugins/noice.nix8
-rw-r--r--modules/development/nixvim/plugins/nvim-tree.nix44
-rw-r--r--modules/development/nixvim/plugins/telescope.nix85
-rw-r--r--modules/development/nixvim/plugins/treesitter.nix19
-rw-r--r--modules/development/nixvim/plugins/web-devicons.nix8
-rw-r--r--modules/development/nixvim/plugins/which-key.nix21
-rw-r--r--modules/development/opencode/default.nix19
-rw-r--r--modules/development/qemu/default.nix30
-rw-r--r--modules/development/vscodium/default.nix20
26 files changed, 1084 insertions, 0 deletions
diff --git a/modules/development/bruno/default.nix b/modules/development/bruno/default.nix
new file mode 100644
index 0000000..7205f31
--- /dev/null
+++ b/modules/development/bruno/default.nix
@@ -0,0 +1,22 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+# Bruno - Open-source API client for testing HTTP endpoints
+{
+ options.programs.bruno = {
+ enable = lib.mkEnableOption "Enables bruno.";
+ package = lib.mkPackageOption pkgs "bruno" { };
+ };
+
+ config = lib.mkIf config.programs.bruno.enable {
+ home.packages = [ config.programs.bruno.package ];
+
+ xdg.mimeApps.defaultApplications = {
+ "x-scheme-handler/bruno" = "bruno.desktop";
+ };
+ };
+}
diff --git a/modules/development/default.nix b/modules/development/default.nix
new file mode 100644
index 0000000..1e79868
--- /dev/null
+++ b/modules/development/default.nix
@@ -0,0 +1,14 @@
+{ ... }:
+
+{
+ imports = [
+ ./bruno
+ ./delta
+ ./git
+ ./lazygit
+ ./nixvim
+ ./opencode
+ ./qemu
+ ./vscodium
+ ];
+}
diff --git a/modules/development/delta/default.nix b/modules/development/delta/default.nix
new file mode 100644
index 0000000..90e35d4
--- /dev/null
+++ b/modules/development/delta/default.nix
@@ -0,0 +1,32 @@
+{
+ config,
+ lib,
+ ...
+}:
+# Delta - A syntax-highlighting pager for git, diff, and grep output
+{
+ config = lib.mkIf config.programs.delta.enable {
+ programs.delta.options = {
+ line-numbers = true;
+ hunk-header-style = "omit";
+ hunk-header-decoration-style = "omit";
+ line-numbers-left-format = "{nm}│ ";
+ line-numbers-right-format = "{np}│ ";
+ };
+
+ programs.git.settings = lib.mkIf config.programs.git.enable {
+ core.pager = "delta";
+ interactive.diffFilter = "delta --color-only";
+ delta.navigate = true;
+ };
+
+ programs.lazygit.settings = lib.mkIf config.programs.lazygit.enable {
+ git.pagers = [
+ {
+ colorArg = "always";
+ pager = "delta --paging=never {{diffArgs}}";
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/development/git/assertions.nix b/modules/development/git/assertions.nix
new file mode 100644
index 0000000..fbe5d3c
--- /dev/null
+++ b/modules/development/git/assertions.nix
@@ -0,0 +1,13 @@
+{ config, ... }:
+{
+ assertions = [
+ {
+ assertion =
+ !config.programs.git.useSSH || (config.programs.git.enable && config.programs.ssh.enable);
+ message = ''
+ programs.git.useSSH is enabled but programs.ssh.enable is not.
+ SSH must be enabled (programs.ssh.enable = true) to use SSH for git.
+ '';
+ }
+ ];
+}
diff --git a/modules/development/git/default.nix b/modules/development/git/default.nix
new file mode 100644
index 0000000..c1aade5
--- /dev/null
+++ b/modules/development/git/default.nix
@@ -0,0 +1,112 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+# Git - Distributed version control system
+{
+ imports = [
+ ./assertions.nix
+ ]
+ ++ lib.optional (builtins.pathExists ../../private/git.nix) ../../private/git.nix;
+
+ options.programs.git = {
+ username = lib.mkOption {
+ type = lib.types.str;
+ description = "Git username.";
+ };
+
+ email = lib.mkOption {
+ type = lib.types.str;
+ description = "Git email.";
+ };
+
+ useSSH = lib.mkEnableOption "Use SSH instead of HTTPS for common git platforms.";
+ };
+
+ config = lib.mkIf config.programs.git.enable {
+ home.packages = with pkgs; [
+ git-graph
+ ];
+
+ xdg.configFile."git-graph/models/custom.toml".text = ''
+ persistence = [
+ '^(master|main|trunk)$',
+ '^(develop|dev)$',
+ '^feature.*$',
+ '^release.*$',
+ '^hotfix.*$',
+ '^bugfix.*$',
+ ]
+
+ order = [
+ '^(master|main|trunk)$',
+ '^(hotfix|release).*$',
+ '^(develop|dev)$',
+ ]
+
+ [terminal_colors]
+ matches = [
+ ['^(master|main|trunk)$', ['bright_blue']],
+ ['^(develop|dev)$', ['bright_yellow']],
+ ['^(feature|fork/).*$', ['bright_magenta', 'bright_cyan']],
+ ['^release.*$', ['bright_green']],
+ ['^(bugfix|hotfix).*$', ['bright_red']],
+ ['^tags/.*$', ['bright_green']],
+ ]
+ # Everything else (e.g. custom/service branches) cycles through these instead of all being white
+ unknown = ['bright_white', 'bright_red', 'bright_green', 'bright_yellow', 'bright_blue', 'bright_magenta', 'bright_cyan']
+
+ [svg_colors]
+ matches = [
+ ['^(master|main|trunk)$', ['blue']],
+ ['^(develop|dev)$', ['orange']],
+ ['^(feature|fork/).*$', ['magenta', 'cyan']],
+ ['^release.*$', ['green']],
+ ['^(bugfix|hotfix).*$', ['red']],
+ ['^tags/.*$', ['green']],
+ ]
+ unknown = ['gray', 'purple', 'teal', 'brown']
+ '';
+
+ programs.git = {
+ settings =
+ lib.recursiveUpdate
+ {
+ user = {
+ name = config.programs.git.username;
+ email = config.programs.git.email;
+ };
+ core.askPass = "";
+ alias = {
+ # The exclamation mark (!) tells Git to execute this as an external shell command.
+ # This overrides standard git-graph behavior with your custom format string.
+ log-graph = ''
+ !f() {
+ fmt=$(printf '\033[1;34mCommit:\033[0m \033[33m%%h\033[0m \033[91m%%d\033[0m%%n\033[1;34mParents:\033[0m \033[35m%%p\033[0m%%n\033[1;34mAuthor:\033[0m \033[32m%%an\033[0m <\033[96m%%ae\033[0m>%%n\033[1;34mDate:\033[0m \033[36m%%ad (%%ar)\033[0m%%n%%n%%B%%n\033[90m--------------------------------------------------------\033[0m')
+ git-graph --model custom --color always --sparse --style round --format="$fmt"
+ }; f | less -R
+ '';
+ # Same formatting, but no pager — meant for embedding (lazygit, etc.)
+ log-graph-embed = ''
+ !f() {
+ fmt=$(printf '\033[1;34mCommit:\033[0m \033[33m%%h\033[0m \033[91m%%d\033[0m%%n\033[1;34mParents:\033[0m \033[35m%%p\033[0m%%n\033[1;34mAuthor:\033[0m \033[32m%%an\033[0m <\033[96m%%ae\033[0m>%%n\033[1;34mDate:\033[0m \033[36m%%ad (%%ar)\033[0m%%n%%n%%B%%n\033[90m--------------------------------------------------------\033[0m')
+ git-graph --model custom --color always --sparse --style round --no-pager --format="$fmt"
+ }; f
+ '';
+ };
+ }
+ (
+ lib.optionalAttrs config.programs.git.useSSH {
+ url."git@github.com:".insteadOf = "https://github.com/";
+ url."git@gitlab.com:".insteadOf = "https://gitlab.com/";
+ url."git@bitbucket.org:".insteadOf = "https://bitbucket.org/";
+ url."git@codeberg.org:".insteadOf = "https://codeberg.org/";
+ url."git@git.sr.ht:".insteadOf = "https://git.sr.ht/";
+ }
+ );
+ };
+ };
+}
diff --git a/modules/development/lazygit/default.nix b/modules/development/lazygit/default.nix
new file mode 100644
index 0000000..cf46e9a
--- /dev/null
+++ b/modules/development/lazygit/default.nix
@@ -0,0 +1,33 @@
+{ config, lib, ... }:
+
+# Lazygit - A simple terminal UI for git commands
+{
+ config = lib.mkIf config.programs.lazygit.enable {
+ programs.lazygit = {
+ enableBashIntegration = config.programs.bash.enable;
+ enableFishIntegration = config.programs.fish.enable;
+ enableNushellIntegration = config.programs.nushell.enable;
+ enableZshIntegration = config.programs.zsh.enable;
+
+ settings = {
+ gui = {
+ theme = {
+ lightTheme = false;
+ };
+ showIcons = true;
+ scrollHeight = 2;
+ nerdFontsVersion = "3";
+ scrollPastBottom = true;
+ mouseEvents = true;
+ border = "single";
+ };
+ git = {
+ log.showWholeGraph = true;
+ branchLogCmd = "git log-graph-embed";
+ overrideGpg = true;
+ };
+ update.method = "never";
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/colorscheme.nix b/modules/development/nixvim/colorscheme.nix
new file mode 100644
index 0000000..ba81634
--- /dev/null
+++ b/modules/development/nixvim/colorscheme.nix
@@ -0,0 +1,26 @@
+{ config, lib, ... }:
+
+# Colorscheme - Base16 theme configuration for nixvim
+{
+ config.programs.nixvim.colorschemes.base16 = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ colorscheme = with config.scheme.withHashtag; {
+ base00 = base00;
+ base01 = base01;
+ base02 = base02;
+ base03 = base03;
+ base04 = base04;
+ base05 = base05;
+ base06 = base06;
+ base07 = base07;
+ base08 = base08;
+ base09 = base09;
+ base0A = base0A;
+ base0B = base0B;
+ base0C = base0C;
+ base0D = base0D;
+ base0E = base0E;
+ base0F = base0F;
+ };
+ };
+}
diff --git a/modules/development/nixvim/default.nix b/modules/development/nixvim/default.nix
new file mode 100644
index 0000000..c7978d4
--- /dev/null
+++ b/modules/development/nixvim/default.nix
@@ -0,0 +1,103 @@
+{ config, lib, ... }:
+
+# Nixvim - Neovim configured through Nix (home-manager integration)
+{
+ imports = [
+ ./colorscheme.nix
+ ./keymaps.nix
+ ./plugins
+ ];
+
+ config = {
+ programs.nixvim = {
+ defaultEditor = true;
+ opts = {
+ number = true;
+ relativenumber = true;
+ shiftwidth = 2;
+ tabstop = 2;
+ softtabstop = 2;
+ expandtab = true;
+ list = true;
+ laststatus = 3;
+ foldlevel = 99;
+ clipboard = "unnamedplus";
+ updatetime = 500;
+ };
+ clipboard.providers.xclip.enable = true;
+ extraConfigLuaPre = with config.scheme.withHashtag; ''
+ vim.opt.fillchars:append({ eob = " " })
+ vim.opt.listchars = { tab = " ", trail = "_", lead = " " }
+ vim.api.nvim_set_hl(0, "WinSeparator", {
+ fg = "${base01}",
+ bg = "${base00}",
+ })
+ vim.api.nvim_set_hl(0, 'NotifyERRORBorder', { fg = '${base08}' })
+ vim.api.nvim_set_hl(0, 'NotifyWARNBorder', { fg = '${base09}' })
+ vim.api.nvim_set_hl(0, 'NotifyINFOBorder', { fg = '${base0B}' })
+ vim.api.nvim_set_hl(0, 'NotifyDEBUGBorder', { fg = '${base03}' })
+ vim.api.nvim_set_hl(0, 'NotifyTRACEBorder', { fg = '${base0E}' })
+
+ vim.api.nvim_set_hl(0, 'NotifyERRORIcon', { fg = '${base08}' })
+ vim.api.nvim_set_hl(0, 'NotifyWARNIcon', { fg = '${base09}' })
+ vim.api.nvim_set_hl(0, 'NotifyINFOIcon', { fg = '${base0B}' })
+ vim.api.nvim_set_hl(0, 'NotifyDEBUGIcon', { fg = '${base03}' })
+ vim.api.nvim_set_hl(0, 'NotifyTRACEIcon', { fg = '${base0E}' })
+
+ vim.api.nvim_set_hl(0, 'NotifyERRORTitle', { fg = '${base08}' })
+ vim.api.nvim_set_hl(0, 'NotifyWARNTitle', { fg = '${base09}' })
+ vim.api.nvim_set_hl(0, 'NotifyINFOTitle', { fg = '${base0B}' })
+ vim.api.nvim_set_hl(0, 'NotifyDEBUGTitle', { fg = '${base03}' })
+ vim.api.nvim_set_hl(0, 'NotifyTRACETitle', { fg = '${base0E}' })
+
+ vim.api.nvim_set_hl(0, 'NotifyERRORBody', { link = 'Normal' })
+ vim.api.nvim_set_hl(0, 'NotifyWARNBody', { link = 'Normal' })
+ vim.api.nvim_set_hl(0, 'NotifyINFOBody', { link = 'Normal' })
+ vim.api.nvim_set_hl(0, 'NotifyDEBUGBody', { link = 'Normal' })
+ vim.api.nvim_set_hl(0, 'NotifyTRACEBody', { link = 'Normal' })
+
+ vim.api.nvim_create_autocmd({ "FileType" }, {
+ pattern = { "yaml", "yml" },
+ callback = function()
+ vim.opt_local.expandtab = true
+ vim.opt_local.shiftwidth = 2
+ vim.opt_local.softtabstop = 2
+ vim.opt_local.tabstop = 2
+ end,
+ })
+ '';
+ performance = {
+ byteCompileLua.enable = true;
+ combinePlugins.enable = true;
+ };
+
+ diagnostic = {
+ settings = {
+ virtual_text = false;
+ signs = true;
+ underline = true;
+ update_in_insert = false;
+ float = {
+ border = "rounded";
+ source = true; # Show which LSP the diagnostic is from
+ header = "";
+ prefix = "";
+ };
+ };
+ };
+
+ # Show diagnostics float on cursor hold
+ autoCmd = [
+ {
+ event = [ "CursorHold" ];
+ pattern = "*";
+ callback.__raw = ''
+ function()
+ vim.diagnostic.open_float(nil, { focus = false })
+ end
+ '';
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/development/nixvim/keymaps.nix b/modules/development/nixvim/keymaps.nix
new file mode 100644
index 0000000..4e4b35a
--- /dev/null
+++ b/modules/development/nixvim/keymaps.nix
@@ -0,0 +1,41 @@
+{ config, lib, ... }:
+
+# Keymaps - Keyboard shortcut configuration for nixvim
+{
+ config.programs.nixvim.keymaps = lib.mkIf config.programs.nixvim.enable [
+ {
+ key = "<c-h>";
+ action = "<c-w>h";
+ options.desc = "Move to left window";
+ }
+ {
+ key = "<c-w>";
+ action = "<c-w>j";
+ options.desc = "Move to bottom window";
+ }
+ {
+ key = "<c-k>";
+ action = "<c-w>k";
+ options.desc = "Move to top window";
+ }
+ {
+ key = "<c-l>";
+ action = "<c-w>l";
+ options.desc = "Move to right window";
+ }
+ {
+ key = "<c-n>";
+ action = "<cmd>NvimTreeToggle<cr>";
+ mode = [
+ "n"
+ "i"
+ ];
+ options.desc = "Toggle file explorer";
+ }
+ {
+ key = "<c-c>";
+ action = "<cmd>NotificationsClear<cr>";
+ options.desc = "Clear notifications";
+ }
+ ];
+}
diff --git a/modules/development/nixvim/plugins/cmp.nix b/modules/development/nixvim/plugins/cmp.nix
new file mode 100644
index 0000000..683e0d3
--- /dev/null
+++ b/modules/development/nixvim/plugins/cmp.nix
@@ -0,0 +1,37 @@
+{ config, lib, ... }:
+
+# Cmp - Completion plugin (nvim-cmp) for auto-completion
+{
+ config.programs.nixvim.plugins.cmp = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ autoEnableSources = true;
+ settings = {
+ snippet.expand = "function(args) require('luasnip').lsp_expand(args.body) end";
+ mapping = {
+ "<C-Space>" = "cmp.mapping.complete()";
+ "<CR>" = "cmp.mapping.confirm({ select = true })";
+ "<Tab>" = "cmp.mapping.select_next_item()";
+ "<S-Tab>" = "cmp.mapping.select_prev_item()";
+ "<Down>" = "cmp.mapping.select_next_item()";
+ "<Up>" = "cmp.mapping.select_prev_item()";
+ "<C-u>" = "cmp.mapping.scroll_docs(-4)"; # scroll docs up
+ "<C-d>" = "cmp.mapping.scroll_docs(4)"; # scroll docs down
+
+ "<Escape>" = ''
+ cmp.mapping(function(fallback)
+ if cmp.visible() then
+ cmp.abort()
+ else
+ fallback()
+ end
+ end, { "i" })
+ '';
+ };
+ sources = [
+ { name = "nvim_lsp"; }
+ { name = "path"; }
+ { name = "buffer"; }
+ ];
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/comment.nix b/modules/development/nixvim/plugins/comment.nix
new file mode 100644
index 0000000..cc1b9cb
--- /dev/null
+++ b/modules/development/nixvim/plugins/comment.nix
@@ -0,0 +1,23 @@
+{ config, lib, ... }:
+
+# Comment - Comment toggling plugin (comment.nvim)
+{
+ config.programs.nixvim.plugins.comment = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ settings = {
+ toggler = {
+ line = "gcc"; # toggle line comment
+ block = "gbc"; # toggle block comment
+ };
+ opleader = {
+ line = "gc"; # line comment operator (gc + motion)
+ block = "gb"; # block comment operator (gb + motion)
+ };
+ extra = {
+ above = "gcO"; # add comment line above
+ below = "gco"; # add comment line below
+ eol = "gcA"; # add comment at end of line
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/default.nix b/modules/development/nixvim/plugins/default.nix
new file mode 100644
index 0000000..a263c51
--- /dev/null
+++ b/modules/development/nixvim/plugins/default.nix
@@ -0,0 +1,20 @@
+{ ... }:
+
+# Plugins - Collection of nixvim plugin configurations
+{
+ imports = [
+ ./cmp.nix
+ ./comment.nix
+ ./gitsigns.nix
+ ./indent-blankline.nix
+ ./lsp.nix
+ ./lualine.nix
+ ./luasnip.nix
+ ./noice.nix
+ ./nvim-tree.nix
+ ./telescope.nix
+ ./treesitter.nix
+ ./web-devicons.nix
+ ./which-key.nix
+ ];
+}
diff --git a/modules/development/nixvim/plugins/gitsigns.nix b/modules/development/nixvim/plugins/gitsigns.nix
new file mode 100644
index 0000000..ea99eba
--- /dev/null
+++ b/modules/development/nixvim/plugins/gitsigns.nix
@@ -0,0 +1,8 @@
+{ config, lib, ... }:
+
+# Gitsigns - Git status in the sign column (gitsigns.nvim)
+{
+ config.programs.nixvim.plugins.gitsigns = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ };
+}
diff --git a/modules/development/nixvim/plugins/indent-blankline.nix b/modules/development/nixvim/plugins/indent-blankline.nix
new file mode 100644
index 0000000..eb2674a
--- /dev/null
+++ b/modules/development/nixvim/plugins/indent-blankline.nix
@@ -0,0 +1,14 @@
+{ config, lib, ... }:
+
+# Indent-blankline - Visual indentation guides (indent-blankline.nvim)
+{
+ config.programs.nixvim.plugins.indent-blankline = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ settings = {
+ indent = {
+ char = "┊";
+ tab_char = "│";
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/lsp.nix b/modules/development/nixvim/plugins/lsp.nix
new file mode 100644
index 0000000..7fc3ddd
--- /dev/null
+++ b/modules/development/nixvim/plugins/lsp.nix
@@ -0,0 +1,234 @@
+{ config, lib, ... }:
+
+# LSP - Language Server Protocol configuration (nvim-lspconfig)
+{
+ config.programs.nixvim.plugins.lsp = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ inlayHints = true;
+ autoLoad = true;
+
+ keymaps.lspBuf = {
+ K = "hover";
+ gD = "references";
+ gd = "definition";
+ gi = "implementation";
+ gt = "type_definition";
+ };
+
+ servers = {
+ # -- System & Configuration --
+ nixd = {
+ enable = true;
+ package = null;
+ }; # Nix
+ bashls = {
+ enable = true;
+ package = null;
+ }; # Bash/Shell
+ taplo = {
+ enable = true;
+ package = null;
+ }; # TOML
+ yamlls = {
+ enable = true;
+ package = null;
+ }; # YAML
+ jsonls = {
+ enable = true;
+ package = null;
+ }; # JSON
+ marksman = {
+ enable = true;
+ package = null;
+ }; # Markdown
+
+ # -- Web Development (HTML/CSS/JS/TS) --
+ html = {
+ enable = true;
+ package = null;
+ }; # HTML
+ cssls = {
+ enable = true;
+ package = null;
+ }; # CSS/SCSS/LESS
+ tailwindcss = {
+ enable = true;
+ package = null;
+ }; # Tailwind CSS
+ vtsls = {
+ # JS/TS (Modern fast wrapper for tsserver)
+ enable = true;
+ package = null;
+ settings = {
+ # Optional but recommended: stops huge generic types from taking over your screen
+ vtsls.experimental.maxInlayHintLength = 30;
+
+ # TypeScript type inferences
+ typescript.inlayHints = {
+ parameterNames.enabled = "all";
+ parameterTypes.enabled = true;
+ variableTypes.enabled = true;
+ propertyDeclarationTypes.enabled = true;
+ functionLikeReturnTypes.enabled = true;
+ enumMemberValues.enabled = true;
+ };
+
+ # JavaScript type inferences (via JSDoc)
+ javascript.inlayHints = {
+ parameterNames.enabled = "all";
+ parameterTypes.enabled = true;
+ variableTypes.enabled = true;
+ propertyDeclarationTypes.enabled = true;
+ functionLikeReturnTypes.enabled = true;
+ enumMemberValues.enabled = true;
+ };
+ };
+ };
+ eslint = {
+ enable = true;
+ package = null;
+ }; # ESLint diagnostics/formatting
+
+ # -- Web Frameworks --
+ volar = {
+ # Vue
+ enable = true;
+ package = null;
+ tslsIntegration = false;
+ };
+ svelte = {
+ enable = true;
+ package = null;
+ }; # Svelte
+ astro = {
+ enable = true;
+ package = null;
+ }; # Astro
+
+ # -- Scripting & High-Level Languages --
+ basedpyright = {
+ # Python (Modern, faster fork of Pyright)
+ enable = true;
+ package = null;
+ settings.basedpyright.analysis.inlayHints = {
+ variableTypes = true;
+ callArgumentNames = true;
+ functionReturnTypes = true;
+ genericTypes = false; # can get noisy, opt-in
+ };
+ };
+ ruff = {
+ enable = true;
+ package = null;
+ }; # Python (Ultra-fast linter/formatter)
+ ruby_lsp = {
+ enable = true;
+ package = null;
+ }; # Ruby (Shopify's modern standard)
+ lua_ls = {
+ # Lua
+ enable = true;
+ package = null;
+ settings.Lua.hint = {
+ enable = true;
+ arrayIndex = "Auto";
+ setType = true;
+ paramName = "All";
+ paramType = true;
+ };
+ };
+ intelephense = {
+ enable = true;
+ package = null;
+ }; # PHP
+ elixirls = {
+ enable = true;
+ package = null;
+ }; # Elixir
+
+ # -- Systems, Compiled, & Enterprise --
+ clangd = {
+ enable = true;
+ package = null;
+ }; # C/C++ (inlay hints on by default)
+ rust_analyzer = {
+ # Rust (inlay hints on by default)
+ enable = true;
+ package = null;
+ installCargo = false;
+ installRustc = false;
+ };
+ gopls = {
+ # Go
+ enable = true;
+ package = null;
+ settings.gopls.hints = {
+ assignVariableTypes = true;
+ compositeLiteralFields = true;
+ compositeLiteralTypes = true;
+ constantValues = true;
+ functionTypeParameters = true;
+ parameterNames = true;
+ rangeVariableTypes = true;
+ };
+ };
+ zls = {
+ enable = true;
+ package = null;
+ }; # Zig (inlay hints on by default)
+ jdtls = {
+ # Java
+ enable = true;
+ package = null;
+ settings.java.inlayHints.parameterNames.enabled = "all";
+ };
+ kotlin_language_server = {
+ enable = true;
+ package = null;
+ }; # Kotlin
+ csharp_ls = {
+ enable = true;
+ package = null;
+ }; # C# (.NET) — no inlay hint support
+ hls = {
+ # Haskell
+ enable = true;
+ package = null;
+ installGhc = false;
+ settings.haskell.plugin."inlay-hints".globalOn = true;
+ };
+ ocamllsp = {
+ enable = true;
+ package = null;
+ }; # OCaml
+
+ # -- Infrastructure & DevOps --
+ dockerls = {
+ enable = true;
+ package = null;
+ }; # Dockerfile
+ docker_compose_language_service = {
+ enable = true;
+ package = null;
+ }; # Docker Compose
+ terraformls = {
+ enable = true;
+ package = null;
+ }; # Terraform/HCL
+
+ # -- Data & APIs --
+ sqlls = {
+ enable = true;
+ package = null;
+ }; # SQL
+ graphql = {
+ enable = true;
+ package = null;
+ }; # GraphQL
+ prismals = {
+ enable = true;
+ package = null;
+ }; # Prisma ORM
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/lualine.nix b/modules/development/nixvim/plugins/lualine.nix
new file mode 100644
index 0000000..72f34be
--- /dev/null
+++ b/modules/development/nixvim/plugins/lualine.nix
@@ -0,0 +1,90 @@
+{ config, lib, ... }:
+
+# Lualine - Statusline configuration (lualine.nvim)
+{
+ config.programs.nixvim.plugins.lualine = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ settings = {
+ options = {
+ theme = with config.scheme.withHashtag; {
+ normal = {
+ a = {
+ fg = base00;
+ bg = base0D;
+ gui = "bold";
+ };
+ b = {
+ fg = base05;
+ bg = base01;
+ };
+ c = {
+ fg = base05;
+ bg = base00;
+ };
+ };
+ insert = {
+ a = {
+ fg = base00;
+ bg = base0B;
+ gui = "bold";
+ };
+ b = {
+ fg = base05;
+ bg = base01;
+ };
+ c = {
+ fg = base05;
+ bg = base00;
+ };
+ };
+ visual = {
+ a = {
+ fg = base00;
+ bg = base0A;
+ gui = "bold";
+ };
+ b = {
+ fg = base05;
+ bg = base01;
+ };
+ c = {
+ fg = base05;
+ bg = base00;
+ };
+ };
+ replace = {
+ a = {
+ fg = base00;
+ bg = base08;
+ gui = "bold";
+ };
+ b = {
+ fg = base05;
+ bg = base01;
+ };
+ c = {
+ fg = base05;
+ bg = base00;
+ };
+ };
+ inactive = {
+ a = {
+ fg = base04;
+ bg = base00;
+ gui = "bold";
+ };
+ b = {
+ fg = base04;
+ bg = base00;
+ };
+ c = {
+ fg = base04;
+ bg = base00;
+ };
+ };
+ };
+ icons_enabled = true;
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/luasnip.nix b/modules/development/nixvim/plugins/luasnip.nix
new file mode 100644
index 0000000..60571e9
--- /dev/null
+++ b/modules/development/nixvim/plugins/luasnip.nix
@@ -0,0 +1,8 @@
+{ config, lib, ... }:
+
+# Luasnip - Snippet engine for Neovim (Lua-based)
+{
+ config.programs.nixvim.plugins.luasnip = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ };
+}
diff --git a/modules/development/nixvim/plugins/noice.nix b/modules/development/nixvim/plugins/noice.nix
new file mode 100644
index 0000000..d466506
--- /dev/null
+++ b/modules/development/nixvim/plugins/noice.nix
@@ -0,0 +1,8 @@
+{ config, lib, ... }:
+
+# Noice - Modern UI for Neovim (cmdline, popupmenu, messages)
+{
+ config.programs.nixvim.plugins.noice = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ };
+}
diff --git a/modules/development/nixvim/plugins/nvim-tree.nix b/modules/development/nixvim/plugins/nvim-tree.nix
new file mode 100644
index 0000000..2ad6570
--- /dev/null
+++ b/modules/development/nixvim/plugins/nvim-tree.nix
@@ -0,0 +1,44 @@
+{ config, lib, ... }:
+
+# Nvim-tree - File explorer sidebar (nvim-tree.lua)
+{
+ config.programs.nixvim.plugins.nvim-tree = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ settings = {
+ filters = {
+ dotfiles = false;
+ git_clean = false;
+ no_buffer = false;
+ custom = { };
+ };
+ git = {
+ enable = true;
+ ignore = false;
+ };
+ view = {
+ width = 30;
+ };
+ renderer = {
+ indent_markers = {
+ enable = true;
+ inline_arrows = false;
+ icons = {
+ corner = "└";
+ edge = "│";
+ item = "├";
+ bottom = "─";
+ none = " ";
+ };
+ };
+ icons = {
+ show = {
+ folder = true;
+ folder_arrow = false;
+ file = true;
+ git = true;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/telescope.nix b/modules/development/nixvim/plugins/telescope.nix
new file mode 100644
index 0000000..b9678fc
--- /dev/null
+++ b/modules/development/nixvim/plugins/telescope.nix
@@ -0,0 +1,85 @@
+{ config, lib, ... }:
+
+# Telescope - Fuzzy finder
+{
+ config.programs.nixvim.plugins.telescope = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ extensions = {
+ fzf-native.enable = true; # faster fuzzy sorting
+ ui-select.enable = true; # use telescope for vim.ui.select (code actions etc.)
+ };
+ settings = {
+ defaults = {
+ layout_strategy = "horizontal";
+ layout_config = {
+ horizontal = {
+ preview_width = 0.55;
+ results_width = 0.45;
+ };
+ width = 0.87;
+ height = 0.80;
+ };
+ mappings = {
+ i = {
+ "<C-k>".__raw = "require('telescope.actions').move_selection_previous";
+ "<C-j>".__raw = "require('telescope.actions').move_selection_next";
+ "<Escape>".__raw = "require('telescope.actions').close";
+ };
+ };
+ };
+ };
+ keymaps = {
+ # Files
+ "<leader>ff" = {
+ action = "find_files";
+ options.desc = "Find files";
+ };
+ "<leader>fg" = {
+ action = "live_grep";
+ options.desc = "Live grep";
+ };
+ "<leader>fb" = {
+ action = "buffers";
+ options.desc = "Find buffers";
+ };
+ "<leader>fr" = {
+ action = "oldfiles";
+ options.desc = "Recent files";
+ };
+
+ # LSP
+ "<leader>fd" = {
+ action = "diagnostics";
+ options.desc = "Diagnostics";
+ };
+ "<leader>fs" = {
+ action = "lsp_document_symbols";
+ options.desc = "Document symbols";
+ };
+
+ # Git
+ "<leader>gc" = {
+ action = "git_commits";
+ options.desc = "Git commits";
+ };
+ "<leader>gb" = {
+ action = "git_branches";
+ options.desc = "Git branches";
+ };
+
+ # Misc
+ "<leader>fh" = {
+ action = "help_tags";
+ options.desc = "Help tags";
+ };
+ "<leader>fc" = {
+ action = "commands";
+ options.desc = "Commands";
+ };
+ "<leader>fk" = {
+ action = "keymaps";
+ options.desc = "Find keymaps";
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/treesitter.nix b/modules/development/nixvim/plugins/treesitter.nix
new file mode 100644
index 0000000..035ac7a
--- /dev/null
+++ b/modules/development/nixvim/plugins/treesitter.nix
@@ -0,0 +1,19 @@
+{ config, lib, ... }:
+
+# Treesitter - Syntax highlighting and parsing (nvim-treesitter)
+{
+ config.programs.nixvim.plugins.treesitter = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ folding = {
+ enable = true;
+ };
+ settings = {
+ highlight = {
+ enable = true;
+ };
+ indent = {
+ enable = true;
+ };
+ };
+ };
+}
diff --git a/modules/development/nixvim/plugins/web-devicons.nix b/modules/development/nixvim/plugins/web-devicons.nix
new file mode 100644
index 0000000..3c6ad86
--- /dev/null
+++ b/modules/development/nixvim/plugins/web-devicons.nix
@@ -0,0 +1,8 @@
+{ config, lib, ... }:
+
+# Web-devicons - File icons for various file types (nvim-web-devicons)
+{
+ config.programs.nixvim.plugins.web-devicons = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ };
+}
diff --git a/modules/development/nixvim/plugins/which-key.nix b/modules/development/nixvim/plugins/which-key.nix
new file mode 100644
index 0000000..18018e7
--- /dev/null
+++ b/modules/development/nixvim/plugins/which-key.nix
@@ -0,0 +1,21 @@
+{ config, lib, ... }:
+
+# Which-key - Popup for keybindings (which-key.nvim)
+{
+ config.programs.nixvim.plugins.which-key = lib.mkIf config.programs.nixvim.enable {
+ enable = true;
+ settings = {
+ plugins = {
+ marks = true;
+ registers = true;
+ spelling = {
+ enabled = true;
+ suggestions = 20;
+ };
+ };
+ win = {
+ border = "single";
+ };
+ };
+ };
+}
diff --git a/modules/development/opencode/default.nix b/modules/development/opencode/default.nix
new file mode 100644
index 0000000..0b3f0b6
--- /dev/null
+++ b/modules/development/opencode/default.nix
@@ -0,0 +1,19 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+# Opencode - AI-powered coding assistant (opencode.ai)
+{
+ config = lib.mkIf config.programs.opencode.enable {
+ programs.opencode = {
+ package = pkgs.opencode;
+ };
+
+ xdg.mimeApps.defaultApplications = {
+ "x-scheme-handler/opencode" = "opencode.desktop";
+ };
+ };
+}
diff --git a/modules/development/qemu/default.nix b/modules/development/qemu/default.nix
new file mode 100644
index 0000000..b34264c
--- /dev/null
+++ b/modules/development/qemu/default.nix
@@ -0,0 +1,30 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+# QEMU - generic and open source machine & userspace emulator and virtualizer.
+{
+ options.programs.qemu = {
+ enable = lib.mkEnableOption "Enables qemu.";
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.symlinkJoin {
+ name = "qemu-bundle";
+ paths = with pkgs; [
+ qemu
+ libvirt
+ virtiofsd
+ virt-manager
+ ];
+ };
+ description = "Bundle of QEMU-related packages.";
+ };
+ };
+
+ config = lib.mkIf config.programs.qemu.enable {
+ home.packages = [ config.programs.qemu.package ];
+ };
+}
diff --git a/modules/development/vscodium/default.nix b/modules/development/vscodium/default.nix
new file mode 100644
index 0000000..a8cbd37
--- /dev/null
+++ b/modules/development/vscodium/default.nix
@@ -0,0 +1,20 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+# VSCodium - Visual Studio Code fork
+{
+ config = lib.mkIf config.programs.vscodium.enable {
+ programs.vscodium = {
+ package = pkgs.vscodium;
+ };
+
+ xdg.mimeApps.defaultApplications = {
+ "x-scheme-handler/vscodium" = "vscodium.desktop";
+ "text/plain" = "vscodium.desktop";
+ };
+ };
+}