{ pkgs, ... }:

with builtins;
{
  config.home-manager.users.moritz.programs.neovim.lazy.plugins = with pkgs.vimPlugins; [
    {
      plugin = oil-nvim;
      lazy = false;
      opts = { };
      dependencies = [
        { plugin = which-key-nvim; }
        { plugin = nvim-web-devicons; }
      ];
    }
    {
      plugin = mini-nvim;
      lazy = false;
      conf = readFile ./lua/mini-nvim.lua;
    }
    {
      plugin = trouble-nvim;
      cmd = [ "TodoTelescope" ];
      keys = [
        { key = "<leader>cD"; cmd = "<cmd>TroubleToggle document_diagnostics<cr>"; desc = "Document Diagnostics (Trouble)"; }
        { key = "<leader>cW"; cmd = "<cmd>TroubleToggle workspace_diagnostics<cr>"; desc = "Workspace Diagnostics (Trouble)"; }
        { key = "<leader>cl"; cmd = "<cmd>TroubleToggle loclist<cr>"; desc = "Location List (Trouble)"; }
        { key = "<leader>cq"; cmd = "<cmd>TroubleToggle quickfix<cr>"; desc = "Quickfix List (Trouble)"; }
        { key = "<leader>ft"; cmd = "<cmd>TodoTelescope<cr>"; desc = "Todo"; }
        {
          key = "[q";
          func = /* lua */ ''
            function()
              if require("trouble").is_open() then
                require("trouble").previous({ skip_groups = true, jump = true })
              else
                vim.cmd.cprev()
              end
            end
          '';
          desc = "Previous trouble/quickfix item";
        }
        {
          key = "]q";
          func = /* lua */  ''
            function()
              if require("trouble").is_open() then
                require("trouble").next({ skip_groups = true, jump = true })
              else
                vim.cmd.cnext()
              end
            end
          '';
          desc = "Next trouble/quickfix item";
        }
      ];
      opts = { };
      dependencies = [
        { plugin = nvim-web-devicons; }
      ];
    }
    {
      plugin = nvim-cmp;
      keys = [
        { key = "<leader>tc"; cmd = "<cmd>CmpToggle<cr>"; desc = "Toggle Cmp sources"; }
      ];
      conf = readFile ./lua/nvim-cmp.lua;
      event = [ "InsertEnter" ];
      dependencies = [
        {
          plugin = nvim-autopairs;
          opts = { };
        }
        { plugin = cmp-async-path; }
        { plugin = cmp-buffer; }
        { plugin = cmp-cmdline; }
        { plugin = cmp-nvim-lsp; }
        { plugin = cmp_luasnip; }
        {
          plugin = codeium-nvim;
          opts = { };
        }
        { plugin = friendly-snippets; }
        { plugin = lspkind-nvim; }
        { plugin = luasnip; }
      ];
    }
    {
      plugin = direnv-vim;
      lazy = false;
    }
    {
      plugin = nvim-lspconfig;
      event = [ "BufRead" "BufNewFile" ];
      conf = readFile ./lua/nvim-lspconfig.lua;
      dependencies = [
        {
          plugin = null-ls-nvim;
          conf = readFile ./lua/null-ls-nvim.lua;
          dependencies = [
            { plugin = which-key-nvim; }
            { plugin = plenary-nvim; }
          ];
        }
        { plugin = which-key-nvim; }
        { plugin = lsp_lines-nvim; }
        {
          plugin = nvim-ufo;
          conf = readFile ./lua/nvim-ufo.lua;
          dependencies = [
            { plugin = promise-async; }
          ];
        }
        {
          plugin = neodev-nvim;
          conf = readFile ./lua/neodev-nvim.lua;
        }
        {
          plugin = inc-rename-nvim;
          opts = {
            input_buffer_type = "dressing";
          };
          dependencies = [
            { plugin = dressing-nvim; }
          ];
        }
        { plugin = actions-preview-nvim; }
      ];
    }
    {
      plugin = vim-fugitive;
      cmd = [
        "G"
        "Git"
        "Ggrep"
        "Glgrep"
        "Gclog"
        "Gllog"
        "Gcd"
        "Glcd"
        "Gedit"
        "Gsplit"
        "Gvsplit"
        "Gtabedit"
        "Gpedit"
        "Gdrop"
        "Gread"
        "Gwrite"
        "Gwq"
        "Gdiffsplit"
        "Gvdiffsplit"
        "GMove"
        "GRename"
        "GDelete"
        "GBrowse"
      ];
    }
    {
      plugin = vim-tmux-navigator;
      event = [ "VeryLazy" ];
    }
    {
      plugin = nvim-lastplace;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = {
        lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ];
        lastplace_ignore_filetype = [ "gitcommit" "gitrebase" "svn" "hgcommit" ];
        lastplace_open_folds = true;
      };
    }
    {
      plugin = telescope-nvim;
      cmd = [ "Telescope" ];
      conf = builtins.readFile ./lua/telescope.lua;
      keys = [
        { key = "<leader>ff"; cmd = "<cmd>Telescope find_files<cr>"; desc = "Find files"; }
        { key = "<leader>fb"; cmd = "<cmd>Telescope buffers<cr>"; desc = "Find buffers"; }
        { key = "<leader>fl"; cmd = "<cmd>Telescope current_buffer_fuzzy_find<cr>"; desc = "Search lines"; }
        { key = "<leader>fg"; cmd = "<cmd>Telescope live_grep<cr>"; desc = "Live grep"; }
        { key = "<leader>fh"; cmd = "<cmd>Telescope help_tags<cr>"; desc = "Help tags"; }
      ];
      dependencies = [
        { plugin = plenary-nvim; }
        { plugin = telescope-fzf-native-nvim; }
      ];
    }
    {
      plugin = vim-startuptime;
      cmd = [ "StartupTime" ];
      conf = readFile ./lua/vim-startuptime.lua;
    }
    {
      plugin = typst-vim;
      ft = [ "typst" "typ" ];
    }
    {
      plugin = comment-nvim;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = { };
    }
    {
      plugin = telekasten-nvim;
      dependencies = [
        { plugin = telescope-nvim; }
        { plugin = which-key-nvim; }
        {
          plugin = markdown-preview-nvim;
          ft = [ "md" ];
        }
      ];
      cmd = [ "Telekasten" ];
      keys = [
        { key = "<leader>fz"; cmd = "<cmd>Telekasten<cr>"; desc = "Zettelkasten"; }
      ];
      conf = builtins.readFile ./lua/zettelkasten-nvim.lua;
    }
    {
      plugin = nvim-surround;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = { };
    }
    {
      plugin = zen-mode-nvim;
      keys = [
        { key = "<leader>tz"; cmd = "<cmd>ZenMode<cr>"; desc = "Zen mode"; }
      ];
      conf = /* lua */ ''
        require("zen-mode").setup({
          plugins = {
            tmux = {
              enabled = true,
            },
          },
        })
      '';
      dependencies = [
        {
          plugin = twilight-nvim;
          conf = /* lua */ ''
            require("twilight").setup({
              context = 20,
              expand = { -- for treesitter, we we always try to expand to the top-most ancestor with these types
                  "function",
                  "function_definition",
                  "if_statement",
                  "method",
                  "method_definition",
                  "table",
                },
            })
          '';
        }
      ];
    }
    {
      plugin = refactoring-nvim;
      keys = [
        {
          key = "<leader>cR";
          cmd = "<cmd>lua require('telescope').extensions.refactoring.refactors()<cr>";
          desc = "Refactor";
          mode = [ "x" "n" ];
        }
      ];
      dependencies = [
        { plugin = which-key-nvim; }
        { plugin = plenary-nvim; }
        { plugin = nvim-lspconfig; }
      ];
      opts = { };
    }
    {
      plugin = harpoon;
      keys = [
        { key = "<leader>ha"; cmd = "<cmd>lua require('harpoon.mark').add_file()<cr>"; desc = "Add file"; }
        { key = "<leader>hh"; cmd = "<cmd>lua require('harpoon.ui').toggle_quick_menu()<cr>"; desc = "Harpoon"; }
        { key = "<leader>1"; cmd = "<cmd>lua require('harpoon.ui').nav_file(1)<cr>"; desc = "Harpoon file 1"; }
        { key = "<leader>2"; cmd = "<cmd>lua require('harpoon.ui').nav_file(2)<cr>"; desc = "Harpoon file 2"; }
        { key = "<leader>3"; cmd = "<cmd>lua require('harpoon.ui').nav_file(3)<cr>"; desc = "Harpoon file 3"; }
        { key = "<leader>4"; cmd = "<cmd>lua require('harpoon.ui').nav_file(4)<cr>"; desc = "Harpoon file 4"; }
      ];
      opts = { };
      init = /* lua */ ''
        require("which-key").register({
          ["<leader>h"] = {
            name = "harpoon",
          },
        })
      '';
      dependencies = [
        { plugin = which-key-nvim; }
      ];
    }
    {
      plugin = nvim-puppeteer;
      lazy = false; # NOTE: plugin lazy-loads itself.
    }
    {
      plugin = neotest;
      keys = [
        { key = "<leader>ct"; cmd = "<cmd>lua require('neotest').summary.toggle()<cr>"; desc = "Test"; }
      ];
      dependencies = [
        { plugin = plenary-nvim; }
        { plugin = FixCursorHold-nvim; }

        # adapters
        { plugin = neotest-python; }
      ];
      conf = readFile ./lua/neotest.lua;
    }
    {
      plugin = conform-nvim;
      keys = [
        { key = "="; cmd = "<cmd>lua require('conform').format()<cr>"; desc = "format buffer"; mode = [ "n" "v" ]; }
      ];
      cmd = [ "ConformInfo" "Format" ];
      conf = readFile ./lua/conform.lua;
    }
    {
      plugin = neogen;
      keys = [
        { key = "<leader>cg"; cmd = "<cmd>Neogen<cr>"; desc = "Test"; }
      ];
      opts = {
        languages = {
          python = {
            template = {
              annotation_convention = "reST";
            };
          };
        };
      };
      cmd = [ "Neogen" ];
    }
  ];
}
