{ inputs, pkgs, lib, ... }:
{
  programs.neovim =
  let 
    toLua = str: "lua << EOF\n${str}\nEOF\n";
    toLuaFile = file: "lua << EOF\n${builtins.readFile file}\nEOF\n";
    fromGitHub = rev: ref: repo: pkgs.vimUtils.buildVimPlugin {
      pname = "${lib.strings.sanitizeDerivationName repo}";
      version = ref;
      src = builtins.fetchGit {
        url = "https://github.com/${repo}.git";
        ref = ref;
        rev = rev;
      };
    };
  in
  {
    enable = true;

    viAlias = true;
    vimAlias = true;
    vimdiffAlias = true;

    defaultEditor = true;

    plugins = with pkgs.vimPlugins; [
      # Colorschemes
      {
        plugin = catppuccin-nvim;
        config = toLuaFile ./plugins/colorschemes/catppuccin.lua;
      }

      # LSP
      {
        plugin = nvim-lspconfig;
        config = toLuaFile ./plugins/lsp.lua;
      }

      cmp-buffer
      cmp-cmdline
      cmp-nvim-lsp
      cmp-nvim-lua
      cmp-path
      cmp_luasnip
      luasnip
      nvim-cmp

      # The rest
      {
        plugin = indent-blankline-nvim;
        config = toLuaFile ./plugins/indent.lua;
      }

      # HTML
      
      {
        plugin = nvim-ts-autotag;
        config = toLuaFile ./plugins/autotag.lua;
      }

      {
        plugin = nvim-colorizer-lua;
        config = toLuaFile ./plugins/colorizer.lua;
      }

      # GIT
      {
        plugin = gitsigns-nvim;
        config = toLuaFile ./plugins/gitsigns.lua;
      }

      vim-fugitive

      {
        plugin = (fromGitHub "3af6232c8d39d51062702e875ff6407c1eeb0391" "main" "xiyaowong/transparent.nvim");
        config = toLuaFile ./plugins/transparent.lua;
      }
      
      {
        plugin = presence-nvim;
        config = toLuaFile ./plugins/presence.lua;
      }

      {
        plugin = comment-nvim;
        config = toLuaFile ./plugins/comment.lua;
      }
        
      {
        plugin = which-key-nvim;
        config = toLuaFile ./plugins/whichkey.lua;
      }

      {
        plugin = nvim-autopairs;
        config = toLuaFile ./plugins/autopairs.lua;
      }

      {
        plugin = (nvim-treesitter.withPlugins (p: [
          p.tree-sitter-nix
          p.tree-sitter-c
          p.tree-sitter-lua
          p.tree-sitter-vim
          p.tree-sitter-python
          p.tree-sitter-html
          p.tree-sitter-go
          p.tree-sitter-javascript
          p.tree-sitter-toml
          p.tree-sitter-css
          p.tree-sitter-gitignore
          p.tree-sitter-gitcommit
          p.tree-sitter-git_rebase
          p.tree-sitter-cpp
          p.tree-sitter-dockerfile
          p.tree-sitter-c_sharp
          p.tree-sitter-jq
          p.tree-sitter-jsonnet
          p.tree-sitter-rust
          p.tree-sitter-ruby
          p.tree-sitter-solidity
          p.tree-sitter-sql
          p.tree-sitter-yaml
        ]));
        config = toLuaFile ./plugins/treesitter.lua;
      }

      {
        plugin = toggleterm-nvim;
        config = toLuaFile ./plugins/toggleterm.lua;
      }

      {
        plugin = nvim-tree-lua;
        config = toLuaFile ./plugins/nvimtree.lua;
      }

      {
        plugin = bufferline-nvim;
        config = toLuaFile ./plugins/bufferline.lua;
      }

      {
        plugin = lualine-nvim;
        config = toLuaFile ./plugins/lualine.lua;
      }

      {
        plugin = telescope-nvim;
        config = toLuaFile ./plugins/telescope.lua;
      }

      {
        plugin = telescope-nvim;
        config = toLuaFile ./plugins/telescope.lua;
      }

      {
        plugin = dashboard-nvim;
        config = toLuaFile ./plugins/dashboard.lua;
      }

      {
        plugin = nvim-web-devicons;
        config = toLuaFile ./plugins/nvim-web-devicons.lua;
      }

    ];

    extraLuaConfig = ''
      ${builtins.readFile ./core/colors.lua}
      ${builtins.readFile ./core/functions.lua}
      ${builtins.readFile ./core/keymaps.lua}
      ${builtins.readFile ./core/options.lua}
    '';

    extraPackages = with pkgs; [
      lua-language-server
      nodePackages_latest.vscode-langservers-extracted
      nixd
    ];
  };
}