# 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";
          "<leader>rn" = "rename";
          "<leader>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 <CR> stays a
          # newline unless an entry is explicitly highlighted.
          mapping = {
            "<C-n>" = "cmp.mapping.select_next_item()";
            "<C-p>" = "cmp.mapping.select_prev_item()";
            "<Tab>" = "cmp.mapping.select_next_item()";
            "<S-Tab>" = "cmp.mapping.select_prev_item()";
            "<CR>" = "cmp.mapping.confirm({ select = false })";
            "<C-Space>" = "cmp.mapping.complete()";
            "<C-e>" = "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 = "<cmd>NvimTreeToggle<cr>";
        options.desc = "Toggle file tree";
      }
      {
        mode = "n";
        key = "<leader>ff";
        action = "<cmd>Telescope find_files<cr>";
        options.desc = "Find files";
      }
      {
        mode = "n";
        key = "<leader>fg";
        action = "<cmd>Telescope live_grep<cr>";
        options.desc = "Live grep";
      }
      {
        mode = "n";
        key = "<leader>fb";
        action = "<cmd>Telescope buffers<cr>";
        options.desc = "Buffers";
      }
      {
        mode = "n";
        key = "<leader>xx";
        action = "<cmd>Trouble diagnostics toggle<cr>";
        options.desc = "Diagnostics list";
      }
    ];

    # au BufNewFile,BufRead *Jenkinsfile setf groovy
    autoCmd = [
      {
        event = [
          "BufNewFile"
          "BufRead"
        ];
        pattern = [ "*Jenkinsfile" ];
        command = "setf groovy";
      }
    ];
  };
}
