Enable neovim through home-manager

- We need to set the default editor to just "nvim" not a particular path, as
  this allows us to override nvim in our home
- Add the mapleader bind to the start of init.vim
- As the leader is interpreted whenever we make a keybind, we must have it at
  the start or it won't be respected for some of our keybinds (but will be for
  others)
- Package the scrollbar plugin and install it
- Setup configs for stuff like treesitter, theme, COC, scrollbar etc.
- Add git capabilities to neovim
- Install fugitive, gitgutter and git-conflict, along with some other basic git
  stuff
- Allow mouse control in neovim
diff --git a/modules/neovim/airline/default.nix b/modules/neovim/airline/default.nix
new file mode 100644
index 0000000..bd1d1ce
--- /dev/null
+++ b/modules/neovim/airline/default.nix
@@ -0,0 +1,18 @@
+{
+  pkgs,
+  lib,
+  ...
+}: {
+  programs.neovim = {
+    plugins = with pkgs.vimPlugins; [
+      airline
+      vim-airline-clock
+    ];
+    extraConfig = lib.pipe [./tabline.vim ./theme.vim ./parts.vim] [
+      (map builtins.readFile)
+      (builtins.concatStringsSep "\n")
+    ];
+  };
+
+  home.file.".config/nvim/autoload/airline/themes/onehalf.vim".source = ./onehalf-dark-airline.vim;
+}
diff --git a/modules/neovim/airline/onehalf-dark-airline.vim b/modules/neovim/airline/onehalf-dark-airline.vim
new file mode 100644
index 0000000..3495a4b
--- /dev/null
+++ b/modules/neovim/airline/onehalf-dark-airline.vim
@@ -0,0 +1,40 @@
+let g:airline#themes#onehalf#palette = {}
+    function! airline#themes#onehalf#refresh()
+
+    function! s:generateAirlinePalette(primary)
+    return {
+        \ 'airline_a'      : [g:black.gui, a:primary.gui, g:black.cterm, a:primary.cterm],
+        \ 'airline_b'      : [g:white.gui, g:lightgrey.gui, g:white.cterm, g:lightgrey.cterm],
+        \ 'airline_c'      : [a:primary.gui, g:statusline.gui, a:primary.cterm, g:statusline.cterm],
+        \ 'airline_x'      : [a:primary.gui, g:statusline.gui, a:primary.cterm, g:statusline.cterm],
+        \ 'airline_y'      : [g:white.gui, g:lightgrey.gui, g:white.cterm, g:lightgrey.cterm],
+        \ 'airline_z'      : [g:black.gui, a:primary.gui, g:black.cterm, a:primary.cterm],
+        \ 'airline_warning': [g:black.gui, g:yellow.gui, g:black.cterm, g:yellow.cterm],
+        \ 'airline_error'  : [g:black.gui, g:red.gui, g:black.cterm, g:red.cterm]}
+    endfunction
+
+    let g:airline#themes#onehalf#palette.normal      = s:generateAirlinePalette(g:green)
+    let g:airline#themes#onehalf#palette.visual      = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.select      = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.multi       = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.insert      = s:generateAirlinePalette(g:yellow)
+    let g:airline#themes#onehalf#palette.commandline = s:generateAirlinePalette(g:red)
+    let g:airline#themes#onehalf#palette.terminal    = s:generateAirlinePalette(g:cyan)
+    let g:airline#themes#onehalf#palette.replace     = s:generateAirlinePalette(g:blue)
+    let g:airline#themes#onehalf#palette.inactive    = s:generateAirlinePalette(g:white)
+    let g:airline#themes#onehalf#palette.normal_modified      = s:generateAirlinePalette(g:green)
+    let g:airline#themes#onehalf#palette.visual_modified      = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.select_modified      = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.multi_modified       = s:generateAirlinePalette(g:purple)
+    let g:airline#themes#onehalf#palette.insert_modified      = s:generateAirlinePalette(g:yellow)
+    let g:airline#themes#onehalf#palette.commandline_modified = s:generateAirlinePalette(g:red)
+    let g:airline#themes#onehalf#palette.terminal_modified    = s:generateAirlinePalette(g:cyan)
+    let g:airline#themes#onehalf#palette.replace_modified     = s:generateAirlinePalette(g:blue)
+
+
+    let g:airline#themes#onehalf#palette.tabline = {
+        \ 'airline_tabtype' : [g:white.gui, g:lightgrey.gui, g:white.cterm, g:lightgrey.cterm]}
+
+    endfunction
+
+    call airline#themes#onehalf#refresh()
diff --git a/modules/neovim/airline/parts.vim b/modules/neovim/airline/parts.vim
new file mode 100644
index 0000000..34e07e6
--- /dev/null
+++ b/modules/neovim/airline/parts.vim
@@ -0,0 +1,17 @@
+set statusline=%t       "tail of the filename
+        set statusline+=[%{strlen(&fenc)?&fenc:'none'}, "file encoding
+        set statusline+=%{&ff}] "file format
+        set statusline+=%h      "help file flag
+        set statusline+=%m      "modified flag
+        set statusline+=%r      "read only flag
+        set statusline+=%y      "filetype
+        set statusline+=%=      "left/right separator
+        set statusline+=%c,     "cursor column
+        set statusline+=%l/%L   "cursor line/total lines
+        set statusline+=\ %P    "percent through file
+" TODO: Check if this is actually used with airline
+
+let g:airline#extensions#hunks#coc_git = 1
+let g:airline#extensions#whitespace#enabled = 1
+let g:airline#parts#ffenc#skip_expected_string='utf-8[unix]'
+let g:airline_skip_empty_sections = 1
diff --git a/modules/neovim/airline/tabline.vim b/modules/neovim/airline/tabline.vim
new file mode 100644
index 0000000..9ff7315
--- /dev/null
+++ b/modules/neovim/airline/tabline.vim
@@ -0,0 +1,16 @@
+let g:airline#extensions#tabline#enabled = 1
+let g:airline#extensions#tabline#formatter = 'unique_tail_improved'
+let g:airline#extensions#tabline#buffer_idx_mode = 1
+
+nmap <leader>1 <Plug>AirlineSelectTab1
+nmap <leader>2 <Plug>AirlineSelectTab2
+nmap <leader>3 <Plug>AirlineSelectTab3
+nmap <leader>4 <Plug>AirlineSelectTab4
+nmap <leader>5 <Plug>AirlineSelectTab5
+nmap <leader>6 <Plug>AirlineSelectTab6
+nmap <leader>7 <Plug>AirlineSelectTab7
+nmap <leader>8 <Plug>AirlineSelectTab8
+nmap <leader>9 <Plug>AirlineSelectTab9
+nmap <leader>0 <Plug>AirlineSelectTab0
+nmap <leader>- <Plug>AirlineSelectPrevTab
+nmap <leader>+ <Plug>AirlineSelectNextTab
diff --git a/modules/neovim/airline/theme.vim b/modules/neovim/airline/theme.vim
new file mode 100644
index 0000000..29cd139
--- /dev/null
+++ b/modules/neovim/airline/theme.vim
@@ -0,0 +1,3 @@
+let g:airline_theme = "onehalf"
+let g:airline_highlighting_cache = 1
+let g:airline_powerline_fonts = 1
diff --git a/modules/neovim/binds/binds.vim b/modules/neovim/binds/binds.vim
new file mode 100644
index 0000000..c26e705
--- /dev/null
+++ b/modules/neovim/binds/binds.vim
@@ -0,0 +1,19 @@
+set whichwrap=b,s,<,>,[,]
+set mouse=a
+
+vnoremap // y/\V<C-R>=escape(@",'/\')<CR><CR>
+
+fun! SetupCommandAlias(from, to)
+    exec 'cnoreabbrev <expr> '.a:from
+    \ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
+    \ .'? ("'.a:to.'") : ("'.a:from.'"))'
+endfun
+
+command W w
+command Wq wq
+call SetupCommandAlias("git","Git")
+
+set ignorecase
+set smartcase
+
+set expandtab
diff --git a/modules/neovim/binds/default.nix b/modules/neovim/binds/default.nix
new file mode 100644
index 0000000..bcf254d
--- /dev/null
+++ b/modules/neovim/binds/default.nix
@@ -0,0 +1,3 @@
+{
+  programs.neovim.extraConfig = builtins.readFile ./binds.vim;
+}
diff --git a/modules/neovim/coc/default.nix b/modules/neovim/coc/default.nix
new file mode 100644
index 0000000..fc6f72d
--- /dev/null
+++ b/modules/neovim/coc/default.nix
@@ -0,0 +1,47 @@
+{
+  pkgs,
+  lib,
+  ...
+}: {
+  programs.neovim = {
+    coc = {
+      enable = true;
+      settings = {
+        "suggest.noselect" = false;
+        "cSpell.checkOnlyEnabledfileTypes" = false;
+        "rust-analyzer.serverPath" = "${pkgs.rust-analyzer}/bin/rust-analyzer";
+        languageserver = {
+          nix = {
+            command = "${pkgs.rnix-lsp}/bin/rnix-lsp";
+            filetypes = ["nix"];
+          };
+        };
+      };
+    };
+    plugins = with pkgs.vimPlugins; [
+      # Language servers
+      coc-tsserver
+      coc-eslint
+      coc-rust-analyzer
+      coc-json
+      coc-jest
+      coc-css
+
+      # Spellchecker
+      coc-spell-checker # FIXME: Broken in upstream, needs an overlay
+
+      # File explorer
+      coc-explorer
+      coc-git # TODO: Check if coc-git is still needed
+
+      # Snippet completion
+      coc-snippets
+      vim-snippets
+    ];
+    extraConfig = lib.pipe [./keybinds.vim ./theme.vim] [
+      (map builtins.readFile)
+      (builtins.concatStringsSep "\n")
+    ];
+    extraPackages = [pkgs.nodejs pkgs.rustc];
+  };
+}
diff --git a/modules/neovim/coc/keybinds.vim b/modules/neovim/coc/keybinds.vim
new file mode 100644
index 0000000..8e5c0c1
--- /dev/null
+++ b/modules/neovim/coc/keybinds.vim
@@ -0,0 +1,16 @@
+nmap <silent> ]c :call CocAction('diagnosticNext')<cr>
+nmap <silent> [c :call CocAction('diagnosticPrevious')<cr>
+nmap <silent> <Leader>fs <Plug>(coc-codeaction-selected)
+nmap <silent> <Leader>fg <Plug>(coc-codeaction-cursor)
+nmap <silent> <Leader>ff <Plug>(coc-codeaction)
+nmap <Leader>fe <Cmd>CocCommand explorer<CR>
+
+function! s:show_documentation()
+if (index(['vim','help'], &filetype) >= 0)
+execute 'h '.expand('<cword>')
+else
+call CocAction('doHover')
+endif
+endfunction
+
+nnoremap <silent> K :call <SID>show_documentation()<CR>
diff --git a/modules/neovim/coc/theme.vim b/modules/neovim/coc/theme.vim
new file mode 100644
index 0000000..92506a4
--- /dev/null
+++ b/modules/neovim/coc/theme.vim
@@ -0,0 +1,3 @@
+highlight CocErrorSign   ctermfg=168 guifg=#e06c75 ctermbg=NONE guibg=NONE
+highlight CocInfoSign    ctermfg=75  guifg=#61afef ctermbg=NONE guibg=NONE
+highlight CocWarningSign ctermfg=180 guifg=#e5c07b ctermbg=NONE guibg=NONE
diff --git a/modules/neovim/git/binds.vim b/modules/neovim/git/binds.vim
new file mode 100644
index 0000000..50c4821
--- /dev/null
+++ b/modules/neovim/git/binds.vim
@@ -0,0 +1,20 @@
+let mapleader = ","
+set whichwrap=b,s,<,>,[,]
+set mouse=a
+
+vnoremap // y/\V<C-R>=escape(@",'/\')<CR><CR>
+
+fun! SetupCommandAlias(from, to)
+    exec 'cnoreabbrev <expr> '.a:from
+    \ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
+    \ .'? ("'.a:to.'") : ("'.a:from.'"))'
+endfun
+
+command W w
+command Wq wq
+call SetupCommandAlias("git","Git")
+
+set ignorecase
+set smartcase
+
+set expandtab
diff --git a/modules/neovim/git/default.nix b/modules/neovim/git/default.nix
new file mode 100644
index 0000000..30ebf70
--- /dev/null
+++ b/modules/neovim/git/default.nix
@@ -0,0 +1,18 @@
+{pkgs, lib, ...}: {
+  programs.neovim = {
+    extraConfig = ''
+      source ${./git-conflict.lua}
+    '' + lib.pipe [
+      ./lazygit.vim
+    ] [
+      (map builtins.readFile)
+      (builtins.concatStringsSep "\n")
+    ];
+    plugins = with pkgs.vimPlugins; [
+      vim-gitgutter
+      vim-fugitive
+      lazygit-nvim
+      pkgs.git-conflict-nvim
+    ];
+  };
+}
diff --git a/modules/neovim/git/git-conflict.lua b/modules/neovim/git/git-conflict.lua
new file mode 100644
index 0000000..0c2c14c
--- /dev/null
+++ b/modules/neovim/git/git-conflict.lua
@@ -0,0 +1 @@
+require('git-conflict').setup()
diff --git a/modules/neovim/git/lazygit.vim b/modules/neovim/git/lazygit.vim
new file mode 100644
index 0000000..ade20d6
--- /dev/null
+++ b/modules/neovim/git/lazygit.vim
@@ -0,0 +1,2 @@
+nnoremap <silent> <leader>gg :LazyGit<CR>
+
diff --git a/modules/neovim/indentation/default.nix b/modules/neovim/indentation/default.nix
new file mode 100644
index 0000000..722d39e
--- /dev/null
+++ b/modules/neovim/indentation/default.nix
@@ -0,0 +1,13 @@
+{pkgs, ...}: {
+  programs.neovim = {
+    extraConfig =
+      builtins.readFile ./indentation.vim
+      + ''
+        source ${./indentation.lua}
+      '';
+    plugins = with pkgs.vimPlugins; [
+      vim-sleuth
+      indent-blankline-nvim
+    ];
+  };
+}
diff --git a/modules/neovim/indentation/indentation.lua b/modules/neovim/indentation/indentation.lua
new file mode 100644
index 0000000..633aae5
--- /dev/null
+++ b/modules/neovim/indentation/indentation.lua
@@ -0,0 +1,18 @@
+vim.opt.list = true
+vim.opt.listchars:append "space:⋅"
+vim.opt.listchars:append "eol:↴"
+vim.opt.listchars:append "tab:――➤"
+
+require("indent_blankline").setup {
+    space_char_blankline = " ",
+    show_current_context = true,
+    show_current_context_start = true,
+    char_highlight_list = {
+        "IndentBlanklineIndent1",
+        "IndentBlanklineIndent2",
+        "IndentBlanklineIndent3",
+        "IndentBlanklineIndent4",
+        "IndentBlanklineIndent5",
+        "IndentBlanklineIndent6",
+    },
+}
diff --git a/modules/neovim/indentation/indentation.vim b/modules/neovim/indentation/indentation.vim
new file mode 100644
index 0000000..54812cc
--- /dev/null
+++ b/modules/neovim/indentation/indentation.vim
@@ -0,0 +1,12 @@
+set tabstop=4
+set shiftwidth=0
+set ve+=onemore
+
+exec "highlight IndentBlanklineContextChar ctermfg=" . g:white.cterm . " guifg=" . g:white.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineContextStart ctermfg=NONE guifg=NONE guisp=white ctermbg=NONE guibg=NONE gui=underline term=underline"
+exec "highlight IndentBlanklineIndent1 ctermfg=" . g:darkred.cterm . " guifg=" . g:darkred.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineIndent2 ctermfg=" . g:darkyellow.cterm . " guifg=" . g:darkyellow.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineIndent3 ctermfg=" . g:darkgreen.cterm . " guifg=" . g:darkgreen.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineIndent4 ctermfg=" . g:darkcyan.cterm . " guifg=" . g:darkcyan.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineIndent5 ctermfg=" . g:darkblue.cterm . " guifg=" . g:darkblue.gui . " ctermbg=NONE guibg=NONE"
+exec "highlight IndentBlanklineIndent6 ctermfg=" . g:darkpurple.cterm . " guifg=" . g:darkpurple.gui . " ctermbg=NONE guibg=NONE"
diff --git a/modules/neovim/neoformat/default.nix b/modules/neovim/neoformat/default.nix
new file mode 100644
index 0000000..c280010
--- /dev/null
+++ b/modules/neovim/neoformat/default.nix
@@ -0,0 +1,18 @@
+{
+  pkgs,
+  lib,
+  ...
+}: {
+  programs.neovim = {
+    plugins = with pkgs.vimPlugins; [
+      neoformat
+    ];
+    extraConfig = builtins.readFile ./setup.vim;
+    extraPackages = with pkgs; [
+      nodePackages.prettier
+      alejandra
+      rustfmt
+      shfmt
+    ];
+  };
+}
diff --git a/modules/neovim/neoformat/setup.vim b/modules/neovim/neoformat/setup.vim
new file mode 100644
index 0000000..e92db5a
--- /dev/null
+++ b/modules/neovim/neoformat/setup.vim
@@ -0,0 +1,4 @@
+" autocmd BufWritePre * undojoin | try | undojoin | Neoformat | catch /^Vim\%((\a\+)\)\=:E790/ | finally | silent Neoformat | endtry
+
+let g:shfmt_opt="-ci"
+let g:neoformat_try_node_exe = 1
diff --git a/modules/neovim/theme/default.nix b/modules/neovim/theme/default.nix
new file mode 100644
index 0000000..168e464
--- /dev/null
+++ b/modules/neovim/theme/default.nix
@@ -0,0 +1,8 @@
+{pkgs, ...}: {
+  programs.neovim = {
+    plugins = with pkgs.vimPlugins; [onehalf nvim-hlslens pkgs.nvim-scrollbar];
+    extraConfig = builtins.readFile ./theme.vim + ''
+      source ${./scrollbar.lua}
+    '';
+  };
+}
diff --git a/modules/neovim/theme/scrollbar.lua b/modules/neovim/theme/scrollbar.lua
new file mode 100644
index 0000000..90d9701
--- /dev/null
+++ b/modules/neovim/theme/scrollbar.lua
@@ -0,0 +1,31 @@
+local kopts = {noremap = true, silent = true}
+
+vim.api.nvim_set_keymap('n', 'n',
+    [[<Cmd>execute('normal! ' . v:count1 . 'n')<CR><Cmd>lua require('hlslens').start()<CR>]],
+    kopts)
+vim.api.nvim_set_keymap('n', 'N',
+    [[<Cmd>execute('normal! ' . v:count1 . 'N')<CR><Cmd>lua require('hlslens').start()<CR>]],
+    kopts)
+vim.api.nvim_set_keymap('n', '*', [[*<Cmd>lua require('hlslens').start()<CR>]], kopts)
+vim.api.nvim_set_keymap('n', '#', [[#<Cmd>lua require('hlslens').start()<CR>]], kopts)
+vim.api.nvim_set_keymap('n', 'g*', [[g*<Cmd>lua require('hlslens').start()<CR>]], kopts)
+vim.api.nvim_set_keymap('n', 'g#', [[g#<Cmd>lua require('hlslens').start()<CR>]], kopts)
+
+vim.api.nvim_set_keymap('n', '<Leader>l', ':noh<CR>', kopts)
+
+require("scrollbar").setup({
+  handle = {
+    color = vim.g["lightgrey"].gui,
+  },
+  marks = {
+    Search = { color = vim.g["yellow"].gui },
+    Error = { color = vim.g["red"].gui },
+    Warn = { color = vim.g["red"].gui },
+    Info = { color = vim.g["blue"].gui },
+    Hint = { color = vim.g["cyan"].gui },
+    Misc = { color = vim.g["purple"].gui },
+  },
+  handlers = {
+    search = true,
+  },
+})
diff --git a/modules/neovim/theme/theme.vim b/modules/neovim/theme/theme.vim
new file mode 100644
index 0000000..0dfbeb0
--- /dev/null
+++ b/modules/neovim/theme/theme.vim
@@ -0,0 +1,37 @@
+if exists('+termguicolors')
+  let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
+  let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
+  set termguicolors
+endif
+colorscheme onehalfdark
+
+highlight Pmenu  ctermfg=188 guifg=#dcdfe4 ctermbg=239 guibg=#474e5d
+highlight PmenuSel   ctermfg=236 guifg=#282c34 ctermbg=75  guibg=#61afef
+highlight PmenuSbar  ctermfg=237 guifg=#313640 ctermbg=237 guibg=#313640
+highlight PmenuThumb ctermfg=188 guifg=#dcdfe4 ctermbg=188 guibg=#dcdfe4
+
+set signcolumn=yes
+set guicursor=v-r-cr:hor50,i:ver50
+set splitright
+set splitbelow
+set scrolloff=3
+set number
+
+" guifg guibg ctermfg ctermbg
+let g:black       = { "gui": "#282c34", "cterm": "236" }
+let g:red         = { "gui": "#e06c75", "cterm": "168" }
+let g:green       = { "gui": "#98c379", "cterm": "114" }
+let g:yellow      = { "gui": "#e5c07b", "cterm": "180" }
+let g:blue        = { "gui": "#61afef", "cterm": "75"  }
+let g:purple      = { "gui": "#c678dd", "cterm": "176" }
+let g:cyan        = { "gui": "#56b6c2", "cterm": "73"  }
+let g:statusline  = { "gui": "#313640", "cterm": "237" }
+let g:lightgrey   = { "gui": "#474e5d", "cterm": "237" }
+let g:darkred     = { "gui": "#844C55", "cterm": "167" }
+let g:darkyellow  = { "gui": "#877658", "cterm": "136" }
+let g:darkgreen   = { "gui": "#607857", "cterm": "71"  }
+let g:darkcyan    = { "gui": "#3F717B", "cterm": "31"  }
+let g:darkblue    = { "gui": "#456E92", "cterm": "31"  }
+let g:darkpurple  = { "gui": "#775289", "cterm": "127" }
+let g:white       = { "gui": "#dcdfe4", "cterm": "188" }
+
diff --git a/modules/neovim/tree-sitter/default.nix b/modules/neovim/tree-sitter/default.nix
new file mode 100644
index 0000000..d4b96de
--- /dev/null
+++ b/modules/neovim/tree-sitter/default.nix
@@ -0,0 +1,20 @@
+{
+  pkgs,
+  lib,
+  ...
+}: {
+  programs.neovim = {
+    plugins = with pkgs.vimPlugins; [
+      (nvim-treesitter.withPlugins (plugins:
+        (builtins.attrValues plugins)
+        ++ (with pkgs.vimPlugins; [
+          nvim-ts-rainbow
+          nvim-treesitter-refactor
+        ])))
+      nvim-treesitter-context
+    ];
+    extraConfig = ''
+      source ${./setup.lua}
+    '';
+  };
+}
diff --git a/modules/neovim/tree-sitter/setup.lua b/modules/neovim/tree-sitter/setup.lua
new file mode 100644
index 0000000..b281245
--- /dev/null
+++ b/modules/neovim/tree-sitter/setup.lua
@@ -0,0 +1,82 @@
+require('nvim-treesitter.configs').setup {
+  highlight = {
+    enable = true,
+    additional_vim_regex_highlighting = {'org'},
+  },
+  rainbow = {
+    enable = true,
+    extended_mode = true,
+    max_file_lines = nil,
+    colors = {
+      "#e06c75",
+      "#e5c07b",
+      "#98c379",
+      "#56b6c2",
+      "#61afef",
+      "#c678dd",
+    },
+    termcolors = {
+      "168",
+      "180",
+      "114",
+      "73",
+      "75",
+      "176",
+    },
+  },
+  incremental_selection = {
+    enable = true,
+    keymaps = {
+      init_selection = "gnn",
+      node_incremental = "grn",
+      scope_incremental = "grc",
+      node_decremental = "grm",
+    },
+  },
+  indent = {
+    enable = true,
+  },
+  refactor = {
+    highlight_definitions = {
+      enable = true,
+      clear_on_cursor_move = true,
+    },
+    smart_rename = {
+      enable = true,
+      keymaps = {
+        smart_rename = "<leader>fr",
+      },
+    },
+    navigation = {
+      enable = true,
+      keymaps = {
+        goto_definition = "<leader>gd",
+        list_definitions = "<leader>gD",
+        list_definitions_toc = "<leader>ggD",
+        goto_next_usage = "<leader>g]",
+        goto_previous_usage = "<leader>g[",
+      },
+    },
+
+  },
+}
+
+require('treesitter-context').setup{
+  enable = true,
+  trim_scope = 'outer',
+  patterns = {
+    default = {
+      'class',
+      'function',
+      'method',
+      'for',
+      'while',
+      'if',
+      'switch',
+      'case',
+    },
+  },
+  mode = 'topline'
+}
+
+vim.cmd[[hi! TreesitterContext guibg=#313640 ctermbg=237]]
diff --git a/modules/neovim/zzz_earlyload/default.nix b/modules/neovim/zzz_earlyload/default.nix
new file mode 100644
index 0000000..bb2381d
--- /dev/null
+++ b/modules/neovim/zzz_earlyload/default.nix
@@ -0,0 +1,6 @@
+# The vim modules are sorted reverse alphabetically, so any extraConfig that is
+# put in here should hopefully be the first thing to be loaded. I'm using it to
+# set stuff like my mapleader
+{
+  programs.neovim.extraConfig = builtins.readFile ./settings.vim;
+}
diff --git a/modules/neovim/zzz_earlyload/settings.vim b/modules/neovim/zzz_earlyload/settings.vim
new file mode 100644
index 0000000..22dde51
--- /dev/null
+++ b/modules/neovim/zzz_earlyload/settings.vim
@@ -0,0 +1 @@
+let mapleader=","