" 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 path+=** " Full tab completion with subfolders and all set inccommand=nosplit " Live preview of substitutes and other similar commands set clipboard^=unnamedplus " system clipboard (requires +clipboard) set number " Line numbers on set noshowmode " Always hide mode set showtabline=2 " Always Show tabline set pumheight=12 " Completion window max size set noswapfile " New buffers will be loaded without creating a swapfile set hidden " Enables to switch between unsaved buffers and keep undo history set lazyredraw " Don't redraw while executing macros (better performance) set showmatch " Show matching brackets when text indicator is over them set matchpairs+=<:> " Add HTML brackets to pair matching set matchtime=1 " Tenths of a second to show the matching paren set cpoptions-=m " showmatch will wait 0.5s or until a char is typed set nojoinspaces " No extra space when joining a line which ends with . ? ! set updatetime=300 " Update time used to create swap file or other things set synmaxcol=200 " Don't try to syntax highlight minified files set splitbelow " Splitting a window will put the new window below the current set splitright " Splitting a window will put the new window right of the current set notimeout " Time out on key codes but not mappings. set ignorecase " Ignore case by default set cursorline " Hightlight the screen line of the cursor set scrolloff=5 " Keep this many lines padding when scrolling set shortmess+=aoOIWcs " Shorten messages and don't show intro set foldnestmax=10 " Deepest fold is 10 levels set foldmethod=marker " Markers are used to specify folds. set foldclose=all " Folds closed by default set foldlevelstart=10 " Don't auto open folds after this many levels set selectmode=key " Shift + arrow keys for selecting text set keymodel=startsel " This one complements the one above it set signcolumn=yes " Gutter for diagnostics and git status set modeline " Vim customized by text files commands 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 conceallevel=1 set diffopt+=algorithm:histogram,indent-heuristic set pastetoggle= setlocal tabstop=8 " Number of spaces a equals setlocal shiftwidth=4 " Number of spaces to use in auto(indent) setlocal softtabstop=4 " While performing editing operations setlocal shiftround " Round indent to multiple of 'shiftwidth' setlocal breakindent " Keep indentation setlocal expandtab " Use spaces instead of tabs. Mostly for linting reasons setlocal nosmarttab " Don't mix tabs and spaces and do weird stuff match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' if &diff set textwidth=80 highlight! link DiffText MatchParen endif 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 aug END aug file_types au FileType typescript,json setlocal formatexpr=CocAction('formatSelected') au FileType json syntax match Comment +\/\/.\+$+ au FileType make setlocal noexpandtab au FileType gitcommit,gitrebase,gitconfig set bufhidden=delete au BufNewFile,BufRead requirements*.txt set syntax=python au BufRead,BufNewFile /tmp/neomutt* set filetype mail au BufNewFile ~/doc/blog/*.wiki :silent 0r !diario.py % 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_set_balloons = 1 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'], \ 'javascript': ['prettier_standard'], \ 'jsx': ['prettier_standard'], \ 'typescript': ['prettier_standard'], \ 'json': ['prettier_standard'], \ 'scss': ['stylelint'], \ 'css': ['stylelint'], \ 'html': ['prettier_standard'], \ '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'] " 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 let g:coc_snippet_next = '' " 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 'othree/yajs.vim', {'for': 'javascript'} Plug 'othree/es.next.syntax.vim', {'for': 'javascript'} Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'jpalardy/vim-slime', {'for': ['python', 'foxdot']} 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 " }}} " 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() " }}} " REPL {{{ let g:slime_paste_file = '$HOME/.cache/slime_paste' let g:slime_target = 'neovim' let g:slime_python_ipython = 1 let g:my_active_terminal_job_id = -1 function! LaunchTerminal() range silent exe "normal! :12split\n" silent exe "normal! :terminal\n" call SetActiveTerminalJobID() endfunction function! LaunchSC() range abort silent exe "normal! :tabnew\n" silent exe "normal! :terminal\n" call SetActiveTerminalJobID() call jobsend(g:my_active_terminal_job_id, "scsynth -u 57110\r") sleep 2200ms silent exe "normal! G" silent exe "normal! :vsplit\n" silent exe "normal! :terminal\n" call SetActiveTerminalJobID() call jobsend(g:my_active_terminal_job_id, "sclang -D ~/doc/Algorave/foxdot.scd\r") silent exe "normal! :tabprev\n" silent exe "normal! \n" sleep 2200ms silent exe "normal! G" endfunction function! LaunchIpython() range abort call LaunchTerminal() call jobsend(g:my_active_terminal_job_id, "ipython\r") sleep 2200ms silent exe "normal! G" endfunction function! LaunchFoxDot() range abort call LaunchTerminal() call jobsend(g:my_active_terminal_job_id, "ipython\r") sleep 2200ms call jobsend(g:my_active_terminal_job_id, "from FoxDot import *\r") silent exe 'normal! G' endfunction function! SetActiveTerminalJobID() let g:my_active_terminal_job_id = b:terminal_job_id echom "Active terminal job ID set to " . g:my_active_terminal_job_id endfunction map xi :call LaunchIpython() map xs :call LaunchSC() map xd :call LaunchFoxDot() map xf :set filetype=foxdot "}}} "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 :call LaunchTerminal() 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 ? 'j' : 'gj' nnoremap k 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 " Global replace with prompt nnoremap cw \ :let b:sub = input('interactive replacement: ') \ if b:sub !=? '' \ execute "%s//".b:sub.'/gc' \ 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 " prompt before each replace vnoremap cw "hy \ :let b:sub = input('interactive replacement: ') \ if b:sub !=? '' \ let b:rep = substitute(getreg('h'), '/', '\\/', 'g') \ execute '%s/'.b:rep.'/'.b:sub.'/gc' \ unlet b:sub b:rep \ endif "}}} "Terminal {{{ " Terminal movement tnoremap tnoremap h tnoremap j tnoremap k tnoremap l "}}} "}}} " vim:foldmethod=marker:foldlevel=0