{
  pkgs,
  lib,
  config,
  nixvimLib,
  ...
}:
let
  nv = nixvimLib.nixvim;
in
{
  config = {
    programs = {
      # https://www.reddit.com/r/neovim/comments/mbj8m5/how_to_setup_ctrlshiftkey_mappings_in_neovim_and/
      alacritty.settings.keyboard.bindings =
        [
          {
            key = "H";
            mods = "Control|Shift";
            chars = "\\u001b[72;5u";
          }
          {
            key = "L";
            mods = "Control|Shift";
            chars = "\\u001b[76;5u";
          }
        ]
        ++ (map (n: {
          key = "Key${builtins.toString n}";
          mods = "Control";
          chars = "\\u001b[${builtins.toString (48 + n)};5u";
        }) (lib.lists.range 0 9));
      # Ctrl+<number> doesn't get interpreted, but Ctrl+Shift+<number> does, so let's use that
      nixvim = {
        autoCmd = [
          # Turn off relativenumber only for insert mode
          {
            event = "InsertEnter";
            pattern = "*";
            command = "set norelativenumber";
          }
          {
            event = "InsertLeave";
            pattern = "*";
            command = "set relativenumber";
          }
        ];
        extraPlugins = with pkgs.vimPlugins; [
          nvim-scrollview # Scroll bar
        ];
        keymaps =
          let
            options = {
              silent = true;
            };
          in
          [
            # barbar
            {
              key = "gb";
              action = "<Cmd>BufferPick<CR>";
              inherit options;
            }
            {
              key = "<C-H>";
              action = "<Cmd>BufferPrevious<CR>";
              inherit options;
            }
            {
              key = "<C-L>";
              action = "<Cmd>BufferNext<CR>";
              inherit options;
            }
            {
              key = "<C-S-H>";
              action = "<Cmd>BufferMovePrevious<CR>";
              inherit options;
            }
            {
              key = "<C-S-L>";
              action = "<Cmd>BufferMoveNext<CR>";
              inherit options;
            }
            {
              key = "<C-0>";
              action = "<Cmd>BufferLast<CR>";
              inherit options;
            }
          ]
          ++ (map (n: {
            key = "<C-${builtins.toString n}>";
            action = "<Cmd>BufferGoto ${builtins.toString n}<CR>";
            inherit options;
          }) (lib.lists.range 1 9));
        opts = {
          showmode = false;
          number = true;
          relativenumber = true;
          title = true;
        };
        plugins = {
          # Tabline
          barbar.enable = true;
          # TODO Reload make it use the preset colorscheme
          # Status line
          lualine =
            with config.lib.stylix.colors.withHashtag;
            let
              normal = {
                fg = base05;
                bg = base01;
              };
              inverted = {
                fg = base00;
                bg = base03;
              };
              normal_ina = {
                fg = base02;
                bg = base01;
              };
              inverted_ina = {
                fg = base00;
                bg = base02;
              };
            in
            {
              enable = true;
              settings = rec {
                inactive_sections = sections;
                sections = {
                  lualine_a = [
                    (nv.listToUnkeyedAttrs [ "string.format('%d', vim.fn.line('$'))" ])
                  ];
                  lualine_b = [ "mode" ];
                  lualine_c = [
                    (
                      (nv.listToUnkeyedAttrs [ "filename" ])
                      // {
                        color = nv.mkRaw ''
                          function(section)
                            return { fg = vim.bo.modified and '${base08}' or '${normal.fg}' }
                          end
                        '';
                        path = 1; # Relative path
                        symbols = {
                          modified = "●";
                          newfile = "󰻭";
                          readonly = "󰏯";
                          unnamed = "󱀶";
                        };
                      }
                    )
                    "location"
                  ];
                  lualine_x =
                    [
                      (
                        (nv.listToUnkeyedAttrs [ ''(next(vim.lsp.buf_get_clients()) == nil) and "󰒲 " or ""'' ])
                        // {
                          separator = {
                            left = "";
                            right = "";
                          };
                        }
                      )
                    ]
                    ++ (lib.mapAttrsToList
                      (
                        diag_name: diag_color:
                        (
                          (nv.listToUnkeyedAttrs [ "diagnostics" ])
                          // {
                            color.bg = diag_color;
                            colored = false;
                            separator = {
                              left = "";
                              right = "";
                            };
                            sections = [ diag_name ];
                          }
                        )
                      )
                      {
                        error = base08;
                        warn = base0A;
                        hint = base0C;
                        info = base0B;
                      }
                    );
                  lualine_y = [
                    (
                      (nv.listToUnkeyedAttrs [ "diff" ])
                      // {
                        diff_color = {
                          added.fg = base0B;
                          modified.fg = base0A;
                          removed.fg = base08;
                        };
                        symbols = {
                          added = " ";
                          modified = " ";
                          removed = " ";
                        };
                      }
                    )
                    "branch"
                  ];
                  lualine_z = [
                    "filetype"
                    "fileformat"
                    "encoding"
                  ];
                };
                options.theme =
                  (lib.mapAttrs
                    (mode_name: mode_color: {
                      a = inverted;
                      b = inverted // {
                        bg = mode_color;
                        gui = "bold";
                      };
                      c = normal;
                      x = inverted;
                      y = normal;
                      z = inverted // {
                        bg = mode_color;
                      };
                    })
                    {
                      normal = base0D;
                      insert = base0B;
                      visual = base0F;
                      replace = base08;
                      command = base0E;
                    }
                  )
                  // {
                    inactive = {
                      a = inverted_ina;
                      b = normal_ina // {
                        bg = base00;
                        gui = "bold";
                      };
                      c = normal_ina;
                      x = inverted_ina;
                      y = normal_ina;
                      z = normal_ina // {
                        bg = base00;
                      };
                    };
                  };
              };
            };
          # Show context on top if scrolled out
          treesitter-context = {
            enable = true;
            settings.max_lines = 5;
          };
          web-devicons.enable = true; # TODO Check out plugins.mini.enable
        };
      };
    };
  };
}