# Editor: Neovim via nixvim. Migrated from plain vim with feature parity (file # tree, indent guides, fugitive, tmux-navigator, Catppuccin Mocha, 2-space hard # tabs, Jenkinsfile=groovy) plus a real LSP stack in place of the inert ALE. # Wanted on every host; vi/vim/$EDITOR all launch nvim. { inputs, pkgs, ... }: { imports = [ inputs.nixvim.homeModules.nixvim ]; programs.nixvim = { enable = true; viAlias = true; vimAlias = true; defaultEditor = true; # Build against our (followed) nixpkgs; set explicitly so the module doesn't # warn that its pinned nixpkgs was overridden by the input `follows`. nixpkgs.source = inputs.nixpkgs; # Formatter binaries for conform-nvim (below), matching the repo's treefmt # set. On nvim's PATH only. extraPackages = with pkgs; [ nixfmt stylua ruff shfmt prettier gofumpt ]; globals.mapleader = " "; opts = { expandtab = false; tabstop = 2; shiftwidth = 2; termguicolors = true; background = "dark"; number = true; }; colorschemes.catppuccin = { enable = true; settings.flavour = "mocha"; }; plugins = { nvim-tree.enable = true; # file explorer (was nerdtree) web-devicons.enable = true; # nvim-tree icons (explicit; else auto-enabled with a warning) indent-blankline.enable = true; # indent guides (was vim-indent-guides) fugitive.enable = true; # git (was vim-fugitive) tmux-navigator.enable = true; # Ctrl-h/j/k/l across vim splits and tmux panes # Highlighting/indent — the Neovim-native replacement for `syntax enable`. treesitter = { enable = true; settings.ensure_installed = [ "nix" "lua" "bash" "markdown" "groovy" "c_sharp" # C# "python" "terraform" # also covers HCL "yaml" # Helm chart templates/values ]; }; # LSP + completion, replacing the (inert) ALE. lsp = { enable = true; # Universal servers. Host-specific ones are enabled in their own module: # C# (omnisharp) and Helm (helm_ls) live in work.nix (EDaaS only). servers = { nil_ls.enable = true; # Nix lua_ls.enable = true; # Lua (editing this config) pyright.enable = true; # Python terraformls.enable = true; # Terraform }; keymaps.lspBuf = { gd = "definition"; gr = "references"; K = "hover"; "rn" = "rename"; "ca" = "code_action"; }; }; cmp = { enable = true; autoEnableSources = true; settings = { # nvim-cmp ships no default keymaps; without these the menu shows but # nothing accepts it. confirm uses select=false so a bare stays a # newline unless an entry is explicitly highlighted. mapping = { "" = "cmp.mapping.select_next_item()"; "" = "cmp.mapping.select_prev_item()"; "" = "cmp.mapping.select_next_item()"; "" = "cmp.mapping.select_prev_item()"; "" = "cmp.mapping.confirm({ select = false })"; "" = "cmp.mapping.complete()"; "" = "cmp.mapping.abort()"; }; snippet.expand = "function(args) require('luasnip').lsp_expand(args.body) end"; sources = [ { name = "nvim_lsp"; } { name = "luasnip"; } { name = "buffer"; } { name = "path"; } ]; }; }; # Fuzzy finder (files / live grep / symbols); rg + fd are already on PATH. telescope = { enable = true; extensions.fzf-native.enable = true; }; gitsigns.enable = true; # gutter signs, stage-hunk, blame which-key.enable = true; # popup of pending keybindings (leader is Space) trouble.enable = true; # project-wide diagnostics/quickfix list lualine = { enable = true; settings.options.theme = "catppuccin-mocha"; }; comment.enable = true; # gc / gcc comment toggling nvim-autopairs.enable = true; treesitter-textobjects.enable = true; luasnip.enable = true; # snippet engine (drives cmp's luasnip source above) # Format-on-save, mirroring the repo's treefmt set. Filetypes with no # formatter here (e.g. terraform) fall back to the LSP formatter. conform-nvim = { enable = true; settings = { formatters_by_ft = { nix = [ "nixfmt" ]; lua = [ "stylua" ]; python = [ "ruff_format" ]; sh = [ "shfmt" ]; markdown = [ "prettier" ]; go = [ "gofumpt" ]; }; format_on_save = { timeout_ms = 2000; lsp_format = "fallback"; }; }; }; }; keymaps = [ { mode = "n"; key = ",,"; action = "NvimTreeToggle"; options.desc = "Toggle file tree"; } { mode = "n"; key = "ff"; action = "Telescope find_files"; options.desc = "Find files"; } { mode = "n"; key = "fg"; action = "Telescope live_grep"; options.desc = "Live grep"; } { mode = "n"; key = "fb"; action = "Telescope buffers"; options.desc = "Buffers"; } { mode = "n"; key = "xx"; action = "Trouble diagnostics toggle"; options.desc = "Diagnostics list"; } ]; # au BufNewFile,BufRead *Jenkinsfile setf groovy autoCmd = [ { event = [ "BufNewFile" "BufRead" ]; pattern = [ "*Jenkinsfile" ]; command = "setf groovy"; } ]; }; }