vimrc (34462B)
1 " vim: foldmethod=marker foldlevel=0 2 let mapleader=" " " Set the mapleader to be space 3 4 " Plugins {{{1 5 " Installation {{{2 6 " Install vim-plug if needed 7 if empty(glob('~/.vim/autoload/plug.vim')) 8 silent execute "!curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" 9 autocmd VimEnter * PlugInstall | source $MYVIMRC 10 endif 11 12 call plug#begin('~/.vim/plugged') 13 Plug 'pearofducks/ansible-vim' 14 " To get documentation on vim-plug 15 Plug 'junegunn/vim-plug' 16 17 " Vim tester 18 Plug 'junegunn/vader.vim', { 'on': 'Vader', 'for': 'vader' } 19 20 " A color table with xterm color codes 21 Plug 'guns/xterm-color-table.vim' 22 23 " Faster HTML 24 Plug 'mattn/emmet-vim', { 'for': ['html', 'css', 'markdown'] } 25 26 " Endwise - smart do-end, if-fi, if-end, case-esac, etc. 27 Plug 'tpope/vim-endwise' 28 29 " Surround - super useful plugin for surrounding stuff with quotes/brackets/tags 30 Plug 'tpope/vim-surround' 31 32 " Eunuch - shell commands but in vim 33 Plug 'tpope/vim-eunuch' 34 35 " Project management 36 Plug 'tpope/vim-projectionist' 37 38 " Git wrapper from tpope 39 Plug 'tpope/vim-fugitive' 40 41 " Repeat everything with '.' 42 Plug 'tpope/vim-repeat' 43 44 " Distraction-free editing 45 Plug 'junegunn/goyo.vim' 46 Plug 'junegunn/limelight.vim' 47 48 " Better CSV editing 49 Plug 'mechatroner/rainbow_csv' 50 51 " Disable hlsearch after finished searching 52 Plug 'romainl/vim-cool' 53 54 " Vim + latex 55 Plug 'lervag/vimtex' 56 57 " Better abbrevation and substitution 58 Plug 'tpope/vim-abolish' 59 60 " Highlight hex colors 61 Plug 'chrisbra/colorizer', { 'on': 'ColorHighlight' } 62 63 " Bracket bindings for filetypes 64 Plug 'arp242/jumpy.vim' 65 66 " Omnifuncs 67 Plug 'myhere/vim-nodejs-complete', { 'for': 'js' } 68 Plug 'othree/html5.vim', { 'for': 'html' } 69 Plug 'vim-scripts/OmniCppComplete', { 'for': 'cpp' } 70 Plug 'vim-scripts/pythoncomplete', { 'for': 'python' } 71 72 " Peek contents of registers 73 Plug 'junegunn/vim-peekaboo' 74 75 " Latex symbol to unicode 76 Plug 'joom/latex-unicoder.vim' 77 78 " Smooth ^U/^D scrolling 79 Plug 'psliwka/vim-smoothie' 80 81 " Asynchronous popery 82 Plug 'tpope/vim-dispatch' 83 84 " Vimscript testing 85 Plug 'tpope/vim-scriptease', { 'on': 'Breakadd' } 86 87 " Set 'path', 'suffixesadd', 'include', 'includeexpr', 'define' 88 " automatically for selected filetypes. 89 Plug 'tpope/vim-apathy' 90 91 " Schemer - colorscheme creator 92 Plug 'thezeroalpha/vim-schemer' 93 94 " Make ins-completion relative to current file 95 Plug 'thezeroalpha/vim-relatively-complete' 96 97 " Run visually selected lines as Vim commands 98 Plug 'thezeroalpha/vim-visualrun' 99 100 " Select files with LF 101 Plug 'thezeroalpha/vim-lf' 102 103 " Literate programming in Markdown 104 Plug 'thezeroalpha/vim-literate-markdown' 105 106 " Lightweight REPL 107 Plug 'axvr/zepl.vim' 108 109 " Center the window vertically (like Goyo but keeps statusline/whatever) 110 Plug 'jmckiern/vim-venter', { 'on': 'Venter' } 111 112 " Edit files directly in quickfix window 113 Plug 'stefandtw/quickfix-reflector.vim' 114 115 " Minesweeper 116 Plug 'iqxd/vim-mine-sweeping' 117 118 Plug 'jceb/vim-orgmode', { 'for': 'org' } 119 120 " Rust 121 Plug 'rust-lang/rust.vim', { 'for': 'rust' } 122 123 " Fuzzy finder in vim 124 Plug 'junegunn/fzf', { 'dir': '$DOTFILES/tools/fzf', 'do': './install --all --xdg --no-fish'} 125 Plug 'junegunn/fzf.vim' 126 127 Plug 'mbbill/undotree' 128 129 " Hide long links 130 Plug 'qadzek/link.vim' 131 132 " Vim-only 133 if !has('nvim') 134 " Alignment 135 Plug 'junegunn/vim-easy-align' 136 137 " A tag overview on the right side 138 Plug 'majutsushi/tagbar' 139 140 " Substitute preview 141 Plug 'markonm/traces.vim' 142 143 Plug 'dense-analysis/ale' 144 145 " Show git changes in the sign column 146 Plug 'airblade/vim-gitgutter' 147 148 Plug 'Yggdroot/indentLine', { 'for': 'python' } 149 150 " Simple commenting 151 Plug 'tpope/vim-commentary' 152 153 " Display ANSI color codes 154 Plug 'vim-scripts/AnsiEsc.vim', { 'on': 'AnsiEsc' } 155 156 " Additional text objects 157 Plug 'wellle/targets.vim' 158 endif 159 call plug#end() 160 161 " quickfix filtering 162 packadd cfilter 163 164 if !has('nvim') 165 " matchit.vim is default, why not enable it 166 packadd matchit 167 endif 168 169 " }}}2 170 " Config {{{2 171 " Say {{{3 172 let g:say_wpm = 230 173 nmap gs <Plug>Say 174 vmap gs <Plug>Say 175 nmap gsl <Plug>SayLine 176 nmap gss <Plug>SayBuffer 177 " Tagbar {{{3 178 " Maps 179 nnoremap <leader>tt :TagbarToggle<CR> 180 nnoremap <leader>to :TagbarOpen fj<CR> 181 182 " tagbar language definitions 183 let g:tagbar_type_go = { 184 \ 'ctagstype' : 'go', 185 \ 'kinds' : [ 186 \ 'p:package', 187 \ 'i:imports:1', 188 \ 'c:constants', 189 \ 'v:variables', 190 \ 't:types', 191 \ 'n:interfaces', 192 \ 'w:fields', 193 \ 'e:embedded', 194 \ 'm:methods', 195 \ 'r:constructor', 196 \ 'f:functions' 197 \ ], 198 \ 'sro' : '.', 199 \ 'kind2scope' : { 200 \ 't' : 'ctype', 201 \ 'n' : 'ntype' 202 \ }, 203 \ 'scope2kind' : { 204 \ 'ctype' : 't', 205 \ 'ntype' : 'n' 206 \ }, 207 \ 'ctagsbin' : 'gotags', 208 \ 'ctagsargs' : '-sort -silent' 209 \ } 210 let g:tagbar_type_scss = { 211 \ 'ctagstype' : 'scss', 212 \ 'kinds' : [ 213 \ 'm:Mixins', 214 \ 'f:Functions', 215 \ 'v:Variables', 216 \ 'c:Classes', 217 \ 'i:IDs', 218 \ 't:Tags', 219 \ 'd:Media', 220 \ 'p:Placeholders' 221 \ ], 222 \ 'sort': 0 223 \ } 224 let g:tagbar_type_conf = { 225 \ 'ctagstype' : 'lfrc', 226 \ 'kinds' : [ 227 \ 'c:Commands', 228 \ 'm:Maps' 229 \ ], 230 \ 'sort': 0 231 \ } 232 let g:tagbar_type_zsh = { 233 \ 'ctagstype' : 'zsh', 234 \ 'kinds' : [ 235 \ 's:Source scripts', 236 \ 'e:Environment variables', 237 \ 'f:Functions', 238 \ 'm:Mappings' 239 \ ], 240 \ 'sort': 0 241 \ } 242 " Doge {{{3 243 let g:doge_mapping = '<leader>gd' 244 " Goyo {{{3 245 let g:goyo_width = "80%" 246 let g:goyo_height = "85%" 247 " Vimtex {{{3 248 let g:vimtex_view_automatic=0 249 let g:vimtex_quickfix_open_on_warning = 0 250 let g:vimtex_quickfix_ignore_filters = [ '[Ww]arning', '\(Under\|Over\)full', 'Missing ".* in' ] 251 let g:tex_flavor='latex' 252 let g:vimtex_toc_config = { 253 \ 'todo_sorted': 0, 254 \ 'show_help': 0 255 \ } 256 let g:vimtex_view_method='sioyek' 257 let g:vimtex_view_sioyek_exe='/Applications/sioyek.app/Contents/MacOS/sioyek' 258 let g:vimtex_syntax_custom_cmds = [ 259 \ {'name': 'fullref', 'argspell': 0}, 260 \ {'name': 'citea', 'argspell': 0}, 261 \ {'name': 'citen', 'argspell': 0, 'arggreedy': 1}, 262 \ {'name': 'citet', 'argspell': 0, 'arggreedy': 1} 263 \ ] 264 let g:vimtex_complete_ref = { 265 \ 'custom_patterns': ['\\fullref\*\?{[^}]*'] 266 \ } 267 let g:vimtex_complete_bib = { 268 \ 'custom_patterns': ['\\citen\*\?{[^}]*}{[^}]*', 269 \ '\\citea\*\?{[^}]*'] 270 \ } 271 let g:tex_comment_nospell=1 272 let g:vimtex_syntax_nospell_comments=1 273 let g:vimtex_quickfix_mode=0 274 let g:tex_conceal='abdmg' 275 let g:vimtex_compiler_enabled = 1 276 let g:vimtex_compiler_method='latexmk' 277 let g:vimtex_compiler_latexmk = { 278 \ 'callback' : 1, 279 \ 'continuous' : 1, 280 \ 'executable' : 'latexmk', 281 \ 'hooks' : [], 282 \ 'options' : [ 283 \ '-verbose', 284 \ '-file-line-error', 285 \ '-synctex=1', 286 \ '-interaction=nonstopmode', 287 \ ], 288 \} 289 let g:vimtex_compiler_tectonic = { 290 \ 'build_dir' : 'build', 291 \ 'callback' : 1, 292 \ 'options' : [ 293 \ '--keep-logs', 294 \ '--synctex', 295 \ '--keep-intermediates' 296 \ ], 297 \} 298 " Abolish {{{3 299 " Work with variants of words easily 300 let g:abolish_save_file = $HOME.."/.dotfiles/vim/abolish_save_file.vim" 301 " Fzf {{{3 302 set rtp+="$HOME"/.dotfiles/tools/fzf 303 function! s:build_quickfix_list(lines) 304 call setqflist(map(copy(a:lines), '{ "filename": v:val }')) 305 copen 306 cc 307 endfunction 308 let g:fzf_action = { 309 \ 'ctrl-f': function('s:build_quickfix_list'), 310 \ 'ctrl-t': 'tabedit', 311 \ 'ctrl-p': 'split', 312 \ 'ctrl-v': 'vsplit' } 313 let g:fzf_layout = {'window': { 'width': 0.9, 'height': 0.4 } } 314 let g:fzf_preview_window = 'right:60%' 315 " Jump to existing buffer/window if possible 316 let g:fzf_buffers_jump = 1 317 318 nnoremap <leader>F :Files<CR> 319 nnoremap <leader><c-f><c-f> :Files<space> 320 nnoremap <expr> <leader><c-f>. ":Files " .. expand("%:h") .. "<CR>" 321 nnoremap <leader>B :Buffers<CR> 322 nnoremap <leader>G :Lines<CR> 323 nnoremap <leader>W :BLines<CR> 324 nnoremap <expr> <leader>Z ':BLines '..&foldmarker->split(',')[0]..'<CR>' 325 nnoremap <leader>? :Helptags<CR> 326 nnoremap <leader>T :Tags<CR> 327 nnoremap <leader>/ :Ag<CR> 328 nnoremap <leader>M :Marks<CR> 329 nnoremap <leader>; :History:<CR> 330 331 " My extensions 332 nmap <leader>J <Plug>FzfChangesJumpsJumps 333 nmap <leader>C <Plug>FzfChangesJumpsChanges 334 335 " Search for Todos/Fixmes 336 command! Todo Ag ((TO ?DO)|FIXME):?<space> 337 nnoremap <leader>! :Todo<CR> 338 339 " Set a filetype 340 cabbrev setf Filetypes 341 342 command! Scripts call fzf#run(fzf#wrap({'source': 'command find $DOTFILES -type f -or -type l -not -ipath "*/.git/*"', 'options': '--multi --reverse --inline-info --prompt="scripts> "', 'sink': 'sp'})) 343 command! Configs call fzf#run(fzf#wrap({'source': 'command find $DOTFILES -type f ! -ipath "*/.git/*" ! -ipath "*/bin/*" ! -ipath "*/oh-my-zsh/*" ! -name ".DS_Store"', 'options': '--multi --reverse --inline-info --prompt="configs> "', 'sink': 'sp'})) 344 " Haskell {{{3 345 let hs_highlight_delimiters = 1 346 let hs_highlight_boolean = 1 347 let hs_highlight_types = 1 348 let hs_highlight_more_types = 1 349 " EasyAlign {{{3 350 " Start interactive EasyAlign in visual mode (e.g. vipga) 351 xmap ga <Plug>(LiveEasyAlign) 352 353 " Start interactive EasyAlign for a motion/text object (e.g. gaip) 354 nmap ga <Plug>(LiveEasyAlign) 355 356 " Keep :ascii as a map 357 nnoremap <leader>ga :<c-u>ascii<cr> 358 " Peekaboo {{{3 359 let g:peekaboo_compact=1 360 " Undotree {{{3 361 nnoremap <leader>u :UndotreeToggle<CR> 362 " Dispatch {{{3 363 " Disable default maps 364 let g:dispatch_no_maps = 1 365 366 " Only enable those I'll actually use 367 nnoremap `<CR> :Dispatch<CR> 368 nnoremap '<CR> :Start<CR> 369 " netrw {{{3 370 let g:netrw_banner = 0 " hide the banner 371 let g:netrw_fastbrowse = 1 " had set to 2 before, which ended up showing duplicate files... 372 let g:netrw_liststyle = 0 " thin listing 373 let g:netrw_winsize = 25 " open at 25% size 374 let g:netrw_keepdir = 0 " keep the current directory the same as the browsing directory. 375 let g:netrw_retmap = 0 " double-click to return to browsing 376 let g:netrw_list_hide = &wildignore " hide everything in &wildignore 377 let g:netrw_list_hide .= ',\(^\|\s\s\)\zs\.\S\+' " as well as dotfiles 378 let g:netrw_special_syntax = 1 " use special syntax groups for certain files in browser 379 " latex-unicoder {{{3 380 let g:unicoder_no_map = 1 381 inoremap <C-l> <Esc>:call unicoder#start(1)<CR> 382 " colorizer {{{3 383 let g:colorizer_colornames = 0 384 command! CH ColorHighlight 385 command! CC ColorClear 386 " Schemer {{{3 387 " List color group 388 nmap <leader><C-p> <Plug>SchemerSynstack 389 nmap <leader><C-E><C-L> <Plug>SchemerEdit 390 " Relatively complete {{{3 391 " Replace default file completion with 'smart' relative complete 392 imap <C-x><C-f> <Plug>RelativelyCompleteFile 393 " Visualrun {{{3 394 " Run selected commands (silent) 395 vmap <silent> <leader><cr> <Plug>VisualRunCommands 396 " Zepl {{{3 397 runtime! zepl/contrib/control_characters.vim 398 \ zepl/contrib/load_files.vim 399 \ zepl/contrib/python.vim 400 let g:repl_config = { 401 \ 'python': { 402 \ 'cmd': 'python3', 403 \ 'formatter': function('zepl#contrib#python#formatter'), 404 \ 'load_file': 'from %s import *' 405 \ }, 406 \ 'javascript': { 'cmd': 'node' }, 407 \ 'ruby': { 'cmd': 'irb', 'load_file': 'load "%s"' }, 408 \ 'r': { 'cmd': 'R' }, 409 \ 'java': {'cmd': 'jshell' }, 410 \ 'sh': {'cmd': 'sh' } 411 \ } 412 nnoremap gzr :Repl<CR> 413 " Medieval {{{3 414 let g:medieval_langs = ['python=python3', 'ruby', 'sh', 'bash', 'haskell=ghci', 'javascript=node'] 415 " LF {{{3 416 nmap <leader>\ <Plug>LfEdit 417 nmap <leader><c-\> <Plug>LfSplit 418 " Ada {{{3 419 let g:ada_standard_types = 1 420 let g:ada_space_errors = 1 421 let g:ada_begin_preproc = 1 422 let g:ada_omni_with_keywords = 1 423 " gh.vim {{{3 424 let g:gh_token = getenv("GITHUB_AUTH_TOKEN") 425 " ALE {{{3 426 if exists('g:loaded_ale') 427 let g:airline#extensions#ale#enabled = 0 428 let g:ale_enabled = 0 429 let g:ale_c_cc_options = '-std=gnu99 -Wall' 430 let g:ale_c_clangd_options = '-std=gnu99 -Wall' 431 let g:ale_c_clangformat_options = '-std=gnu99 -Wall' 432 let g:ale_c_clangtidy_options = '-std=gnu99 -Wall' 433 let g:ale_c_clangtidy_extra_options = '-std=gnu99 -Wall' 434 let g:ale_perl_perlcritic_options = '--brutal' 435 let g:ale_python_flake8_options = '--max-line-length=130' 436 call ale#Set('tex_textidote_executable', 'textidote') 437 call ale#Set('tex_textidote_options', '--no-color --output singleline') 438 " TODO get language from spell spelllang 439 call ale#Set('tex_textidote_check_lang', '') 440 call ale#linter#Define('tex', { 441 \ 'name': 'textidote', 442 \ 'output_stream': 'stdout', 443 \ 'executable': {b -> ale#Var(b, 'tex_textidote_executable')}, 444 \ 'command': function('ale_linters#tex#textidote#GetExecutable'), 445 \ 'callback': 'ale_linters#tex#textidote#Handle', 446 \}) 447 endif 448 449 " indentLine {{{3 450 if !has('nvim') 451 let g:indentLine_char_list = ['|', '¦', '┆', '┊'] 452 let g:indentLine_enable = 0 " off by default 453 let g:indentLine_fileType = ['python'] " enable for python 454 endif 455 " Emmet {{{3 456 let g:user_emmet_settings = { 457 \ 'markdown': { 458 \ 'indentation': '', 459 \ 'extends': 'html' 460 \ } 461 \ } 462 " Smoothie {{{3 463 let g:smoothie_remapped_commands = ['<C-D>', '<C-U>', '<C-F>', '<C-B>'] 464 " }}}1 465 " General {{{1 466 " Put viminfo in ~/.cache 467 if has('nvim') 468 set viminfofile=~/.cache/nvim/viminfo 469 else 470 set viminfofile=~/.cache/vim/viminfo 471 endif 472 473 " Set the colors 474 " Use true color 475 " Set Vim-specific sequences for RGB colors 476 let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum" 477 let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum" 478 479 if has('termguicolors') 480 set termguicolors 481 endif 482 483 if filereadable($HOME."/.config/dark-theme") 484 colorscheme junipero 485 else 486 colorscheme jokull 487 endif 488 489 " where to find tags files 490 set tags=./tags;~,tags,~/.tags 491 if has("path_extra") 492 " If compiled with path_extra, search for .git/tags upwards in the tree 493 " and stop searching at $HOME 494 let &tags = &tags.',.git/tags;~' 495 else 496 let &tags = &tags.',.git/tags' 497 endif 498 499 " follow the 'ignorecase' option when looking for tags 500 set tagcase=followic 501 502 " dictionary files, in order (custom words should appear at the top) 503 " remember, to generate a wordlist from spellcheck, do :spelldump 504 set dictionary=~/.vim/words/dict/global/custom.txt 505 set dictionary+=~/.vim/words/dict/global/3of6all.txt 506 set dictionary+=/usr/share/dict/words 507 508 " thesaurus file 509 set thesaurus=~/.vim/words/thesaurus/mthesaur.txt 510 511 if !has('nvim') 512 " same with :Man 513 " I'm lazy-loading this because it really affects my startup time. 514 " I'm not the only one: https://www.reddit.com/r/vim/comments/emx856/lazy_loading_man_page_plugin/ 515 silent! command! -bar -nargs=* Man 516 \ delcommand Man | 517 \ runtime ftplugin/man.vim | 518 \ Man <args> 519 endif 520 521 " For editing binaries 522 set binary 523 524 " Save swapfiles to ~/.local/share/vim/swap 525 if has('nvim') 526 if !isdirectory($HOME.'/.local/share/nvim/swap') 527 silent call mkdir($HOME.'/.local/share/nvim/swap', 'p') 528 endif 529 set directory=~/.local/share/nvim/swap// 530 else 531 if !isdirectory($HOME.'/.local/share/vim/swap') 532 silent call mkdir($HOME.'/.local/share/vim/swap', 'p') 533 endif 534 set directory=~/.local/share/vim/swap// 535 endif 536 set swapfile 537 538 " Save backups to ~/.local/share/vim/backup 539 if has('nvim') 540 if !isdirectory($HOME.'/.local/share/nvim/backup') 541 silent call mkdir($HOME.'/.local/share/nvim/backup', 'p') 542 endif 543 set backupdir=~/.local/share/nvim/backup// 544 else 545 if !isdirectory($HOME.'/.local/share/vim/backup') 546 silent call mkdir($HOME.'/.local/share/vim/backup', 'p') 547 endif 548 set backupdir=~/.local/share/vim/backup// 549 endif 550 set nobackup writebackup 551 552 " make regexes consistent with other programs (extended) 553 set magic 554 555 " global setting for directories to search for files (e.g. for gf) 556 " . == directory of current file, ,, == current working directory 557 set path=.,"$HOME"/.dotfiles/vim/**,, 558 559 " global suffixes to add when looking for files (configured otherwise on per-language basis) 560 set suffixesadd=.vim 561 562 " include, includeexpr, define: very language-specific, so no default global value 563 564 " global patterns to ignore in wildmenu 565 set wildignore=*.swp 566 set wildignorecase 567 568 " Persistent undos (useful for plugins too){{{ 569 if has('persistent_undo') 570 if has('nvim') 571 let myUndoDir = $HOME . '/.local/share/nvim/undo' 572 else 573 let myUndoDir = $HOME . '/.local/share/vim/undo' 574 endif 575 silent! call mkdir(myUndoDir, 'p') 576 let &undodir = myUndoDir 577 set undofile 578 endif 579 " }}} 580 581 " Hide buffers instead of closing 582 set hidden 583 584 " Dont redraw while executing macros 585 set lazyredraw 586 587 " Encoding & formats 588 set encoding=utf-8 nobomb 589 set fileformats=unix,dos,mac 590 591 " Number of lines to use for command line 592 " (this fixes the 'press to continue' thing on :help) 593 set cmdheight=1 594 595 " Send more characters at a given time 596 set ttyfast 597 598 " Show partial command on last line 599 set showcmd 600 601 " Don't show current mode (it's in the statusline) 602 set noshowmode 603 " Command completion 604 set wildmenu 605 606 " Allow the mouse, good for e.g. resizing splits 607 set mouse=a 608 " fix issue with not being able to drag resize split windows in tmux 609 if !has('nvim') 610 if &term =~# '^screen' || $TMUX !=# "" 611 set ttymouse=xterm2 612 elseif &term =~# '^st-' || &term =~# '^alacritty' 613 set ttymouse=sgr 614 endif 615 endif 616 617 " How to split new windows 618 set splitbelow splitright 619 620 " Allow per-file settings 621 set modeline 622 set modelines=5 "within the first/last 5 lines 623 624 " Allow italics 625 set t_ZH=[3m 626 set t_ZR=[23m 627 628 " Since belloff isn't always an option 629 if exists("&belloff") 630 set belloff=showmatch,esc,shell,wildmode,backspace " Disable beeping if no match is found 631 endif 632 633 " Command-line autocompletion 634 set wildmode=longest:list,full 635 636 " Add everything to sessions 637 set sessionoptions=buffers,curdir,folds,globals,localoptions,options,resize,tabpages 638 639 " Use ag for grepping 640 set grepprg=ag\ --vimgrep 641 set updatetime=100 642 643 " Make <esc> faster. 644 " Note: this disables arrow keys in insert mode, because arrow keys start with <esc> (e.g. `\eOD` for left arrow). 645 " However, I don't use arrow keys anyway, so that's fine. 646 if !has('nvim') 647 set noesckeys 648 endif 649 650 " }}}1 651 " Editor {{{1 652 " In general, don't conceal anything 653 if has('conceal') 654 set conceallevel=0 655 endif 656 657 " Change cursor shape between insert and normal mode in iTerm2.app and 658 " Alacritty 659 " '\e[n q' with n: 0 blinking block, 1 blinking block, 2 steady block, 3 660 " blinking underline, 4 steady underline, 5 blinking bar, 6 steady bar 661 " If this doesn't work, you might need a different escape sequence: 662 " - t_SI = "\<Esc>]50;CursorShape=1\x7\<Esc>\\" 663 " - t_EI = "\<Esc>]50;CursorShape=0\x7\<Esc>\\" 664 " (test them with e.g. `printf '\e[6 q'`) 665 if exists('$TMUX') 666 " NOTE: For tmux >= version 3.3, you need 'allow-passthrough' set. 667 let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>[6 q\<Esc>\\" " Vertical bar in insert mode 668 let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>[2 q\<Esc>\\" " Block in normal mode 669 let &t_SR = "\<Esc>Ptmux;\<Esc>\<Esc>[4 q\<Esc>\\" " Underline in replace mode 670 else 671 let &t_SI = "\<Esc>[6 q" " Vertical bar in insert mode 672 let &t_SR = "\<Esc>[4 q" " Underline in replace mode 673 let &t_EI = "\<Esc>[2 q" " Block in normal mode 674 endif 675 676 " Highlight current line 677 set cursorline 678 679 " Reduce waiting on keys (like esc) 680 set timeoutlen=1000 ttimeoutlen=5 681 682 " Wrap settings - no wrap by default 683 set nowrap 684 set textwidth=0 685 set wrapmargin=0 686 set linebreak " break at &breakat 687 " Continue wrapped line on same indent as previous 688 if has('breakindent') 689 set breakindent 690 set breakindentopt+=shift:3 691 endif 692 693 " Default formatoptions: 694 " - q: allow gq 695 " - n: recognise numbered lists 696 " - l: don't break long lines in insert mode 697 " - j: remove comment leader when joining 698 set formatoptions=qnlj 699 700 " Numbered lines 701 set number 702 set numberwidth=3 703 set relativenumber 704 705 " with a smart tab 706 set smarttab 707 708 " and 1 tab == 2 spaces 709 set tabstop=8 " visual length of \t in spaces, should be left at 8 710 set expandtab " use spaces instead of tabs 711 set softtabstop=4 " 4 spaces inserted when TAB pressed 712 set shiftwidth=2 " 2 spaces when >> 713 set shiftround " always shift by multiple of shiftwidth 714 715 " Auto indent when starting new line 716 set autoindent 717 set copyindent " copy structure of other indents whn autoindenting 718 719 " Enable indenting based on filetype 720 filetype plugin indent on 721 722 " Syntax highlighting 723 syntax on 724 725 " Enable fenced code highlighting in markdown (tpope's plugin, ships with vim) 726 " NOTE: I'm disabling it because it makes Vim very slow when typing in 727 " markdown... 728 " let g:markdown_fenced_languages = ['html', 'python', 'ruby', 'bash=sh', 'map', 'vim', 'c', 'cpp', 'make'] 729 730 " Enable markdown folding 731 " NOTE: I'm disabling it because it makes Vim very slow when typing in 732 " markdown... 733 " let g:markdown_folding = 1 734 735 " Folding on indentation 736 set foldmethod=indent 737 set foldlevelstart=5 " start with up to 5 levels open 738 set foldnestmax=10 " unless callback-hell JS 739 740 " Show matching brackets 741 set showmatch 742 set matchtime=2 743 744 " Searching 745 set hlsearch " highlight matches 746 set incsearch " search while typing 747 set ignorecase " ignore case generally 748 set smartcase " but not if searching for capital 749 750 " Backspace tweaks 751 set backspace=indent,eol,start 752 set whichwrap+=<,>,h,l 753 754 " Complete from current buffer, other windows, buffers, unloaded buffers, tags, 755 " current and included files, and dictionary if spell is set 756 set complete=.,w,b,u,t,i,kspell 757 " Use popup menu, also when there is only one match, don't insert until the user selects 758 " a match, don't select anything automatically. 759 set completeopt=menu,menuone,preview 760 761 nnoremap <silent><expr> <leader># ":set ".(&relativenumber?'norelativenumber number':'relativenumber number')."<CR>" 762 763 set omnifunc=syntaxcomplete#Complete 764 765 " Keep cursor off top and bottom of screen 766 set scrolloff=5 767 768 " Which formats to use for incrementing/decrementing 769 set nrformats=hex,bin 770 771 " We write posix shell scripts 772 let g:is_posix = 1 773 774 " Show where lines were wrapped 775 set showbreak=≻ 776 " }}} 777 " Commands {{{1 778 command! NoteP vimgrep /NOTE\C/ **/*.* | copen 779 command! Note vimgrep /NOTE\C/ % | copen 780 command! FixP vimgrep /FIXME\C/ **/*.* | copen 781 command! Fix vimgrep /FIXME\C/ % | copen 782 command! ListFileTypes echo glob($VIMRUNTIME . '/syntax/*.vim') 783 command! CD cd %:p:h 784 command! LCD lcd %:p:h 785 command! TCD tcd %:p:h 786 command! RO setlocal nomodifiable readonly 787 command! RW setlocal modifiable noreadonly 788 command! Maketab set noet ts=2 | %retab! 789 command! Diff w !diff % - 790 command! Diffg w !git diff % - 791 command! Fuckwindows %s/ //g 792 command! Hexedit %!xxd 793 command! Unhex %!xxd -r 794 command! JsonSimplifyObject %s/^\(\s\{10}\){\n\s\{12\}\(.*\)\n\s\{10\}}\(,\?\)/\1{ \2 }\3 795 command! UnsmartQuotes silent %s/[“”]/"/ge | %s/[‘’]/'/ge 796 command! BeautifyJson %!python -m json.tool 797 command! Dos2unix %!dos2unix 798 command! -nargs=1 Cheat terminal curl cheat.sh/<args> 799 command! Reveal exe "silent !open ".shellescape(expand("%:p:h")) | redraw! 800 command! Softwrap setlocal wrap formatoptions-=cat 801 command! Hardwrap setlocal nowrap formatoptions+=cat 802 command! Syncwin windo set scrollbind! cursorbind! 803 command! EF exe "split $HOME/.vim/after/ftplugin/".&filetype.".vim" 804 command! FD filetype detect 805 command! D smile 806 command! QuickfixAddCurrent call setqflist([{'bufnr': bufnr(), 'lnum': line('.'), 'text': getline('.')}], 'a') 807 command! LoclistAddCurrent call setloclist(winnr(), [{'bufnr': bufnr(), 'lnum': line('.'), 'text': getline('.')}], 'a') 808 command! QuickfixDelCurrent call setqflist(getqflist()->filter($'v:val["bufnr"] !=# {bufnr()} || v:val["lnum"] !=# {line(".")}'), 'r') 809 command! LoclistDelCurrent call setloclist(winnr(), getloclist(winnr())->filter($'v:val["bufnr"] !=# {bufnr()} || v:val["lnum"] !=# {line(".")}'), 'r') 810 command! QuickfixClear call setqflist([], 'f') 811 command! LoclistClear call setloclist(winnr(), [], 'f') 812 command! -nargs=? Browser exe 'terminal ++close w3m -config '.getenv("XDG_CONFIG_HOME").'/w3m/config -bookmark '.getenv("XDG_CONFIG_HOME").'/w3m/bookmark.html '.<q-args> 813 command! -nargs=1 Img 814 \ exe "r! find ".shellescape(expand("%:p:h"))." -maxdepth ".<args>." -type f -exec file --mime-type '{}' \\+" 815 \ ."| awk -F: '$2 ~ /image\\//{print $1}'" 816 \ ."| sxiv -qto - 2>/dev/null" 817 818 " Fat finger fixes/convenience abbreviations 819 cnoreabbrev E Explore 820 cnoreabbrev Colors XtermColorTable 821 cnoreabbrev lset setl 822 cnoreabbrev sudow w !sudo tee > /dev/null % 823 cnoreabbrev hg helpgrep 824 cnoreabbrev gitr system("git root") 825 826 if has('terminal') 827 " ++close means close when process ends 828 " (so that I don't get a hanging term buffer) 829 cnoreabbrev wt terminal ++close 830 cnoreabbrev tt tab terminal ++close 831 cnoreabbrev tm terminal ++close man 832 cnoreabbrev tf terminal ++close lf 833 cnoreabbrev tn terminal ++close joplin 834 command! Reddit tab terminal ttrv 835 endif 836 837 " Convenient command to see the difference between the current buffer and the 838 " file it was loaded from, thus the changes you made. 839 command! DiffOrig vert new | set bt=nofile | r# | 0d_ | diffthis 840 \ | wincmd p | diffthis 841 " }}} 842 " Digraphs {{{1 843 let digraphs = { 844 \ 'o+': 0x2295, 'O+': 0x2a01, 845 \ 'e$': 0x20ac, 846 \ '\|>': 0x21a6, 847 \ '[[': 0x27e6, ']]': 0x27e7, 848 \ 'aS': 0x1D43, 'bS': 0x1D47, 'cS': 0x1D9C, 'dS': 0x1D48, 'eS': 0x1D49, 'fS': 0x1DA0, 'gS': 0x1D4D, 'hS': 0x02B0, 'iS': 0x2071, 'jS': 0x02B2, 'kS': 0x1D4F, 'lS': 0x02E1, 'mS': 0x1D50, 'nS': 0x207F, 'oS': 0x1D52, 'pS': 0x1D56, 'rS': 0x02B3, 'sS': 0x02E2, 'tS': 0x1D57, 'uS': 0x1D58, 'vS': 0x1D5B, 'wS': 0x02B7, 'xS': 0x02E3, 'yS': 0x02B8, 'zS': 0x1DBB, 'AS': 0x1D2C, 'BS': 0x1D2D, 'DS': 0x1D30, 'ES': 0x1D31, 'GS': 0x1D33, 'HS': 0x1D34, 'IS': 0x1D35, 'JS': 0x1D36, 'KS': 0x1D37, 'LS': 0x1D38, 'MS': 0x1D39, 'NS': 0x1D3A, 'OS': 0x1D3C, 'PS': 0x1D3E, 'RS': 0x1D3F, 'TS': 0x1D40, 'US': 0x1D41, 'VS': 0x2C7D, 'WS': 0x1D42, 849 \ 'as': 0x2090, 'es': 0x2091, 'is': 0x1D62, 'os': 0x2092, 'rs': 0x1D63, 'us': 0x1D64, 'vs': 0x1D65, 'xs': 0x2093, 'ys': 0x1D67, 850 \ '0S': 0x2070, '1S': 0x00B9, '2S': 0x00B2, '3S': 0x00B3, '4S': 0x2074, '5S': 0x2075, '6S': 0x2076, '7S': 0x2077, '8S': 0x2078, '9S': 0x2079, '+S': 0x207A, '-S': 0x207B, '=S': 0x207C, '(S': 0x207D, ')S': 0x207E, 851 \ '0s': 0x2080, '1s': 0x2081, '2s': 0x2082, '3s': 0x2083, '4s': 0x2084, '5s': 0x2085, '6s': 0x2086, '7s': 0x2087, '8s': 0x2088, '9s': 0x2089, '+s': 0x208A, '-s': 0x208B, '=s': 0x208C, '(s': 0x208D, ')s': 0x208E, 852 \ '-<': 0x227a, '>-': 0x227b, 853 \ '\|=': 0x22a8, '\|-': 0x22a2, '!m': 0x22ad, 854 \ '[]': 0x25a1, '()': 0x25c7, '<(': 0x3008, '>)': 0x3009, 855 \ 'n#': 0x2115, 'r#': 0x211d, 'z#': 0x2124 } 856 857 for [dg, code] in items(digraphs) 858 exe 'digraphs ' .. dg .. ' ' .. code 859 endfor 860 " Mappings {{{1 861 " So I don't have to mash shift all the time 862 nnoremap ; : 863 vnoremap ; : 864 865 if has('terminal') 866 tnoremap <C-w>; <C-w>: 867 endif 868 869 " To keep the old functionality of ; 870 nnoremap : ; 871 vnoremap : ; 872 873 " Disable q: cuz I hate it 874 " (also C-F does the same) 875 nnoremap q: <Nop> 876 877 " Normal mode shortcuts 878 nnoremap <leader>b :ls<CR>:b<Space> 879 880 " Retain visual mode after > and < 881 vnoremap < <gv 882 vnoremap > >gv 883 884 " visual j/k 885 nnoremap j gj 886 nnoremap k gk 887 nnoremap gj j 888 nnoremap gk k 889 vnoremap j gj 890 vnoremap k gk 891 vnoremap gj j 892 vnoremap gk k 893 894 " Move visual block 895 xnoremap D :m '>+1<CR>gv=gv 896 xnoremap U :m '<-2<CR>gv=gv 897 898 " and don't break my colours (U for 'unfuck my screen please') 899 nnoremap <leader><c-l> :syntax sync fromstart<CR>:redraw!<CR>:diffupdate<CR><c-l> 900 901 " urlview 902 nnoremap <silent> U :w !urlview<CR> 903 nnoremap <leader>U U 904 905 " 'zoom to head level' 906 nnoremap zh mzzt10<c-u>`z 907 908 " Reindent the file 909 nnoremap <leader>= mlgg=G`lzz 910 911 " Tab mappings 912 nnoremap <leader>tn :tabnew<CR> 913 nnoremap <leader>tc :tabclose<CR> 914 nnoremap <leader>th :tabmove -1<CR> 915 nnoremap <leader>tl :tabmove +1<CR> 916 917 " Window resizing mappings 918 nnoremap <C-k> <C-w>+ 919 nnoremap <C-j> <C-w>- 920 nnoremap <C-h> <C-W>< 921 nnoremap <C-l> <C-W>> 922 923 " Delete hidden buffers 924 nmap <leader>dh <Plug>DeleteHiddenBuffers 925 926 " Show hidden symbols 927 nnoremap <leader>hs :set list!<CR> 928 929 " List marks 930 nnoremap <leader>mm :<C-u>marks<CR>:normal! ` 931 nnoremap <leader>ml :<C-u>marks a-z<CR>:normal! ` 932 933 934 " Map '0' to act as '^' on first press and '0' on second 935 nnoremap <expr> <silent> 0 col('.') == match(getline('.'),'\S')+1 ? '0' : '^' 936 937 " Highlight last inserted text 938 nnoremap gV `[v`] 939 940 " Save in insert mode 941 inoremap <C-Z> <C-o>:w<CR> 942 943 " Allow undo/redo on C-w and C-u in insert mode 944 inoremap <c-u> <c-g>u<c-u> 945 inoremap <c-w> <c-g>u<c-w> 946 947 if !has('nvim') 948 " Config edit mappings 949 " Why :drop? It uses the file if it's already open. 950 " Also have to map c-c to no-op first, otherwise doesn't work 951 nnoremap <C-c> <nop> 952 nnoremap <leader><C-E><C-V> :DropToFoldedVimrc<CR>zXgg 953 nnoremap <leader><C-E><C-A> :DropToFoldedVimrc<CR>zXgg/^" Autocommands {{<CR>:noh<CR>za 954 nnoremap <leader><C-E><C-C> :DropToFoldedVimrc<CR>zXgg/Commands {{<CR>:noh<CR>za 955 nnoremap <leader><C-E><C-E> :DropToFoldedVimrc<CR>zXgg/Editor {{<CR>:noh<CR>za 956 nnoremap <leader><C-E><C-G> :DropToFoldedVimrc<CR>zXgg/General {{<CR>:noh<CR>za 957 nnoremap <leader><C-E><C-M> :DropToFoldedVimrc<CR>zXgg/Mappings {{<CR>:noh<CR>za 958 nnoremap <leader><C-E><C-P><C-I> :DropToFoldedVimrc<CR>zXgg/Plugins {{<CR>:noh<CR>za/Installation {{<CR>:noh<CR>za 959 nnoremap <leader><C-E><C-P><C-C> :DropToFoldedVimrc<CR>zXgg/Plugins {{<CR>:noh<CR>za/Config {{<CR>:noh<CR>za 960 nnoremap <leader><C-E><C-U> :UltiSnipsEdit<CR> 961 endif 962 963 " Yank to clipboard 964 nnoremap <leader>d "+d 965 vnoremap <leader>d "+d 966 nnoremap <leader>D "+D 967 nnoremap <leader>y "+y 968 vnoremap <leader>y "+y 969 nnoremap <leader><leader>p "+p 970 nnoremap <leader><leader>P "+P 971 vnoremap <leader><leader>p "+p 972 vnoremap <leader><leader>P "+P 973 nnoremap <leader>n "_ 974 vnoremap <leader>n "_ 975 nnoremap <leader>yy "+yg_ 976 nnoremap <leader>y<leader> :<c-u>let @*=@0<CR> 977 nnoremap Y y$ 978 979 " Insert lines without moving cursor and going into insert mode 980 nnoremap <leader>o m`o<esc>`` 981 nnoremap <leader>O m`O<esc>`` 982 983 " native file browsing 984 nnoremap <leader>f :Lexplore<CR> 985 986 " Strip trailing whitespace (silent makes it so nothing is echoed) 987 nmap <silent> <leader>$ <Plug>StripTrailingWhitespace 988 989 " Buffer switching 990 nnoremap H :bprevious<CR> 991 nnoremap L :bnext<CR> 992 993 " Arg switching 994 nnoremap <leader>H :previous<CR> 995 nnoremap <leader>L :next<CR> 996 997 998 " Correct the last spelling error 999 inoremap <expr> <C-x>s &spell ? "<c-g>u<Esc>[s1z=`]a<c-g>u" : "" 1000 1001 " Make-ing (use Dispatch if enabled) 1002 nnoremap <leader>m? :set makeprg<CR> 1003 nnoremap <leader>mm :Make<CR> 1004 nnoremap <leader>mc :Make clean<CR> 1005 1006 " If Dispatch not used 1007 " :silent make<CR>\|:redraw!<CR>\|:cwindow<CR> 1008 " :silent make clean<CR>\|:redraw!<CR> 1009 1010 " Vmap for searching in selection 1011 vnoremap <leader>/ <esc>/\%V 1012 1013 " Allow scrolling popup menus with the mouse 1014 if has('mouse') 1015 inoremap <expr> <ScrollWheelUp> pumvisible() ? "<C-p>" : "<Esc><ScrollWheelUp>" 1016 inoremap <expr> <ScrollWheelDown> pumvisible() ? "<C-n>" : "<Esc><ScrollWheelDown>" 1017 endif 1018 1019 " 'Zoom' the current buffer in a new tab 1020 nnoremap <C-w>Z :tab split<CR> 1021 1022 " Go to line:column 1023 nnoremap <leader>gg :call input("go line:col> ")->split(":")->cursor()<CR> 1024 1025 " Which commit introduced this line? 1026 nnoremap <silent><Leader>gw :call setbufvar(winbufnr(popup_atcursor(systemlist("cd " . shellescape(fnamemodify(resolve(expand('%:p')), ":h")) . " && git log --no-merges -n 1 -L " . shellescape(line("v") . "," . line(".") . ":" . resolve(expand("%:p")))), { "padding": [1,1,1,1], "pos": "botleft", "wrap": 0, "highlight": "StatusLine"})), "&filetype", "git")<CR> 1027 1028 " Avoid paste hijacking in insert mode 1029 inoremap <c-r> <c-r><c-o> 1030 1031 " Up/down arrows on the command line search for commands starting with current 1032 " string. I want <c-n/p> to do the same. 1033 cnoremap <expr> <c-n> wildmenumode() ? "\<c-n>" : "\<down>" 1034 cnoremap <expr> <c-p> wildmenumode() ? "\<c-p>" : "\<up>" 1035 1036 " Use <Tab> and <S-Tab> to jump to next search result, 1037 " while keeping <Tab>'s wildmenu function. 1038 set wildcharm=<c-z> 1039 cnoremap <expr> <Tab> getcmdtype() =~ '[?/]' ? "<c-g>" : "<c-z>" 1040 cnoremap <expr> <S-Tab> getcmdtype() =~ '[?/]' ? "<c-t>" : "<S-Tab>" 1041 1042 " Easier pasting 1043 nnoremap <leader>p "0p 1044 vnoremap <leader>p "0p 1045 nnoremap <leader>P "0P 1046 vnoremap <leader>P "0P 1047 1048 " Highlight one or more lines 1049 highlight LineHighlight ctermbg=darkgray guibg=darkgray cterm=bold 1050 nnoremap <silent> <leader>hl :call matchadd('LineHighlight', '\%'.line('.').'l')<CR> 1051 vnoremap <silent> <leader>hl :call matchadd('LineHighlight', '\%'.line('.').'l')<CR> 1052 nnoremap <silent> <leader>hc :call clearmatches()<CR> 1053 vnoremap <silent> <leader>hc :call clearmatches()<CR> 1054 1055 " have n always search forward 1056 noremap <expr> <SID>(search-forward) 'Nn'[v:searchforward] 1057 " and N always search backward 1058 noremap <expr> <SID>(search-backward) 'nN'[v:searchforward] 1059 1060 " backspace to switch to alternate buffer 1061 nnoremap <backspace> <c-^> 1062 1063 " Switch to tab/space indentation 1064 nnoremap <leader>i<tab> :set noexpandtab shiftwidth=4 softtabstop=4 tabstop=4<CR> 1065 nnoremap <leader>i<space> :set expandtab shiftwidth=4 softtabstop=4 tabstop=8<CR> 1066 1067 " Switch fold methods 1068 nnoremap <leader>zm :setlocal foldmethod=manual<CR> 1069 nnoremap <leader>zi :setlocal foldmethod=indent<CR> 1070 nnoremap <leader>z{ :setlocal foldmethod=marker<CR> 1071 nnoremap <leader>zs :setlocal foldmethod=syntax<CR> 1072 nnoremap <leader>ze :setlocal foldmethod=expr<CR> 1073 nnoremap <leader>zd :setlocal foldmethod=diff<CR> 1074 nmap z/ <Plug>SearchFold 1075 1076 " Set the foldlevel 1077 nnoremap <leader>zn :set foldlevel= 1078 nnoremap <leader>z. :exe "set foldlevel=".foldlevel(line('.'))<CR> 1079 1080 " quickfix 1081 nnoremap <leader>qf :cwindow<CR> 1082 nnoremap <leader>qn :cnext<CR> 1083 nnoremap <leader>qp :cprevious<CR> 1084 nnoremap <leader>qc :cclose<CR> 1085 nnoremap <leader>qz :<c-u>QuickfixClear<CR> 1086 nnoremap <leader>q. :<c-u>QuickfixAddCurrent<CR> 1087 nnoremap <leader>q- :<c-u>QuickfixDelCurrent<CR> 1088 nnoremap <leader>qr :<c-u>crewind<CR> 1089 1090 " location 1091 nnoremap <leader>ll :lwindow<CR> 1092 nnoremap <leader>ln :lnext<CR> 1093 nnoremap <leader>lp :lprevious<CR> 1094 nnoremap <leader>lb :lbefore<CR> 1095 nnoremap <leader>la :lafter<CR> 1096 nnoremap <leader>lf :lfirst<CR> 1097 nnoremap <leader>lz :<c-u>LoclistClear<CR> 1098 nnoremap <leader>l. :<c-u>LoclistAddCurrent<CR> 1099 nnoremap <leader>l- :<c-u>LoclistDelCurrent<CR> 1100 " Autocommands {{{1 1101 if has('autocmd') 1102 augroup vimrc_sets 1103 autocmd! 1104 autocmd InsertEnter * setlocal nocursorline 1105 autocmd InsertLeave * setlocal cursorline 1106 autocmd ColorScheme * highlight ColorColumn ctermbg=233 1107 augroup END 1108 augroup vimrc_commands 1109 autocmd! 1110 autocmd BufWritePre * silent StripTrailingWhitespace 1111 1112 augroup END 1113 endif 1114 " }}}