.config/nvim/init.vim (625 lines)
1 " _ 2 " _ __ ___ _____ _(_)_ __ ___ 3 " | '_ \ / _ \/ _ \ \ / / | '_ ` _ \ 4 " | | | | __/ (_) \ V /| | | | | | | 5 " |_| |_|\___|\___/ \_/ |_|_| |_| |_| 6 " 7 " by github.com/mjkloeckner 8 9 " Automatically install vim-plug (plugin manager) if not already installed 10 let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim' 11 if empty(glob(data_dir . '/autoload/plug.vim')) 12 silent execute '!curl -fLo ' . data_dir . '/autoload/plug.vim --create-dirs '. 13 \' https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' 14 autocmd VimEnter * PlugInstall --sync | source $MYVIMRC 15 endif 16 17 " Plugins call 18 call plug#begin('~/.config/nvim/plugged') 19 Plug 'jiangmiao/auto-pairs' 20 Plug 'alvan/vim-closetag' 21 Plug 'ayosec/hltermpaste.vim' 22 Plug 'chrisbra/Colorizer' 23 Plug 'christoomey/vim-tmux-navigator' 24 Plug 'flazz/vim-colorschemes' 25 Plug 'flw-cn/vim-nerdtree-l-open-h-close' 26 Plug 'hattya/vcs-info.vim' 27 Plug 'iamcco/markdown-preview.nvim', 28 \{ 'do': { -> mkdp#util#install() }, 29 \'for': [ 'markdown', 'vim-plug' ]} 30 Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } 31 Plug 'junegunn/fzf.vim' 32 Plug 'junegunn/vim-easy-align' 33 Plug 'justinmk/vim-syntax-extra' 34 Plug 'preservim/nerdtree' 35 Plug 'ryanoasis/vim-devicons' 36 Plug 'sainnhe/edge' 37 Plug 'sainnhe/gruvbox-material' 38 Plug 'skywind3000/asyncrun.vim' 39 Plug 'tikhomirov/vim-glsl' 40 Plug 'tpope/vim-commentary' 41 Plug 'tpope/vim-surround' 42 Plug 'tpope/vim-fugitive' 43 Plug 'vim-python/python-syntax' 44 Plug 'mjkloeckner/autosave.vim' 45 call plug#end() 46 47 " Basic settings 48 syntax on 49 set title 50 " remove the `NVIM` ending from the title 51 " (see https://neovim.io/doc/user/options.html#'titlestring') 52 set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:~:.:h\")})%)%(\ %a%) 53 set encoding=utf-8 54 scriptencoding utf-8 55 set fileencoding=utf-8 56 set noemoji 57 set tabstop=4 58 set shiftwidth=4 59 set scrolloff=5 60 set path+=./** 61 set lcs+=space:· 62 set iskeyword-=(,) 63 set wildmenu 64 set incsearch 65 set smartcase 66 " set noshowmode 67 set number 68 set relativenumber 69 set cursorline 70 set listchars=tab:\|\ ,trail:-,nbsp:+,space:· 71 set list 72 set mouse=a 73 set undofile 74 set undodir=~/.cache/nvim/undo 75 set dir=~/.cache/nvim/swap 76 set backupdir=~/.cache/nvim/backup 77 set clipboard=unnamedplus 78 79 " Enable blinking together with different cursor shapes for 80 " insert/command mode, and cursor highlighting: 81 set guicursor=n-v:block,i-ci-ve-c:ver25,r-cr:hor20,o:hor50 82 \,a:blinkwait700-blinkoff4000-blinkon2500-Cursor/lCursor 83 \,sm:block-blinkwait175-blinkoff150-blinkon175 84 85 " Set colorscheme and transparent background 86 function! AdaptColorscheme() 87 hi Normal guibg=NONE ctermbg=NONE 88 hi LineNr guibg=NONE ctermbg=NONE 89 hi Folded guibg=NONE ctermbg=NONE 90 hi FoldColumn ctermbg=NONE 91 hi EndOfBuffer guibg=NONE ctermbg=NONE ctermfg=12 92 hi SpecialKey guibg=NONE ctermbg=NONE 93 hi VertSplit guibg=NONE ctermbg=NONE 94 hi SignColumn guibg=NONE ctermbg=NONE 95 hi TabLineSel ctermfg=LightGreen ctermbg=NONE 96 hi TabLineFill ctermfg=Gray ctermbg=NONE 97 hi Title ctermfg=LightBlue ctermbg=NONE 98 hi MatchParen ctermfg=234 ctermbg=208 99 100 if &bg == 'light' 101 hi ColorColumn ctermbg=254 102 else 103 hi ColorColumn ctermbg=240 104 hi CursorLine ctermbg=240 105 endif 106 endfunction 107 108 function! DarkTheme() 109 set bg=dark 110 let g:gruvbox_contrast_dark='hard' 111 colorscheme gruvbox 112 call AdaptColorscheme() 113 endfunction 114 115 function! LightTheme() 116 set bg=light 117 let g:gruvbox_contrast_light='hard' 118 colorscheme gruvbox 119 call AdaptColorscheme() 120 endfunction 121 122 hi TrailingWhitespace ctermbg=yellow guibg=yellow 123 call matchadd("TrailingWhitespace", '\v\s+$') 124 125 if filereadable('/home/mk/.config/scheme/light') 126 call LightTheme() 127 else 128 call DarkTheme() 129 endif 130 131 function ToggleTheme() 132 if &bg == 'dark' 133 call LightTheme() 134 else 135 call DarkTheme() 136 endif 137 endfunction 138 139 nnoremap <silent> <F12> :call ToggleTheme()<CR> 140 141 " Key remaps 142 let mapleader =' ' 143 map <leader>f :NERDTreeToggle<CR> 144 map <leader>F :NERDTreeFocus<CR> 145 map <leader>r :NERDTreeFind<CR> 146 map <leader>s :source $HOME/.config/nvim/init.vim<CR> 147 map <leader>c :make 148 149 " Disable ex-mode keybinding (type visual thing) 150 map Q <NOP> 151 152 " Improves indenting chunks of code with '<' '>' keys 153 vnoremap < <gv 154 vnoremap > >gv 155 156 " Type a replacement term and press . to repeat the replacement again. Useful 157 " for replacing a few instances of the term (comparable to multiple cursors). 158 nnoremap <silent> s* :let @/='\<'.expand('<cword>').'\>'<CR>cgn 159 xnoremap <silent> s* "sy:let @/=@s<CR>cgn 160 161 " Stops highlight after a search hitting return; 162 nnoremap <silent> <CR> :nohlsearch<CR> 163 164 " Shortcut for split navigation 165 noremap <C-Down> <C-W>j<CR> 166 noremap <C-Up> <C-W>k<CR> 167 noremap <C-Left> <C-W>h<CR> 168 noremap <C-Right> <C-W>l<CR> 169 170 " Move between windows with Ctrl + hjkl 171 noremap <C-h> <C-w>h 172 noremap <C-j> <C-w>j 173 noremap <C-k> <C-w>k 174 noremap <C-l> <C-w>l 175 176 " Go to next/prev quickfix 177 nnoremap <C-n> :cnext<CR>zz 178 nnoremap <C-p> :cprev<CR>zz 179 180 " Go to tab by number 181 noremap <leader>1 1gt 182 noremap <leader>2 2gt 183 noremap <leader>3 3gt 184 noremap <leader>4 4gt 185 noremap <leader>5 5gt 186 noremap <leader>6 6gt 187 noremap <leader>7 7gt 188 noremap <leader>8 8gt 189 noremap <leader>9 9gt 190 noremap <leader>0 :tablast<cr> 191 192 " Scroll half page with PageUp/PageDown 193 nnoremap <PageUp> <C-u> 194 nnoremap <PageDown> <C-d> 195 196 " Start interactive EasyAlign in visual mode (e.g. vipga) 197 xmap ga <Plug>(EasyAlign) 198 199 " Start interactive EasyAlign for a motion/text object (e.g. gaip) 200 nmap ga <Plug>(EasyAlign) 201 202 " Highlight whitespace problems. 203 " flags is '' to clear highlighting, or is a string to 204 " specify what to highlight (one or more characters): 205 " e whitespace at end of line 206 " i spaces used for indenting 207 " s spaces before a tab 208 " t tabs not at start of line 209 function! ShowWhitespace(flags) 210 let bad = '' 211 let pat = [] 212 for c in split(a:flags, '\zs') 213 if c == 'e' 214 call add(pat, '\s\+$') 215 elseif c == 'i' 216 call add(pat, '^\t*\zs \+') 217 elseif c == 's' 218 call add(pat, ' \+\ze\t') 219 elseif c == 't' 220 call add(pat, '[^\t]\zs\t\+') 221 else 222 let bad .= c 223 endif 224 endfor 225 if len(pat) > 0 226 let s = join(pat, '\|') 227 exec 'syntax match ExtraWhitespace "'.s.'" containedin=ALL' 228 else 229 syntax clear ExtraWhitespace 230 endif 231 if len(bad) > 0 232 echo 'ShowWhitespace ignored: '.bad 233 endif 234 endfunction 235 236 function! ToggleShowWhitespace() 237 if !exists('b:ws_show') 238 let b:ws_show = 0 239 endif 240 if !exists('b:ws_flags') 241 let b:ws_flags = 'est' " default (which whitespace to show) 242 endif 243 let b:ws_show = !b:ws_show 244 if b:ws_show 245 call ShowWhitespace(b:ws_flags) 246 else 247 call ShowWhitespace('') 248 endif 249 endfunction 250 251 nnoremap <Leader>ws :call ToggleShowWhitespace()<CR> 252 highlight ExtraWhitespace ctermbg=red guibg=red 253 254 nnoremap <A-j> :m .+1<CR>== 255 nnoremap <A-k> :m .-2<CR>== 256 257 nnoremap <Leader>/ :vsplit<CR> 258 nnoremap <Leader>" :split<CR> 259 260 inoremap <A-j> <Esc>:m .+1<CR>==gi 261 inoremap <A-k> <Esc>:m .-2<CR>==gi 262 263 vnoremap <A-j> :m '>+1<CR>gv=gv 264 vnoremap <A-k> :m '<-2<CR>gv=gv 265 266 nnoremap n nzzzv 267 nnoremap N Nzzzv 268 269 function! ToggleQuickFix() 270 if empty(filter(getwininfo(), 'v:val.quickfix')) 271 copen 272 else 273 cclose 274 endif 275 endfunction 276 277 nnoremap <silent> <leader>c :call ToggleQuickFix()<cr> 278 279 set laststatus=1 280 autocmd VimEnter * set laststatus=1 281 282 let NERDTreeHijackNetrw=1 283 let NERDTreeMinimalUI=1 284 285 " Highjack nerdtree's highjacking to keep normal nerdtree from loading on directories 286 " let g:NERDTreeHijackNetrw=0 287 " augroup NERDTreeHijackNetrw 288 " autocmd VimEnter * silent! autocmd! FileExplorer 289 " augroup END 290 291 " autocmd VimEnter * call CloseExtraNERDTree() 292 293 " If vim is started with a file, simply show that file 294 " If vim is started with nothing or a directory close extra NERDTree buffer 295 " function CloseExtraNERDTree() 296 " wincmd l " move to right pane 297 " let l:main_bufnr = bufnr('%') 298 " let l:fname = expand('%') " get name of current buffer 299 " if l:fname ==# 'NERD_tree_1' 300 " exe bufwinnr(l:main_bufnr) . "wincmd w" 301 " bd 302 " endif 303 " endfunction 304 305 function VerboseMark() 306 echo '' 307 let c = getchar() 308 if ((c >= 0x41) && (c <= 0x5A)) || ((c >= 0x61) && (c <= 0x7A)) 309 normal! m nr2char(c) 310 echon "mark `" nr2char(c) "`: line " line(".") ", col " col(".") 311 else 312 return 313 endif 314 endfunction 315 316 let g:asyncrun_open = 12 317 318 " Pressing Ctrl-C during command mode breaks highlight 319 cnoremap <C-c> <Esc> 320 321 " Oposite of <Shift-k> 322 nnoremap K :m-2<CR>J 323 324 function Compile() 325 echohl Question 326 let l:input = split(input("Compile command: ", &makeprg, "filetype"), ' ') 327 echohl None 328 329 if empty(l:input) 330 return 331 endif 332 redraw 333 334 if(!empty(matchstr(l:input, "%"))) 335 if(empty(expand('%'))) 336 echohl Question 337 echo 'Filename empty' 338 echohl None 339 return 340 endif 341 endif 342 343 let string = join(l:input, ' ') 344 " exe "set makeprg = " .. string 345 let &makeprg = string 346 let l:s = &makeprg 347 exe "AsyncRun " .. l:s 348 mod 349 endfunction 350 351 " autocmd BufEnter *.txt if &filetype == 'help' | wincmd T | endif 352 function SearchHelp() 353 mod 354 echohl Question 355 let l:input = substitute(input("Search vim help: ", "", "help"), "\\\'\\\|\\\"", '', 'g') 356 echohl None 357 mod 358 359 if empty(l:input) 360 return 361 endif 362 363 let v:errmsg = "" 364 let l:cmd = "help " .. l:input 365 silent! execute(l:cmd) 366 367 if matchstr(v:errmsg, "no help") != "" 368 echohl WarningMsg 369 mod 370 echo "Sorry, no help for: `" .. l:input .. "`" 371 echohl None 372 else 373 exe "wincmd T | mod | set nornu" 374 endif 375 endfunction 376 377 " autocmd BufEnter *.txt if &filetype == 'man' | wincmd T | endif 378 function SearchMan() 379 echohl Question 380 " let l:input = input("Search man page: ") 381 let l:input = substitute(input("Search man page: "), "\\\'\\\|\\\"", '', 'g') 382 echohl None 383 mod 384 385 if empty(l:input) 386 return 387 endif 388 389 " let l:string = join(l:input, ' ') 390 let l:cmd = "man " .. l:input .. " > /dev/null 2>&1" 391 call system(l:cmd) 392 if v:shell_error == 0 393 if matchstr(expand('%'), "man://") == "" 394 exe "tabnew" 395 exe "Man " .. l:input 396 exe "only" 397 else 398 exe "Man " .. l:input 399 endif 400 401 else 402 echohl WarningMsg 403 mod 404 echon l:input .. ": nothing appropriate." 405 echohl None 406 endif 407 endfunction 408 409 function Search() 410 echohl Question 411 let l:input = split(input("Search keyword in CWD: "), ' ') 412 echohl None 413 if empty(l:input) 414 return 415 endif 416 mod 417 418 let l:string = join(l:input, ' ') 419 echo l:string 420 exe "silent grep -r -I -s --exclude-dir=.git " .. l:string .. " *" 421 copen 422 endfunction 423 424 function JumpBuffer() 425 let l:prev_buffer = expand("#:t") 426 echohl Question 427 let l:input = split(input("Change buffer: ", l:prev_buffer, "buffer"), ' ') 428 echohl None 429 if empty(l:input) 430 return 431 endif 432 mod 433 434 let l:string = join(l:input, ' ') 435 echo l:string 436 if bufexists(l:string) 437 exe "b " .. l:string 438 else 439 if filereadable(l:string) 440 exe "e " .. l:string 441 else 442 exe "e " .. l:string 443 mod 444 echo "Buffer doesn't exists: editinig new file `".. l:string .. "`" 445 endif 446 endif 447 endfunction 448 449 function FindFile() 450 echohl Question 451 let l:input = split(input("Find file: ", expand('%'), "file"), ' ') 452 echohl None 453 if empty(l:input) 454 return 455 endif 456 mod 457 458 let l:string = join(l:input, ' ') 459 echo l:string 460 if bufexists(l:string) 461 exe "b " .. l:string 462 else 463 if filereadable(l:string) 464 exe "e " .. l:string 465 else 466 exe "e " .. l:string 467 mod 468 echo "file doesn't exists: editinig new file `".. l:string .. "`" 469 endif 470 endif 471 endfunction 472 473 nnoremap <C-x><C-f> :call FindFile()<CR> 474 nnoremap <Leader>cc :call Compile()<CR> 475 nnoremap <Leader>cC :make<CR> 476 nnoremap <Leader>v :call Search()<CR> 477 nnoremap <Leader>m :call SearchMan()<CR> 478 nnoremap <Leader>h :call SearchHelp()<CR> 479 nnoremap <Leader>b :call JumpBuffer()<CR> 480 481 function Text() 482 if winwidth('%') > 86 483 set nuw=8 484 endif 485 set tw=80 486 set colorcolumn=80 487 set spelllang=es,en 488 set spell 489 endfunction 490 491 let g:TextMode = 0 492 function ToggleText() 493 if g:TextMode == 0 494 let g:TextMode = 1 495 call Text() 496 else 497 let g:TextMode = 0 498 set nuw=4 499 set tw=0 500 set colorcolumn=0 501 set nospell 502 endif 503 endfunction 504 505 let g:mkdp_browser = 'qutebrowser' 506 507 " make MarkdownPreview's tableofcontents pattern same as latex (for use 508 " with pandoc) 509 let g:mkdp_preview_options = { 510 \ 'toc': { 'placeholder': '\\tableofcontents' } 511 \ } 512 513 nnoremap <silent> <Leader>T :call ToggleText()<CR> 514 nnoremap m :call VerboseMark()<CR> 515 516 au TextYankPost * silent! lua vim.highlight.on_yank() 517 let g:python_highlight_all = 1 518 519 autocmd ColorScheme gruvbox call AdaptColorscheme() 520 521 " close if quickfix is the last window 522 au BufEnter * call MyLastWindow() 523 function! MyLastWindow() 524 " if the window is quickfix go on 525 if &buftype=="quickfix" 526 " if this window is last on screen quit without warning 527 if winbufnr(2) == -1 528 quit! 529 endif 530 endif 531 endfunction 532 533 " enable auto_save for only these filetypes, to see all posible ifletypes 534 " see: https://vi.stackexchange.com/questions/5780/list-known-filetypes 535 let g:auto_save_file_types = [ 'markdown' ] 536 537 " enable auto_save for all filetypes 538 let g:auto_save_all_filetypes = 0 539 540 " Switch to last-active tab 541 if !exists('g:Lasttab') 542 let g:Lasttab = 1 543 let g:Lasttab_backup = 1 544 endif 545 autocmd! TabLeave * let g:Lasttab_backup = g:Lasttab | let g:Lasttab = tabpagenr() 546 autocmd! TabClosed * let g:Lasttab = g:Lasttab_backup 547 nmap <silent> <Leader>; :exe "tabn " . g:Lasttab<cr> 548 549 " Markdown mode 550 function MarkdownMode() 551 so ~/.config/nvim/md-toc.vim 552 function! GeneratePDF() 553 mod 554 let l:filename = expand("%:r") 555 let l:md_filename = l:filename .. ".md" 556 let l:pdf_filename = l:filename .. ".pdf" 557 558 if filereadable(l:md_filename) 559 let l:pdf_generate_cmd = "!md2pdf " .. l:md_filename 560 mod 561 " exe l:pdf_generate_cmd 562 exe "AsyncRun -mode=term -pos=bottom -rows=3 " .. l:pdf_generate_cmd 563 else 564 mod 565 echohl WarningMsg 566 echo "File `" .. l:md_filename .. "` not found in CWD" 567 echohl None 568 endif 569 endfunction 570 571 " requires neovim-remote to clear command line 572 function! OpenPDF() 573 let l:filename = expand("%:r") 574 let l:pdf_filename = l:filename .. ".pdf" 575 let l:server_name = v:servername 576 577 " Check if pdf exists 578 if filereadable(l:pdf_filename) 579 let l:open_pdf_cmd = "!xdg-open " .. l:pdf_filename .. " &" 580 silent exe l:open_pdf_cmd 581 mod 582 echohl Question 583 echon "Opening `" .. l:pdf_filename .. "`" 584 echohl None 585 else 586 echohl WarningMsg 587 echo "File `" .. l:pdf_filename .. "` not found in CWD" 588 echohl None 589 endif 590 endfunction 591 592 nnoremap <buffer> <F9> :MarkdownPreviewToggle<CR> 593 autocmd TermOpen * set cmdheight=0 | set laststatus=0 | exe 594 \"au WinClosed <buffer> set cmdheight=1 | set laststatus=1 | mod" 595 \| nnoremap <silent> <buffer> <Esc> :close<CR> | mod 596 nnoremap <silent> <buffer> <F11> :call GeneratePDF()<CR> 597 nnoremap <silent> <buffer> <F12> :call OpenPDF()<CR> 598 nnoremap <silent> <tab> :TocToggle<CR> 599 600 " do not treat underscore as errors in certain contexts 601 " https://github.com/tpope/vim-markdown/issues/21 602 hi link markdownError NONE 603 endfunction 604 605 au FileType markdown silent! call MarkdownMode() 606 " au CursorHold,CursorHoldI * mod 607 608 " delete word in command/prompt mode with Ctrl + Backspace 609 cnoremap <C-H> <C-w> 610 cnoremap <C-BS> <C-H> 611 612 let $FZF_DEFAULT_OPTS = "" 613 let g:fzf_layout = {'down':'10'} 614 " let g:fzf_layout = { 'window': { 'width': 1.0, 'height': 0.25, 'relative': v:true, 'yoffset': 1.0 } } 615 616 autocmd! FileType fzf 617 autocmd FileType fzf set laststatus=0 noshowmode noruler nonumber norelativenumber cmdheight=0 618 \| autocmd BufLeave <buffer> set laststatus=1 showmode ruler number relativenumber cmdheight=1 619 620 " enable syntax highlight inside markdown codeblocks 621 let g:markdown_fenced_languages = [ 622 \"html", "javascript", "js=javascript", "go", "golang=go", 623 \"css", "dot", "xml", "python", "c", "c++=cpp", "sh", 624 \"bash=sh", "vim", "lua" ] 625
