From b4f0765591a47634404ef212a3c8eba9280ca526 Mon Sep 17 00:00:00 2001 From: emmatherock Date: Sat, 29 Aug 2026 13:09:27 -0300 Subject: [PATCH] feat(neovim): add Neovim configuration and integrate with home profiles --- flake.nix | 5 + home/emmatherock/neovim.nix | 203 +++++++++++++++++++++++++++++++++ hosts/miku-homelab/default.nix | 1 + hosts/vps/default.nix | 3 +- 4 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 home/emmatherock/neovim.nix diff --git a/flake.nix b/flake.nix index df51811..145d20d 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,7 @@ url = "github:gmodena/nix-flatpak/?ref=latest"; }; vscode-server.url = "github:nix-community/nixos-vscode-server"; + nixvim.url = "github:nix-community/nixvim"; llm-agents.url = "github:numtide/llm-agents.nix"; nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; agenix = { @@ -53,6 +54,7 @@ home-manager.extraSpecialArgs = { inherit inputs; }; home-manager.sharedModules = [ plasma-manager.homeModules.plasma-manager + inputs.nixvim.homeModules.nixvim ]; home-manager.users.emmatherock = { osConfig, ... }: { imports = [ ./home/emmatherock/core.nix ] ++ osConfig.myHomeProfile.extraPrograms; @@ -74,6 +76,9 @@ home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.extraSpecialArgs = { inherit inputs; }; + home-manager.sharedModules = [ + inputs.nixvim.homeModules.nixvim + ]; home-manager.users.emmatherock = { osConfig, ... }: { imports = [ ./home/emmatherock/core.nix ] ++ osConfig.myHomeProfile.extraPrograms; }; diff --git a/home/emmatherock/neovim.nix b/home/emmatherock/neovim.nix new file mode 100644 index 0000000..7660b44 --- /dev/null +++ b/home/emmatherock/neovim.nix @@ -0,0 +1,203 @@ +# Declarative Neovim config via nixvim. Goal: a real, lean IDE — not a +# feature-for-feature VSCode clone. Every plugin here earns its place. + +{ pkgs, ... }: + +{ + programs.nixvim = { + enable = true; + defaultEditor = true; + vimAlias = true; # `vim` -> nvim, handy when SSH'd into the VPS/homelab + + colorschemes.catppuccin = { + enable = true; + settings.flavour = "mocha"; + }; + + globals.mapleader = " "; + + opts = { + number = true; + relativenumber = true; + shiftwidth = 2; + tabstop = 2; + expandtab = true; + termguicolors = true; + signcolumn = "yes"; + scrolloff = 8; + }; + + # --- File explorer --- + plugins.neo-tree = { + enable = true; + settings.window.width = 30; + }; + + # --- Fuzzy finder: files, grep, buffers, LSP symbols --- + plugins.telescope = { + enable = true; + extensions.fzf-native.enable = true; + }; + + # --- Treesitter: syntax highlighting/parsing for your stack --- + plugins.treesitter = { + enable = true; + settings.ensure_installed = [ + "nix" "bash" "lua" "markdown" "json" "yaml" + "rust" "go" "gomod" "c" "cpp" "c_sharp" "python" + "javascript" "typescript" "tsx" "vue" "html" "css" + ]; + }; + + # --- LSP: one server per language/toolchain you use --- + plugins.lsp = { + enable = true; + servers = { + nixd.enable = true; + bashls.enable = true; + rust_analyzer = { + enable = true; + installCargo = true; + installRustc = true; + }; + gopls.enable = true; + clangd.enable = true; # C / C++ + csharp_ls.enable = true; + pyright.enable = true; + ts_ls.enable = true; # JS/TS, React + volar.enable = true; # Vue + html.enable = true; + cssls.enable = true; + tailwindcss.enable = true; + jsonls.enable = true; + }; + keymaps.lspBuf = { + "gd" = "definition"; + "gr" = "references"; + "K" = "hover"; + "rn" = "rename"; + "ca" = "code_action"; + }; + }; + + # --- Autocompletion --- + plugins.cmp = { + enable = true; + settings.sources = [ + { name = "nvim_lsp"; } + { name = "path"; } + { name = "buffer"; } + ]; + }; + plugins.cmp-nvim-lsp.enable = true; + plugins.cmp-path.enable = true; + plugins.cmp-buffer.enable = true; + + # --- Format on save --- + plugins.conform-nvim = { + enable = true; + settings = { + format_on_save = { + lsp_fallback = true; + timeout_ms = 500; + }; + formatters_by_ft = { + rust = [ "rustfmt" ]; + go = [ "gofmt" ]; + c = [ "clang-format" ]; + cpp = [ "clang-format" ]; + python = [ "black" ]; + javascript = [ "prettier" ]; + typescript = [ "prettier" ]; + javascriptreact = [ "prettier" ]; + typescriptreact = [ "prettier" ]; + vue = [ "prettier" ]; + nix = [ "nixpkgs-fmt" ]; + }; + }; + }; + + # --- Git: gutter signs, hunk stage/reset, blame --- + plugins.gitsigns.enable = true; + + # --- Statusline --- + plugins.lualine.enable = true; + + # --- Discoverable keybindings while you're still learning --- + plugins.which-key.enable = true; + + # --- AI agent: CodeCompanion, curated natively in nixvim --- + # Configured to reuse your existing `claude`/`gemini` CLI auth via ACP + # adapters instead of a separate Anthropic Console API key. + # + # Verified against https://codecompanion.olimorris.dev/configuration/adapters-acp + # (CodeCompanion >= v18.0.0, which is what's pinned by nixvim's nixpkgs as of + # 2026-08). Two things changed from an older/assumed layout: + # - the default-adapter key is `interactions.chat.adapter`, not + # `strategies.chat.adapter` (renamed in v18.0.0); + # - the built-in adapter names are `claude_code` and `gemini_cli` (no + # `_acp` suffix) and live under `adapters.acp.`. + # + # Neither adapter has a true zero-config mode that silently piggybacks on + # an already-logged-in CLI session: + # - gemini_cli: `defaults.auth_method = "oauth-personal"` reuses the + # `gemini` CLI's own login — no key needed, closest thing to "just + # use my existing session". + # - claude_code: there's no oauth-personal equivalent. Run + # `claude setup-token` once (ties to your Pro/Max subscription rather + # than a Console API key) and save the result to + # ~/.config/codecompanion/claude-oauth-token (chmod 600, outside the + # nix store). It's read at runtime via the `cmd:` prefix below rather + # than embedded in this file. + plugins.codecompanion = { + enable = true; + settings = { + interactions.chat.adapter = "claude_code"; # switch to "gemini_cli" per-chat + adapters.acp = { + claude_code.__raw = '' + function() + return require("codecompanion.adapters").extend("claude_code", { + env = { + CLAUDE_CODE_OAUTH_TOKEN = "cmd:cat ~/.config/codecompanion/claude-oauth-token", + }, + }) + end + ''; + gemini_cli.__raw = '' + function() + return require("codecompanion.adapters").extend("gemini_cli", { + defaults = { + auth_method = "oauth-personal", + }, + }) + end + ''; + }; + }; + }; + + # --- Editor-level tooling only: formatters conform.nvim shells out to. + # Language toolchains themselves (cargo, go, dotnet-sdk, nodejs, + # a compiler, a python interpreter) come from your per-project + # nix-shell / flake devShell, not from here — launch nvim from + # inside that shell (`nix develop`, or nix-shell + direnv) so LSP + # servers resolve the right toolchain via PATH. + extraPackages = with pkgs; [ + python3Packages.black + prettier + nixpkgs-fmt + ]; + + keymaps = [ + { mode = "n"; key = "e"; action = "Neotree toggle"; } + { mode = "n"; key = "ff"; action = "Telescope find_files"; } + { mode = "n"; key = "fg"; action = "Telescope live_grep"; } + { mode = "n"; key = "fb"; action = "Telescope buffers"; } + + # CodeCompanion + { mode = [ "n" "v" ]; key = "ac"; action = "CodeCompanionChat Toggle"; } + { mode = "v"; key = "aa"; action = "CodeCompanionChat Add"; } + { mode = "n"; key = "ai"; action = "CodeCompanion"; } # inline assistant + ]; + }; +} diff --git a/hosts/miku-homelab/default.nix b/hosts/miku-homelab/default.nix index 772e0d6..4ee7778 100644 --- a/hosts/miku-homelab/default.nix +++ b/hosts/miku-homelab/default.nix @@ -27,6 +27,7 @@ ../../home/emmatherock/deskflow.nix ../../home/emmatherock/gaming.nix ../../home/emmatherock/media.nix + ../../home/emmatherock/neovim.nix ../../home/emmatherock/packages.nix ../../home/emmatherock/plasma.nix ../../home/emmatherock/vscode.nix diff --git a/hosts/vps/default.nix b/hosts/vps/default.nix index 2768b71..985065b 100644 --- a/hosts/vps/default.nix +++ b/hosts/vps/default.nix @@ -11,8 +11,9 @@ age.secrets.vps-wg.file = ../../secrets/vps-wg.age; - myHomeProfile.extraPrograms = [ + myHomeProfile.extraPrograms = [ ../../home/emmatherock/agents.nix + ../../home/emmatherock/neovim.nix ]; myNetworking = {