{ pkgs, home, ... }:
{
  home.sessionVariables = { EDITOR = "vim"; };

  home.packages = with pkgs; [ nixfmt git ];

  programs.neovim = {
    enable = true;
    viAlias = true;
    vimAlias = true;
    vimdiffAlias = true;

    coc.enable = true;

    withPython3 = true;
    plugins = with pkgs.vimPlugins; [
      #theme
      dracula-vim

      # LSP
      nvim-lspconfig
      plenary-nvim

      #Telescope
      telescope-nvim

      nvim-web-devicons


      (nvim-treesitter.withPlugins (ps: with ps; [
        tree-sitter-nix
        tree-sitter-python
        tree-sitter-svelte
      ]))


      bufferline-nvim
      galaxyline-nvim
      nvim-colorizer-lua
      pears-nvim
#      dusk-vim
      nvim-tree-lua

      vim-lastplace
      vim-nix
      lean-nvim
      vim-nixhash
      vim-yaml
      vim-toml
      vim-airline
      vim-devicons
      zig-vim
      vim-scriptease
      semshi
      coc-nvim
      coc-rust-analyzer
      rust-vim
    ];

    extraPackages = with pkgs; [ rust-analyzer ];

    extraConfig = ''
        syntax on
      " This has to be defined at the top of the file
        let maplocalleader = "\<Space>\<Space>"
        let mapleader = "\<Space>"

        colorscheme dracula

        set scrolloff=4

      " noswapfile
      " nobackup
      " undodir=~/.vim/undodir
      " undofile
      " spell

      " Search case sensitivity
        set smartcase
        set ignorecase

      " No error bells
        set noerrorbells


      " GoTo code navigation.
      nmap <silent> gd <Plug>(coc-definition)
      nmap <silent> gy <Plug>(coc-type-definition)
      nmap <silent> gi <Plug>(coc-implementation)
      nmap <silent> gr <Plug>(coc-references)
      " Use K to show documentation in preview window.
      nnoremap <silent> K :call <SID>show_documentation()<CR>
      " Flex
        nnoremap <C-s> gg0<C-v>G$y<C-v>G$r Go<esc>0"_Dp$pgg$p

      " Correct my typos
        command W :w
        command Wq :wq
        command WQ :wq

      " Move text arround
        vnoremap J :m '>+1<CR>gv=gv
        vnoremap K :m '<-2<CR>gv=gv
        inoremap <C-j> <esc>:m .+1<CR>==i
        inoremap <C-k> <esc>:m .-2<CR>==i
        nnoremap <leader>j :m .+1<CR>==
        nnoremap <leader>k :m .-2<CR>==

      " Completion
        set wildmenu
        set completeopt=longest,menuone

      " Completion in command bar
        set wmnu
        set wildmode=list:longest,list:full
        set wildignore=*.o

      " Command bar
        set history=2000

      " Search
        set incsearch
        set nohlsearch

      " No mouse
      " set mouse=

      " Encoding
        set encoding=utf-8
        set fileencoding=utf-8

      " Make neovim more powerfull
        set nocompatible

      " Allow backspace in insert mode
        set backspace=indent,eol,start

      " Highlight the current line
        set cursorline
        hi CursorLine term=bold cterm=bold ctermbg=darkgrey

      " Line numbers
        set number
        set relativenumber

      " Tabs vs spaces
        set tabstop=2
        set softtabstop=2
        set shiftwidth=2
        set expandtab

      " Auto indent
        set smartindent
        set autoindent

      " Ctrl-T for new tab
        nnoremap <C-t> :tabnew<cr>

      " Delete tralling whitespace on save
        autocmd BufWritePre * %s/\s\+$//e

      " Spell-check
        map <F6> :setlocal spell! spelllang=en_us<CR>
        map <F7> :setlocal spell! spelllang=fr<CR>

      " Line and word count
        map <F3> :!wc <C-R>%<CR>

      " Lean
        lua<<EOF
        local on_attach = function(client, bufnr)
          local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
          local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end

          -- Enable completion triggered by <c-x><c-o>
          buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')

          -- Mappings.
          local opts = { noremap=true, silent=true }

          -- See `:help vim.lsp.*` for documentation on any of the below functions
          buf_set_keymap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
          buf_set_keymap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
          buf_set_keymap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
          buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
          buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
          buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
          buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
          buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
          buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
          buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
          buf_set_keymap('n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
          buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
          buf_set_keymap('n', '<space>e', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
          buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
          buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
          buf_set_keymap('n', '<space>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
          buf_set_keymap('n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)

        end
        require("nvim-tree").setup()
        local builtin = require('telescope.builtin')
        vim.keymap.set('n', 'ff', builtin.find_files, {})
        vim.keymap.set('n', 'fg', builtin.live_grep, {})
        vim.keymap.set('n', 'fb', builtin.buffers, {})
        vim.keymap.set('n', 'fh', builtin.help_tags, {})

        require'nvim-web-devicons'.setup()

      EOF
    '';
  };
}