" Important {{{ scriptencoding utf-8 " Set utf-8 as default script encoding let g:loaded_python_provider=1 " Disable python 2 interface let g:python_host_skip_check=1 " Skip python 2 host check if filereadable('bin/python3') let g:python3_host_prog = '/bin/python3' endif let g:node_host_prog = '~/.local/share/npm/bin/neovim-node-host' let $GIT_EDITOR = 'nvr -cc split --remote-wait' if empty(glob('~/.local/share/nvim/site/autoload/plug.vim')) silent !curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim autocmd VimEnter * PlugInstall --sync | call coc#util#install() | source $MYVIMRC endif " }}} " Options {{{ set inccommand=nosplit set clipboard^=unnamedplus set number set noshowmode set showtabline=2 set pumheight=12 set noswapfile set hidden set lazyredraw set showmatch set matchpairs+=<:> set matchtime=1 set cpoptions-=m set nojoinspaces set updatetime=300 set synmaxcol=200 set splitbelow set splitright set notimeout set ignorecase set scrolloff=5 set sidescroll=5 set shortmess+=aoOIWcs set foldnestmax=10 set foldmethod=marker set foldclose=all set foldlevelstart=10 set selectmode=key set keymodel=startsel set signcolumn=yes set tabstop=2 set shiftwidth=2 set softtabstop=2 set shiftround set linebreak set breakindent set expandtab set nosmarttab set title set redrawtime=500 set ttimeoutlen=10 set nowritebackup set completeopt-=preview set nostartofline set undofile set undolevels=1000 set undoreload=10000 set formatoptions+=nl set formatoptions-=crot set fillchars+=vert:\ set listchars+=precedes:<,extends:> set conceallevel=1 set diffopt+=algorithm:histogram,indent-heuristic set pastetoggle= match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' let mapleader="\" let maplocalleader=',' let formatlistpat='^\s*\(\d\+[\]:.)}\t ]\|[*-][\t ]\)\s*' let g:netrw_dirhistmax=0 " }}} " Functions {{{ function! MyHighlights() abort highlight Trail ctermbg=red guibg=red call matchadd('Trail', '\s\+$', 100) highlight ColorColumn ctermbg=magenta call matchadd('ColorColumn', '\%81v', 100) endfunction function! PopOutOfInsertMode() abort if v:insertmode call feedkeys("\\") endif endfunction function! Relativize(v) abort if &number let &relativenumber = a:v endif endfunction function! CmdLine(str) call feedkeys(':' . a:str) endfunction function! s:new_mail() let l:path = system('mktemp --tmpdir XXXXXXXXXX.eml') execute 'sp' l:path 0r ~/.config/nvim/templates/skeleton.eml | w | $ endfunction command! Mail call s:new_mail() " }}} " AutoCommands {{{ if !exists('autocommands_loaded') && has('autocmd') let autocommands_loaded = 1 aug relativize au BufWinEnter,FocusGained,InsertLeave,WinEnter * call Relativize(1) au BufWinLeave,FocusLost,InsertEnter,WinLeave * call Relativize(0) aug END aug term_stuff au TermOpen * setlocal nonumber norelativenumber laststatus=0 au TermOpen * setlocal signcolumn=no noruler nocursorline scrolloff=0 aug END aug miscs au CursorHold * silent call CocActionAsync('highlight') au CursorHold * call CocActionAsync('doHover') au User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') au ColorScheme * call MyHighlights() aug END aug inserts au InsertEnter * norm zz au InsertEnter * setlocal nocursorline au InsertLeave * setlocal cursorline nopaste au InsertLeave,CompleteDone * if pumvisible() == 0 | pclose | endif au FocusLost,TabLeave * call PopOutOfInsertMode() au WinLeave * setlocal nocursorline aug END aug skeletons au BufNewFile *.py 0r ~/.config/nvim/templates/py.skeleton au BufNewFile *.sh 0r ~/.config/nvim/templates/sh.skeleton au BufNewFile ~/doc/blog/*.wiki :silent 0r !diario.py % aug END aug file_types au FileType typescript,json setlocal formatexpr=CocAction('formatSelected') au FileType gitcommit,gitrebase,gitconfig set bufhidden=delete au BufNewFile,BufRead requirements*.txt set syntax=python au BufRead,BufNewFile /tmp/neomutt* set filetype=mail aug END aug statusline au VimEnter * call UpdateInactiveWindows() au VimEnter,WinEnter,BufWinEnter * call RefreshStatusLine('active') au WinLeave * call RefreshStatusLine('inactive') augroup END aug on_save au BufWritePre * :%s/\s\+$//e au BufWritePost *xresources !xrdb % au BufWritePost *sxhkdrc !pkill -USR1 sxhkd au BufWritePost *.tex !pdflatex % au QuitPre * if empty(&buftype) | lclose | endif aug END endif " }}} " {{{ Ale let g:ale_use_global_executables = 1 let g:ale_completion_enabled = 0 let g:ale_linters_explicit = 1 let g:ale_lint_delay = 0 let g:ale_lint_on_text_changed = 'normal' let g:ale_lint_on_insert_leave = 1 let g:ale_fix_on_save = 1 let g:ale_close_preview_on_insert = 1 let g:ale_sign_highlight_linenrs = 1 let g:ale_sign_error = '✖' let g:ale_sign_warning = '⚠' let g:ale_sign_info = '●' let g:ale_virtualtext_cursor = 1 let g:ale_loclist_msg_format = '[%linter%] %s% (code)% [%severity%]' let g:ale_set_highlights = 1 let g:ale_set_signs = 1 let g:ale_python_mypy_options = '--ignore-missing-imports' let g:ale_python_pylint_options = '--disable=C' let g:ale_python_flake8_options = '--ignore=E221' let g:move_key_modifier = 'N' let g:ale_linter_aliases = { \ 'jsx': ['css', 'javascript'], \ 'vue': ['vue', 'javascript'], \} let g:ale_linters = { \ 'javascript': ['prettier_standard'], \ 'jsx': ['prettier_standard'], \ 'typescript': ['tsserver', 'eslint'], \ 'json': ['prettier_standard'], \ 'html': ['prettier_standard'], \ 'css': ['stylelint'], \ 'scss': ['stylelint'], \ 'bash': ['shellcheck'], \ 'sh': ['shellcheck'], \ 'vim': ['vint'], \ 'tex': ['chktex'], \ 'python': ['pyls', 'flake8', 'pylint'] \} let g:ale_fixers = { \ '*': ['remove_trailing_lines', 'trim_whitespace'], \ 'jsx': ['prettier_standard'], \ 'javascript': ['prettier_standard'], \ 'typescript': ['prettier_standard'], \ 'json': ['prettier_standard'], \ 'html': ['prettier_standard'], \ 'scss': ['stylelint'], \ 'css': ['stylelint'], \ 'markdown': ['prettier_standard'], \ 'python': ['autopep8', 'isort', 'yapf'] \} let g:ale_pattern_options = { \ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, \ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, \} nmap (ale_previous_wrap) nmap (ale_next_wrap) " }}} " CoC {{{ let g:coc_global_extensions = ['coc-lists', 'coc-highlight', 'coc-explorer', 'coc-snippets', 'coc-python', 'coc-tsserver', 'coc-css', 'coc-html', 'coc-json', 'coc-emmet'] " Lists nnoremap :CocList -S --ignore-case helptags nnoremap :CocList -S --ignore-case files nnoremap :CocList --normal buffers nnoremap :CocList windows nnoremap :CocList snippets " Explorer nnoremap :CocCommand explorer " Config nnoremap :CocConfig inoremap \ pumvisible() ? coc#_select_confirm() : \ coc#expandableOrJumpable() ? "\=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\" : \ check_back_space() ? "\" : \ coc#refresh() function! s:check_back_space() abort let col = col('.') - 1 return !col || getline('.')[col - 1] =~# '\s' endfunction " to confirm completion inoremap pumvisible() ? "\" : "\" " Use to trigger completion. inoremap coc#refresh() " GoTo code navigation. nnoremap gd (coc-definition) nnoremap gr (coc-references) " Use K to show documentation in preview window. nnoremap D :call show_documentation() function! s:show_documentation() if (index(['vim','help'], &filetype) >= 0) execute 'h '.expand('') else call CocAction('doHover') endif endfunction " Symbol renaming. nnoremap rn (coc-rename) "}}} "{{{ Polyglot let g:polyglot_disabled = ['javascript', 'python'] let g:vim_markdown_toc_autofit = 1 let g:markdown_fenced_languages = ['vim', 'help'] let g:vim_jsx_pretty_colorful_config = 1 let g:jsx_ext_required = 1 let g:tex_flavor='latex' let g:tex_conceal='abdmg' let g:Tex_DefaultTargetFormat ='pdf' let g:vimtex_motion_matchparen = 0 let g:vimtex_complete_enable = 1 let g:vimtex_compiler_progname = 'nvr' let g:vimtex_view_use_temp_files = 2 let g:vimtex_view_method = 'zathura' let g:vimtex_quickfix_mode = 0 "}}} " Plugins {{{ call plug#begin(stdpath('data') . '/plugged') Plug 'dense-analysis/ale' Plug 'lervag/vimtex', {'for': 'latex'} Plug 'othree/yajs.vim', {'for': 'javascript'} Plug 'othree/es.next.syntax.vim', {'for': 'javascript'} Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'sheerun/vim-polyglot' Plug 'tmsvg/pear-tree' Plug 'tpope/vim-commentary' Plug 'lambdalisue/gina.vim' Plug 'srcery-colors/srcery-vim' call plug#end() " }}} " Colors {{{ set termguicolors let g:srcery_transparent_background = 1 let g:srcery_italic = 1 let g:srcery_underline = 1 let g:srcery_undercurl = 1 let g:srcery_inverse_matches = 1 colorscheme srcery highlight! VertSplit ctermbg=NONE ctermfg=NONE cterm=NONE guibg=NONE guifg=#080808 gui=NONE highlight! TabLineFill ctermbg=NONE ctermfg=NONE cterm=NONE guibg=NONE guifg=#ef2f27 gui=NONE highlight! TablineSel ctermbg=NONE ctermfg=234 guibg=NONE guifg=#008bbd highlight! CocWarningHighlight ctermfg=4 cterm=undercurl guifg=#c4ab39 gui=undercurl highlight! CocErrorHighlight ctermfg=red cterm=undercurl guifg=#c4384b gui=undercurl highlight! CocUnderline cterm=undercurl gui=undercurl highlight! PmenuSel guibg=#111111 guifg=#6699cc highlight! Folded ctermbg=NONE guibg=NONE highlight! RedrawDebugClear guibg=#080808 highlight! NvimInternalError guifg=#080808 highlight! DiffAdded guifg=#333333 highlight! PmenuThumb guifg=#333333 highlight! link CocErrorSign WarningMsg highlight! link CocWarningSign Number highlight! link CocInfoSign Type if &diff highlight! link DiffText MatchParen endif " }}} " Statusline {{{ highlight User1 ctermfg=251 ctermbg=NONE guibg=NONE guifg=#c6c6c6 highlight User2 ctermfg=234 ctermbg=NONE guibg=NONE guifg=#f74782 highlight User3 ctermfg=234 ctermbg=4 guibg=NONE guifg=#008bb4 highlight User4 ctermfg=234 ctermbg=251 guibg=NONE guifg=#c6c6c6 highlight User5 ctermfg=234 ctermbg=4 guibg=NONE guifg=#e64eff highlight User6 ctermfg=234 ctermbg=9 guibg=NONE guifg=#fbad34 highlight User7 ctermfg=234 ctermbg=251 guibg=NONE guifg=#407e4a let g:modes={ \ 'n' : ['%3*', 'NORMAL'], \ 'no' : ['%3*', 'N·OPERATOR PENDING'], \ 'v' : ['%5*', 'VISUAL'], \ 'V' : ['%5*', 'V·LINE'], \ '' : ['%5*', 'V·BLOCK'], \ 's' : ['%7*', 'SELECT'], \ 'S' : ['%7*', 'S·LINE'], \ '' : ['%7*', 'S·BLOCK'], \ 'i' : ['%4*', 'INSERT'], \ 'R' : ['%2*', 'REPLACE'], \ 'Rv' : ['%2*', 'V·REPLACE'], \ 'c' : ['%6*', 'COMMAND'], \ 'cv' : ['%6*', 'VIM EX'], \ 'ce' : ['%6*', 'EX'], \ 'r' : ['%1*', 'PROMPT'], \ 'rm' : ['%1*', 'MORE'], \ 'r?' : ['%1*', 'CONFIRM'], \ '!' : ['%*1', 'SHELL'], \ 't' : ['%*1', 'TERMINAL'] \} function! ModeColor() abort return get(g:modes, mode(), '%*')[0] endfunction function! CurrentMode() abort return ' ' . get(g:modes, mode(), '-')[1] . ' ' endfunction function! StatusLine() abort let l:statusline='' let l:statusline.=ModeColor() let l:statusline.=CurrentMode() let l:statusline.=LinePasteMode() let l:statusline.='%<' let l:statusline.='%1* ' let l:statusline.='%= ' let l:statusline.=coc#status() let l:statusline.=' %6*' let l:statusline.=LinterStatus() let l:statusline.='%3* %p%% %c ' let l:statusline.='' return l:statusline endfunction function! StatusLineNC() abort let l:statusline='' let l:statusline.='%t' let l:statusline.='%<' let l:statusline.='%= ' return l:statusline endfunction function! HelpStatusLine() abort let l:statusline='' let l:statusline.= '%#error#[HELP] %t ' let l:statusline.='%1* ' let l:statusline.='%<' let l:statusline.='%= ' let l:statusline.=' %p%% ' return l:statusline endfunction function! UpdateInactiveWindows() for winnum in range(1, winnr('$')) if winnum != winnr() call setwinvar(winnum, '&statusline', '%!StatusLineNC()') endif endfor endfunction function! RefreshStatusLine(mode) if (a:mode == "active" && &filetype !=? 'help') setlocal statusline=%!StatusLine() else setlocal statusline=%!StatusLineNC() endif if &filetype ==? 'help' setlocal statusline=%!HelpStatusLine() endif endfunction function! LinterStatus() abort let l:counts = ale#statusline#Count(bufnr('')) let l:all_errors = l:counts.error + l:counts.style_error let l:all_non_errors = l:counts.total - l:all_errors return l:counts.total == 0 ? '' : printf( \ ' ⚠ :%d ✖ :%d ', \ l:all_non_errors, \ l:all_errors \) endfunction function! LinePasteMode() abort let paste_status = &paste if paste_status == 1 return ' paste ' else return '' endif endfunction " }}} " Tabline {{{ function! Tabline() let s = '' for i in range(tabpagenr('$')) let tab = i + 1 let winnr = tabpagewinnr(tab) let buflist = tabpagebuflist(tab) let bufnr = buflist[winnr - 1] let bufname = bufname(bufnr) let bufmodified = getbufvar(bufnr, '&mod') let s .= '%' . tab . 'T' let s .= (tab == tabpagenr() ? '%#TabLineSel#' : '%#TabLine#') let s .= ' ' . tab .':' let s .= (bufname !=? '' ? fnamemodify(bufname, ':t') . ' ' : '[Untitled] ') if bufmodified let s .= ' + ' endif endfor let s .= '%#TabLineFill#' if (exists('g:tablineclosebutton')) let s .= '%=%999XX' endif return s endfunction set tabline=%!Tabline() " }}} "Mappings {{{ "Normal {{{ " Ñ master race nnoremap ñ ; nnoremap Ñ , " Rearrange Splits nnoremap H nnoremap L nnoremap K nnoremap J " Resize splits nnoremap :vertical resize -2 nnoremap :vertical resize +2 nnoremap :resize -1 nnoremap :resize +1 " Alt to switch windows nnoremap nnoremap nnoremap nnoremap " Edit and source config file nnoremap ev :vsplit $MYVIMRC nnoremap sv :source $MYVIMRC " Gotta Go Fast (save, buffer close, quit, messages, SOF, EOF) nnoremap g :w! nnoremap b :bdelete nnoremap q :q! nnoremap Q :qa! nnoremap m :messages nnoremap gg nnoremap ¿ G " Splits nnoremap t :terminal nnoremap v :vnew nnoremap s :new " Quote words under cursor nnoremap " viWa"gvoi"gvo3l nnoremap ' viWa'gvoi'gvo3l " Move a line of text using Shift+[jk] nnoremap mz:m+`z nnoremap mz:m-2`z " My vim wants to enter all the time, enter all the time nnoremap + i " Unhighlight search terms nnoremap :noh=has('diff')?'diffupdate':'' " j = gj :: k = gk while preserving numbered jumps ie. 12j or 30k nnoremap j v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj' nnoremap k v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk' " Line movements noremap g noremap g nnoremap Y 0y$ nnoremap y y$ " Tab movement nnoremap tn :tabnew nnoremap th :tabfirst nnoremap tl :tablast nnoremap tx :tabclose " Center view on search result nnoremap n nzz nnoremap N Nzz nnoremap * *zz nnoremap # #zz nnoremap g* g*zz nnoremap g# g#zz " Prevent x from overriding what's in the clipboard. nnoremap x "_x nnoremap X "_x " Prevent selecting and pasting from overwriting what you originally copied. xnoremap p pgvy " Global replace nnoremap sw \ :let b:sub = input('global replacement: ') \ if b:sub !=? '' \ execute "%s//".b:sub.'/g' \ unlet b:sub \ endif " What about the Q nnoremap Q map q "}}} "Insert {{{ " Ensure that ctrl+u in insert mode can be reversed " http://vim.wikia.com/wiki/Recover_from_accidental_Ctrl-U inoremap u inoremap u " Exit insert, dd line, enter insert inoremap ddi " Line movements inoremap g inoremap g " Alt to switch windows inoremap h inoremap j inoremap k inoremap l "}}} "Visual {{{ " Fast beginning and end of document vnoremap ¿ G vnoremap gg " Visual mode pressing # searches for the current selection vnoremap # :call VisualSelection('', '')?=@/ " Move a line of text using Shift+[jk] vnoremap :m'>+`mzgv`yo`z vnoremap :m'<-2`>my`j v:count ? 'j' : 'gj' vnoremap k v:count ? 'k' : 'gk' " Line movements vnoremap $ $h " Fix indentation without leaving visual mode vnoremap > >gv vnoremap < " Delete current visual selection and dump in black hole buffer before pasting " Used when you want to paste over something without it getting copied to " Vim's default buffer vnoremap p "_dP " global replace vnoremap sw "hy \ :let b:sub = input('global replacement: ') \ if b:sub !=? '' \ let b:rep = substitute(getreg('h'), '/', '\\/', 'g') \ execute '%s/'.b:rep."/".b:sub.'/g' \ unlet b:sub b:rep \ endif "}}} "Terminal {{{ " Terminal movement tnoremap tnoremap h tnoremap j tnoremap k tnoremap l "}}} "}}} " vim:foldmethod=marker:foldlevel=0