{ config, lib, mylib, pkgs, ... }: let { body = { environment.systemPackages = [ vim-wrapper ]; environment.etc.vimrc.source = vimrc; environment.variables.EDITOR = lib.mkForce "vim"; environment.variables.VIMINIT = ":so /etc/vimrc"; programs.nano.enable = false; }; base-plugins = [ pkgs.tv.vimPlugins.file-line pkgs.tv.vimPlugins.hack pkgs.vimPlugins.undotree (pkgs.tv.vim.makePlugin (pkgs.write "vim-tv-base" { "/ftplugin/haskell.vim".text = '' if exists("g:vim_tv_ftplugin_haskell_loaded") finish endif let g:vim_tv_ftplugin_haskell_loaded = 1 setlocal iskeyword+=' ''; })) ]; extra-plugins = [ pkgs.tv.vimPlugins.elixir pkgs.tv.vimPlugins.fzf pkgs.tv.vimPlugins.jq pkgs.tv.vimPlugins.nix pkgs.tv.vimPlugins.showsyntax pkgs.tv.vimPlugins.tv pkgs.tv.vimPlugins.vim pkgs.vimPlugins.fzfWrapper pkgs.vimPlugins.vim-nftables ]; dirs = { backupdir = "$HOME/.cache/vim/backup"; swapdir = "$HOME/.cache/vim/swap"; undodir = "$HOME/.cache/vim/undo"; }; files = { viminfo = "$HOME/.cache/vim/info"; }; need-dirs = let dirOf = s: let out = lib.concatStringsSep "/" (lib.init (lib.splitString "/" s)); in assert out != ""; out; alldirs = builtins.attrValues dirs ++ map dirOf (builtins.attrValues files); in lib.unique (builtins.sort builtins.lessThan alldirs); vim-wrapper = pkgs.symlinkJoin { name = "vim"; paths = [ (pkgs.writeDashBin "vim" '' set -efu export FZF_DEFAULT_COMMAND='${pkgs.ripgrep}/bin/rg --files' export PATH=$PATH:${lib.makeBinPath [ pkgs.fzf pkgs.ripgrep ]} (umask 0077; exec ${pkgs.coreutils}/bin/mkdir -p ${toString need-dirs}) exec ${pkgs.vim}/bin/vim "$@" '') pkgs.vim ]; }; vimrc = pkgs.writeText "vimrc" /* vim */ '' vim9script set nocompatible set autoindent set backspace=indent,eol,start set backup set backupdir=${dirs.backupdir}/ set directory=${dirs.swapdir}// set hlsearch set incsearch set mouse=a set noruler set pastetoggle= set runtimepath=${pkgs.tv.vim.makeRuntimePath base-plugins},$VIMRUNTIME set shortmess+=I set showcmd set showmatch set timeoutlen=0 set ttimeoutlen=0 set ttymouse=sgr set undodir=${dirs.undodir} set undofile set undolevels=1000000 set undoreload=1000000 set viminfo='20,<1000,s100,h,n${files.viminfo} set visualbell set wildignore+=*.o,*.class,*.hi,*.dyn_hi,*.dyn_o set wildmenu set wildmode=longest,full set runtimepath^=${pkgs.tv.vim.makeRuntimePath extra-plugins} syntax on set et ts=2 sts=2 sw=2 filetype plugin indent on # [cursor] keep in sync with &t_SI = "\e[6 q" &t_EI = "\e[2 q" au VimEnter * silent !echo -ne "\e[2 q" set t_Co=256 colorscheme hack au Syntax * syn match Garbage containedin=ALL /\s\+$/ \ | syn match TabStop containedin=ALL /\t\+/ \ | syn keyword Todo containedin=ALL TODO au BufRead,BufNewFile *.nix set ft=nix au BufRead,BufNewFile /dev/shm/* set nobackup nowritebackup noswapfile cnoremap noremap :q nnoremap [5^ :tabp\|file nnoremap [6^ :tabn\|file nnoremap [5@ :tabm -1 nnoremap [6@ :tabm +1 nnoremap :tabp\|file nnoremap :tabn\|file imap imap nnoremap :tabm -1 nnoremap :tabm +1 imap imap noremap :ShowSyntax # noremap Oa | noremap! Oa noremap Ob | noremap! Ob noremap Oc | noremap! Oc noremap Od | noremap! Od # <[C]S-{Up,Down,Right,Left}> noremap [a | noremap! [a noremap [b | noremap! [b noremap [c | noremap! [c noremap [d | noremap! [d vnoremap u # fzf nnoremap q :Buffers nnoremap f :Files nnoremap w :Rg # edit alternate buffer # For some reason neither putting 6 nor ^ works here... nnoremap a  if $TOUCHSCREEN == "1" nnoremap nnoremap nnoremap 3 nnoremap 3 nnoremap 3 nnoremap 3 nnoremap nnoremap endif # remember last position autocmd BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ exe "normal! g`\"" | \ endif ''; }