" Important stuff {{{ 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 let g:python3_host_prog = '/usr/bin/python3' let g:node_host_prog = '/usr/local/bin/neovim-node-host' let g:tagbar_ctags_bin = '/usr/bin/ctags' let python_highlight_all=1 " full python syntax highlighting " }}} " Plugins {{{ call plug#begin('~/.config/nvim/plugged') Plug 'w0rp/ale' Plug 'othree/yajs.vim', {'for': 'javascript'} Plug 'othree/es.next.syntax.vim', {'for': 'javascript'} Plug 'mhartington/nvim-typescript', {'do': './install.sh', 'for': 'typescript'} Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'sheerun/vim-polyglot' Plug 'liuchengxu/vista.vim' Plug 'jpalardy/vim-slime' Plug 'tmsvg/pear-tree' Plug 'tpope/vim-commentary' Plug 'honza/vim-snippets' Plug 'mhartington/oceanic-next' call plug#end() " }}} " Options {{{ set binary 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 fileencoding=utf-8 " The encoding written to file. set shell=/bin/zsh " Setting shell to zsh set number " Line numbers on set noshowmode " Always hide mode set showtabline=2 " Always Show tabline set pumheight=12 " Completion window max size set helpheight=12 " Minimum help window height 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 visualbell " Use visual bell instead of beeping 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 tabstop=8 " Number of spaces a equals set shiftwidth=4 " Number of spaces to use in auto(indent) set softtabstop=4 " While performing editing operations set shiftround " Round indent to multiple of 'shiftwidth' set breakindent " Keep indentation set expandtab set nosmarttab set title set redrawtime=500 set ttimeoutlen=10 set nowritebackup set completeopt-=preview set nostartofline set modeline set undofile set undolevels=1000 set undoreload=10000 set undodir=$HOME/.config/nvim/undo set formatoptions+=nl set pastetoggle= set grepprg=rg\ --vimgrep\ --hidden\ --no-heading set grepformat=%f:%l:%c:%m,%f:%l:%m set wildignore+=*.jpg,*.jpeg,*.bmp,*.gif,*.png,*.svg " image set wildignore+=*.manifest " gb set wildignore+=*.o,*.obj,*.exe,*.dll,*.so,*.out,*.class " compiler set wildignore+=*.swp,*.swo,*.swn " vim set wildignore+=*/.git,*/.hg,*/.svn,*/node_modules " vcs if &diff set textwidth=80 highlight! link DiffText MatchParen endif match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' let mapleader="\" let maplocalleader=',' let formatlistpat='^\s*\(\d\+[\]:.)}\t ]\|[*-][\t ]\)\s*' let g:polyglot_disabled = ['javascript', 'python'] let g:markdown_fenced_languages = ['vim', 'help'] " }}} " {{{ 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'], \ 'html': ['prettier'], \ 'css': ['stylelint'], \ 'scss': ['stylelint'], \ 'bash': ['shellcheck'], \ 'sh': ['shellcheck'], \ 'vim': ['vint'], \ 'python': ['pyls', 'flake8', 'pylint'] \} let g:ale_fixers = { \ 'javascript': ['prettier_standard'], \ 'jsx': ['prettier_standard'], \ 'typescript': ['prettier'], \ 'json': ['prettier'], \ 'scss': ['stylelint'], \ 'css': ['stylelint'], \ 'html': ['prettier'], \ 'markdown': ['prettier'], \ 'python': ['autopep8', 'remove_trailing_lines', '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-tsserver', 'coc-emmet', 'coc-css', 'coc-html', 'coc-json'] " Explorer nmap :CocCommand explorer " Config nnoremap :CocConfig " Lists nnoremap :CocList -S --ignore-case helptags nnoremap :CocList -S --ignore-case files nnoremap :CocList --normal buffers nnoremap :CocList windows " to confirm completion inoremap pumvisible() ? "\" : "\" 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 " Snippets imap (coc-snippets-expand-jump) let g:coc_snippet_next = '' let g:coc_snippet_prev = '' " Python nnoremap gp :CocCommand python.execInTerminal nnoremap gr :CocCommand python.startREPL "}}} " Vista {{{ let g:vista#renderer#enable_icon = 1 let g:vista_default_executive = 'ctags' let g:vista_disable_statusline = 1 let g:vista_sidebar_width = 35 let g:vista_executive_for = { \ 'javascript': 'coc', \ 'javascript.jsx': 'coc', \ 'python': 'ctags', \ } nnoremap :Vista!! " }}} " JS {{{ let g:vim_jsx_pretty_colorful_config = 1 let g:jsx_ext_required = 1 let g:yats_host_keyword = 1 "}}} " Colors {{{ set termguicolors let g:oceanic_next_terminal_italic = 1 colorscheme OceanicNext function! MyHighlights() abort highlight Trail ctermbg=red guibg=red call matchadd('Trail', '\s\+$', 100) highlight ColorColumn ctermbg=magenta call matchadd('ColorColumn', '\%81v', 100) endfunction hi! VertSplit ctermbg=NONE ctermfg=NONE guibg=#080808 guifg=#080808 hi! Comment cterm=italic ctermbg=NONE guibg=NONE hi! Normal ctermbg=NONE guibg=NONE hi! NonText ctermbg=NONE guibg=NONE hi! LineNr guibg=NONE hi! CursorLineNr ctermbg=236 ctermfg=NONE guibg=#303030 hi! CursorLine ctermbg=236 ctermfg=NONE guibg=#303030 hi! SignColumn ctermbg=NONE guibg=NONE hi! Folded ctermbg=NONE guibg=NONE hi! TabLineFill ctermfg=NONE ctermbg=NONE guibg=#080808 guifg=#080808 hi! TablineSel ctermfg=234 ctermbg=4 guibg=#008bbd guifg=#1c1c1c hi! EndOfBuffer ctermbg=NONE ctermfg=NONE guibg=NONE guifg=#080808 hi! WildMenu ctermfg=228 ctermbg=0 guifg=#ffff00 guibg=#000000 hi! link CocErrorSign WarningMsg hi! link CocWarningSign Number hi! link CocInfoSign Type " }}} " Statusline {{{ highlight User1 ctermfg=251 ctermbg=NONE guibg=#080808 guifg=#c6c6c6 highlight User2 ctermfg=234 ctermbg=NONE guibg=#f74782 guifg=#1c1c1c highlight User3 ctermfg=234 ctermbg=4 guibg=#008bb4 guifg=#1c1c1c highlight User4 ctermfg=234 ctermbg=251 guibg=#c6c6c6 guifg=#1c1c1c highlight User5 ctermfg=234 ctermbg=4 guibg=#e64eff guifg=#1c1c1c highlight User6 ctermfg=234 ctermbg=9 guibg=#fbad34 guifg=#1c1c1c highlight User7 ctermfg=234 ctermbg=251 guibg=#407e4a guifg=#ffffff let g:modes={ \ 'n' : ['%3*', 'NORMAL'], \ 'no' : ['%3*', 'NORMAL·OPERATOR PENDING'], \ 'v' : ['%5*', 'VISUAL'], \ 'V' : ['%5*', 'V·LINE'], \ '^V' : ['%5*', 'V·BLOCK'], \ 's' : ['%7*', 'SELECT'], \ 'S' : ['%7*', 'S·LINE'], \ '^S' : ['%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! 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! ModeColor() abort return get(g:modes, mode(), '%*')[0] endfunction function! CurrentMode() abort return ' ' . get(g:modes, mode(), '-')[1] . ' ' endfunction function! LinePasteMode() let paste_status = &paste if paste_status == 1 return ' paste ' else return '' endif endfunction function! Statusline() let b:status='' let b:status.=ModeColor() let b:status.=CurrentMode() let b:status.=LinePasteMode() let b:status.='%1* ' let b:status.='%= ' let b:status.=coc#status() let b:status.=' %6*' let b:status.=LinterStatus() let b:status.='%3* %p%% %c ' return b:status endfunction set statusline=%!Statusline() " }}} " 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') . ' ' : '[No Name] ') if bufmodified let s .= ' + ' endif endfor let s .= '%#TabLineFill#' if (exists('g:tablineclosebutton')) let s .= '%=%999XX' endif return s endfunction set tabline=%!Tabline() " }}} " AutoCommands {{{ if !exists('autocommands_loaded') && has('autocmd') let autocommands_loaded = 1 " Plug updates itself automatically if empty(glob('~/.config/nvim/autoload/plug.vim')) silent !curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim aug Plugged au VimEnter * PlugInstall --sync | source $MYVIMRC aug END endif function! PopOutOfInsertMode() if v:insertmode call feedkeys("\\") endif endfunction function! Relativize(v) if &number let &relativenumber = a:v endif endfunction function! LocalStatusLine() let b:status = '%#error#[HELP]%*' return b:status endfunction aug relativize au BufWinEnter,FocusGained,InsertLeave,WinEnter * call Relativize(1) au BufWinLeave,FocusLost,InsertEnter,WinLeave * call Relativize(0) aug END aug status_line au FileType help setlocal statusline=%!LocalStatusLine() au FileType man setlocal statusline=%!LocalStatusLine() aug END aug on_save " Delete whitespace on :w au BufWritePre * :%s/\s\+$//e au BufWritePost *xresources !xrdb % au BufWritePost *sxhkdrc !pkill -USR1 sxhkd au QuitPre * if empty(&buftype) | lclose | endif aug END aug term_stuff au TermOpen * setlocal nonumber norelativenumber au TermOpen * setlocal laststatus=0 au TermOpen * setlocal nocursorline au TermOpen * setlocal signcolumn=no au TermOpen * setlocal noshowmode au TermOpen * setlocal noruler aug END aug miscs " Highlight symbol under cursor on CursorHold 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 * setlocal nocursorline au InsertLeave * setlocal cursorline au InsertLeave * setlocal nopaste au InsertLeave,CompleteDone * if pumvisible() == 0 | pclose | endif au FocusLost,TabLeave * call PopOutOfInsertMode() 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 * setl formatoptions-=cro au FileType typescript,json setl formatexpr=CocAction('formatSelected') au FileType json syntax match Comment +\/\/.\+$+ aug END endif " }}} " REPL {{{ 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 ~/Music/LiveCoding/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 "}}} " Vim-Tmux Navigator {{{ " Intelligently navigate tmux panes and Vim splits using the same keys. " See https://sunaku.github.io/tmux-select-pane.html for documentation. let progname = substitute($VIM, '.*[/\\]', '', '') set title titlestring=%{progname}\ %f\ +%l\ #%{tabpagenr()}.%{winnr()} if &term =~? '^screen' && !has('nvim') | exe "set t_ts=\e]2; t_fs=\7" | endif "}}} "Mappings {{{ "Normal {{{ " Plug nnoremap pu :PlugUpdate " Ñ 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 " Maximize current split vertically nnoremap z " Make all splits equal size vertically nnoremap Z " Edit and source config file nnoremap ev :vsplit $MYVIMRC nnoremap sv :source $MYVIMRC " Fast saves nnoremap w :w! " Fast closes nnoremap b :bdelete " Fast exits nnoremap q :q! nnoremap Q :qa! " Fast leave insert mode cnoremap jk " Fast beginning and end of document nnoremap gg nnoremap ¿ G " Fast message checking nnoremap m :messsages " Splits nnoremap T :call LaunchTerminal() nnoremap s :split nnoremap v :vsplit nnoremap nv :vnew nnoremap ns :new " My vim wants to enter all the time, enter all the time nnoremap i " 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 " 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 " What about the Q nnoremap Q map q " Shift butterfinger :command! WQ wq :command! Wq wq :command! Wqa wqa :command! Wa wa :command! WA wa :command! W w :command! Q q :command! Qa qa :command! QA qa "}}} "Insert {{{ inoremap jk inoremap kj " Ensure that ctrl+u in insert mode can be reversed " http://vim.wikia.com/wiki/Recover_from_accidental_Ctrl-U inoremap u inoremap u " Deedee 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 < p "_dP "}}} "Terminal {{{ " Terminal movement tnoremap tnoremap h tnoremap j tnoremap k tnoremap l "}}} "}}} " Functions {{{ function! CmdLine(str) call feedkeys(':' . a:str) endfunction " vp doesn't replace paste buffer function! RestoreRegister() let @" = s:restore_reg return '' endfunction function! s:Repl() let s:restore_reg = @" return "p@=RestoreRegister()\" endfunction vmap p Repl() " 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 nnoremap sw \ :let b:sub = input('global replacement: ') \ if b:sub !=? '' \ execute "%s//".b:sub.'/g' \ unlet b:sub \ 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 nnoremap cw \ :let b:sub = input('interactive replacement: ') \ if b:sub !=? '' \ execute "%s//".b:sub.'/gc' \ unlet b:sub \ endif " local keyword jump nnoremap fw \ [I:let b:jump = input('Go To: ') \ if b:jump !=? '' \ execute "normal! ".b:jump."[\t" \ unlet b:jump \ endif " }}} " vim:foldmethod=marker:foldlevel=0