Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/dotfiles
Path: blob/master/files/vimrc
244 views
" ========= Auto-install ================== {{{
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 | source $MYVIMRC
endif
" }}}

" ========= Plugins ======================= {{{

" === vim-polyglot
" Disable polyglot for go because we use vim-go
let g:polyglot_disabled = ['go']

call plug#begin('~/.local/share/nvim/plugged')

"Plug 'Valloric/YouCompleteMe'           " Code completion
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'dense-analysis/ale'                         " Asynchronous linter
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'                 " Fast fuzzy finder (:fzf)
Plug 'tpope/vim-fugitive'               " Awesome git wrapper (:Git)
Plug 'tpope/vim-surround'               " Parentheses surrounded (ys, cs, ds)
Plug 'tpope/vim-unimpaired'             " Bracket mappings
Plug 'jiangmiao/auto-pairs'             " Autoclose brackets, parens, quotes
Plug 'junegunn/vim-easy-align'          " Easy align stuff! (Use `ga`)
Plug 'justinmk/vim-dirvish'             " File explorer
Plug 'kristijanhusak/vim-dirvish-git'   " Plug git into dirvish
"Plug 'lilydjwg/colorizer'               " Colorize hex #FFF
Plug 'aos/tslime.vim'                   " Send commands from vim to tmux
" Markdown previewer
"Plug 'kannokanno/previm', { 'for': 'markdown' }
"Plug 'iamcco/markdown-preview.nvim', { 'for': 'markdown' }

" Go swiss army knife
"Plug 'fatih/vim-go', { 'for': ['go'], 'do': ':GoUpdateBinaries' }

" On-demand lazy-loaded syntax highlighting for ALL the languages
Plug 'sheerun/vim-polyglot'
"Plug 'numirias/semshi', { 'do': ':' }
" Rainbow parentheses for scheme/lisp
"Plug 'junegunn/rainbow_parentheses.vim', { 'for': ['scheme', 'lisp'] }
" Grab vim-sexp for selecting forms
Plug 'guns/vim-sexp', { 'for': ['scheme', 'lisp'] }
" And let's make it easier to use
Plug 'tpope/vim-sexp-mappings-for-regular-people', { 'for': ['scheme', 'lisp'] }

" Language servers (for deoplete)
Plug 'zchee/deoplete-jedi'                                        " Python
"Plug 'carlitux/deoplete-ternjs', { 'do': 'npm install -g tern' }  " JS

" Colorschemes
Plug 'cocopon/iceberg.vim'
Plug 'lifepillar/vim-gruvbox8'
"Plug 'romainl/Apprentice'
"Plug 'habamax/vim-alchemist'
"Plug 'bluz71/vim-moonfly-colors'
"Plug 'joshdick/onedark.vim'
"Plug 'mhartington/oceanic-next'
"Plug 'keith/parsec.vim'
"Plug 'jnurmine/Zenburn'
"Plug 'caksoylar/vim-mysticaltutor'
"Plug 'Nequo/vim-allomancer'
"Plug 'crusoexia/vim-monokai'
"Plug 'drewtempelmeyer/palenight.vim'
"Plug 'mhartington/oceanic-next'
"Plug 'junegunn/seoul256.vim'
"Plug 'jnurmine/Zenburn'
"Plug 'chriskempson/base16-vim'
"Plug 'tyrannicaltoucan/vim-deep-space'
call plug#end()
" }}}

" ========= General Config ================ {{{
let mapleader = ","                     " Map leader to comma
let maplocalleader = "\\"               " Maps local leader to backslash
set number 	                        " line numbers
set wrap                                " Wrap lines
set history=1000	                " Store lots of :cmdline history
set showcmd		                " Show incomplete commands
set showmode		                " Show current mode
set visualbell		                " No sounds
set clipboard=unnamed,unnamedplus	" Use system clipboard with yank
set relativenumber                      " See NumberToggle function below
set title		                " Give more detailed title
set hidden                              " Allows making buffers hidden
set backspace=indent,eol,start          " Proper backspace behavior
set timeoutlen=400
set autoread                            " Auto-read file when changed from outside
set textwidth=79                        " Set the max text with, use 'gq'
set spelllang=en
"set spellfile=$HOME/GDrive/vim/spell/en.utf-8.add  " Sets spellfile
set inccommand=nosplit                  " Shows realtime changes of Ex command
set viewoptions=""                      " Remove :mkview all together

" Sets cursor types based on mode (bar and line)
if exists("$TMUX")
  let &t_SI = "\ePtmux;\e\e[5 q\e\\"
  let &t_EI = "\ePtmux;\e\e[2 q\e\\"
  " This allows italics and bold within tmux and vim
  let &t_8f="\<Esc>[38;2;%lu;%lu;%lum"
  let &t_8b="\<Esc>[48;2;%lu;%lu;%lum"
else
  let &t_SI = "\e[5 q"
  let &t_EI = "\e[2 q"
endif
" }}}

" ========= Status line =================== {{{
set laststatus=2                        " Always show statusbar

set statusline=
set statusline+=%#ColorColumn#            " Buffer number color
set statusline+=\ %-1.2n\               " Space offset for buffer number
set statusline+=%{GitInfo()}\           " Set git info with color
set statusline+=%#ColorColumn#          " CursorColumn color
set statusline+=%f                      " Relative path to file
set statusline+=\%r%w                   " Read-only flag (and preview)
set statusline+=\ %m                    " Modified flag
set statusline+=%=                      " Right align
set statusline+=\ %y                    " Filetype
set statusline+=\ %l:%c\ %L             " Line number : column number (total lines)
set statusline+=\ %p%%                  " Percent
set statusline+=\ 
" }}}

" ========= Indentation =================== {{{
" Number of spaces that a <Tab> counts for while editing
set softtabstop=2
" Indentation amount for < and > commands
let &shiftwidth = &softtabstop
set shiftround      " Round indent to multiple of 'shiftwidth'
set expandtab       " Insert spaces when <Tab> is pressed
"set tabstop=2       " Render tabs using this many spaces
" }}}

" ========= Colorscheme and filetype ===== {{{
filetype plugin indent on
syntax enable
"set termguicolors
set background=dark " can use light for gruvbox8
"let g:oceanic_next_terminal_bold=1
"let g:oceanic_next_terminal_italic=1
"let g:onedark_terminal_italics=1
colorscheme iceberg " one of apprentice or gruvbox8{_soft, hard}
if &background == "light"
  colorscheme iceberg
endif
"let g:gruvbox_plugin_hi_groups = 1
"let g:gruvbox_transp_bg = 1
"let g:seoul256_background = 234
"let g:deepspace_italics=1
"let g:palenight_terminal_italics=1
"let g:monokai_term_italic = 1
let g:jsx_ext_required = 0               " JSX syntax highlight in .js files
"let ruby_operators = 1                  " Highlights ruby operators
" }}}

" ========= GUI color/syntax ============== {{{
set cursorline
set cursorcolumn
"highlight column 80
set colorcolumn=80

if &background == "dark"
  highlight ColorColumn guibg=#3A3A3A
  highlight CursorLine guibg=#2F2F2F
  highlight CursorColumn guibg=#2F2F2F

  " == Tab bar coloring
  highlight TabLineFill guibg=#3A3A3A guifg=#3A3A3A
  highlight TabLine guibg=#B7B7B7 guifg=#3A3A3A
  highlight TabLineSel guifg=#D6B600
endif

highlight LineNr guibg=NONE
highlight SignColumn guibg=NONE

" == Remove tildes at end of buffer
"highlight EndOfBuffer ctermbg=NONE ctermfg=NONE guibg=NONE guifg=NONE

" == Highlight extra whitespace as green
highlight ExtraWhitespace guibg=lightgreen
" }}}

" ========= Menu and other options ======== {{{
set splitbelow    " Always open vsplit below
set splitright    " ... and to right
set undofile 	  " Persistent undo
set lazyredraw    " Speed up buffer loading
set modeline      " Enable modeline -> Allows custom config for each file
set nojoinspaces  " Prevents inserting two spaces after punctuation on join
set wildchar=<Tab>
set wildmenu      " Opens wildmenu for tab completion of commands
set wildmode=longest:list,full
set listchars=tab:▸\ ,eol:¬
" }}}

" ========= Folding options =============== {{{
set foldmethod=indent                     " Fold based on indent
set foldnestmax=3                         " Deepest fold is 3 levels
set foldlevelstart=99                     " All folds open by default
highlight! link Folded Special
" }}}

" ========= Plugin options ================ {{{
" === fzf
let g:fzf_layout = { 'window': '10new' }

" === ale
let g:ale_linters = {
  \ 'javascript': ['eslint'],
  \ 'python': ['flake8'],
  \ 'ruby': ['rubocop'],
  \ 'jsx': ['eslint', 'stylelint'],
  \ 'markdown': ['markdownlint'],
  \ 'rust': ['analyzer'],
\}
let g:ale_fixers = {
  \ 'python': ['black'],
\}
let g:ale_sign_error = '▶▶'
let g:ale_sign_warning = '┄┄'
"let g:ale_linters_explicit = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
let g:ale_fix_on_save = 1
let g:ale_javascript_eslint_suppress_missing_config = 1

hi! link ALEErrorSign WarningMsg
hi! link ALEWarningSign WarningMsg
hi! ALEError ctermbg=none
hi! ALEWarning ctermbg=none

" === vim-go
let g:go_fmt_command = "goimports"
let g:go_fmt_fail_silently = 1
let g:go_highlight_diagnostic_errors = 0
let g:go_highlight_diagnostic_warnings = 0

" Map moving between lint errors to C-k and C-j
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)

" === Previm -- preview file using :PrevimOpen
"let g:previm_open_cmd = 'qutebrowser --target tab'

" === Tslime
let g:tslime_always_current_session = 1
let g:tslime_always_current_window = 1
" Send paragraph (vip) to Tmux
nmap <localleader>n <Plug>NormalModeSendToTmux
" Send selection to Tmux
vmap <localleader>s <Plug>SendSelectionToTmux
" Reset the session, window, and pane info
nmap <localleader>R <Plug>SetTmuxVars
" Send something to Tmux
nmap <localleader>t :Tmux

" === Easy Align
" Interactive EA in visual mode (vipga)
xmap ga <Plug>(EasyAlign)

" Start interactive EA for motion/text object (gaip)
nmap ga <Plug>(EasyAlign)

" === Dirvish Git
hi DirvishGitStaged guifg=#689D6A guibg=#262626
hi DirvishGitModified guifg=#D65D0E guibg=#262626
hi DirvishGitUntracked guifg=#9D0006 guibg=#262626
" }}}

" ========= Python provider install ======= {{{
"if has('mac')
"  let g:python3_host_prog = '/usr/local/bin/python3'
"  let g:python_host_prog = '/usr/bin/python'
"endif
" }}}

" ========= Deoplete global options ======= {{{
" Use tab and S-tab to cycle between autocomplete
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
" Autoclose preview window
autocmd! InsertLeave,CompleteDone * if pumvisible() == 0 | pclose | endif
let g:deoplete#enable_at_startup = 1
"let g:ycm_global_ycm_extra_conf = '~/.vim/.ycm_extra_conf.py'
"let g:ycm_autoclose_preview_window_after_insertion = 1
" completions for go (using vim-go)
call deoplete#custom#option('omni_patterns', { 'go': '[^. *\t]\.\w*' })
" }}}

" ========= Turn off swap files =========== {{{
set noswapfile
set nobackup
set nowritebackup
" }}}
" ========= Scrolling ===================== {{{
set scrolloff=8		" Scroll when we're 8 lines away from margins
set sidescrolloff=7
set sidescroll=1

set mouse=a
" }}}

" ========= Searching ===================== {{{
set hlsearch        " Highlight search
set ignorecase
set smartcase
set infercase
"set gdefault        " Use 'g' flag by default with :s/foo/bar
set magic           " Use 'magic' patterns (extended reg exp)
set incsearch       " Incremental search, hit '<CR>' to stop

if has('mac')
  set wildignorecase " Ignores case when completing file names and dirs
endif

" Redefines # and * for visual mode to search visually selected
function! s:VSetSearch()
  let temp = @s
  norm! gv"sy
  let @/ = '\V' . substitute(escape(@s, '|'), '|n', '||n', 'g')
  let @s = temp
endfunction

xnoremap * :<C-u>call <SID>VSetSearch()<CR>/<C-R>=@/<CR><CR>
xnoremap # :<C-u>call <SID>VSetSearch()<CR>?<C-R>=@/<CR><CR>
" }}}

" ========= Functions ===================== {{{

" Switch between dark and light theme
function! SwitchTheme()
  if &background == "dark"
    set background=light
    "colorscheme gruvbox8_soft
  else
    set background=dark
    "colorscheme alchemist
  endif
endfunc

" <<deprecated>> Toggle between relative and absolute line numbers
function! NumberToggle()
  if(&relativenumber == 1)
    set nornu
    set number
  else
    set rnu
  endif
endfunc

" Open daily log and append a time stamp
function! AppendToLog()
  let time=strftime('%F')
  sp ~/.daily_log
  call append('$', ['', time])
  execute "normal! Go* "
  startinsert!
endfunc

" JSON pretty print
function! JSONify()
  if executable('jq')
    %!jq '.'
  else
    %!python -mjson.tool
  endif
  set syntax=json
endfunction

" Redirect the output of a Vim or external command into a scratch buffer
function! Redir(cmd)
  for win in range(1, winnr('$'))
    if getwinvar(win, 'scratch')
      execute win . 'windo close'
    endif
  endfor
  if a:cmd =~ '^!'
    execute "let output = system('" . substitute(a:cmd, '^!', '', '') . "')"
  else
    redir => output
    execute a:cmd
    redir END
  endif
  vnew
  let w:scratch = 1
  setlocal nobuflisted buftype=nofile bufhidden=wipe noswapfile
  call setline(1, split(output, "\n"))
endfunction
" Usage:
"   :Redir hi           show the full output of command ':hi' in scratch win
"   :Redir !ls -al      show the full output of command ':!ls -al' in scratch
command! -nargs=1 -complete=command Redir silent call Redir(<f-args>)

function! GitInfo()
  let git = FugitiveHead()
  if git != ''
    return '(' . git . ')'
  else
    return ''
endfunction

" Create a scratch buffer, can give it a filetype using an option such as:
" ft=javascript
function! ScratchEdit(cmd, options)
  exe a:cmd tempname()
  setl buftype=nofile bufhidden=wipe nobuflisted
  if !empty(a:options) | exe 'setl' a:options | endif
endfunction

command! -bar -nargs=* Sedit call ScratchEdit('edit', <q-args>)
command! -bar -nargs=* Ssplit call ScratchEdit('split', <q-args>)
command! -bar -nargs=* Svsplit call ScratchEdit('vsplit', <q-args>)
command! -bar -nargs=* Stabedit call ScratchEdit('tabe', <q-args>)
" }}}

" ========= Key mappings ================== {{{

" Map 'Y' to be like 'C' and 'D' -- for consistency
nnoremap Y y$

" When pasting in visual mode don't replace my register with selection
xnoremap <silent> p p:if v:register == '"'<Bar>let @@=@0<Bar>endif<CR>

" Clear search highlight with escape key
nnoremap <silent> <Esc> :noh<CR><Esc>

" Maps insert-mode 'jk' to escape key
inoremap jk <Esc>

" Map neovim terminal exit to jk
tnoremap jk <C-\><C-n>

" Open file explorer in new vertical split pane
nnoremap _ <C-w>v:Dirvish<CR>

" Highlight last INSERTED text
nnoremap gV `[v`]

" Remap Q to be @@ so that replaying macros is that much easier
nnoremap Q @@

" Map neovim terminal exit to jk
tnoremap jk <C-\><C-n>

" Remaps original <Tab> function (forward jumplist) to <C-p>
" We do this because we end up using <Tab> for FZF
noremap <C-p> <Tab>

" Remap BS in normal mode to flip back to the last buffer
nnoremap <BS> <C-^>

"=== Command-line {{{
" start of line
cnoremap <C-A> <Home>
" back one character
cnoremap <C-B> <Left>
" delete character under cursor
cnoremap <C-D> <Del>
" end of line
cnoremap <C-E> <End>
" forward one character
cnoremap <C-F> <Right>
" recall newer command-line
cnoremap <C-N> <Down>
" recall previous (older) command-line
cnoremap <C-P> <Up>
" }}}

" === Custom text objects {{{
" inner-line
xnoremap <silent> il :<C-u>normal! g_v^<CR>
onoremap <silent> il :<C-u>normal! g_v^<CR>
" }}}

" === Operator pending ======== {{{

" Inside last/next parenthesis and go to insert mode
onoremap in( :<c-u>normal! f(vi(<CR>
onoremap il( :<c-u>normal! F(vi(<CR>
" }}}

" === Swap ; and : functionality {{{

" Use ':' to go to next item in list
"noremap : ;
" Use ';' for commands
"noremap ; :
" }}}

" === Fold mappings =========== {{{

" Map folding to <Space>
noremap <Space> za
noremap <expr> <Leader><Space> &foldlevel ? 'zM' : 'zR'
" }}}

" === Movement mappings ======= {{{

" Remap 'j' and 'k' to account for text wrapping
noremap j gj
noremap k gk

" Map moving to beginning and end of line
noremap H ^
nnoremap L $
onoremap L $
vnoremap L g_

" Map moving page up and down
"noremap <C-j> <C-d>
"noremap <C-k> <C-u>
" }}}

" === Leader mappings ========= {{{

" Open command look up file
nnoremap <Leader>m :sp ~/.cmd_lookup<CR>

" Quick-edit daily log
nnoremap <Leader>l :call AppendToLog()<CR>

" Quick-edit .vimrc (horizontal split)
nnoremap <Leader>ev :sp ~/.vimrc<CR>

" Quick-source .vimrc
nnoremap <Leader>sv :source ~/.vimrc<CR>

" Save a session (can be re-opened with nvim -S)
nnoremap <Leader>n :mksession<CR>

" Toggle between normal and relative numbering (deprecated, use vim-unimpaired's 'yor')
" nnoremap <silent> <Leader>r :call NumberToggle()<CR>

" Map search and replace to 's', global and ask for confirmation
nnoremap <Leader>s :%s///gc<Left><Left><Left><Left>

" Map highlighting trailing whitespace (wn -> On, wf -> Off, wd -> Delete)
nnoremap <Leader>wn :match ExtraWhitespace /\s\+$/<CR>
nnoremap <Leader>wf :match<CR>
nnoremap <Leader>wd :%s/\s\+$//e<CR>

" Copy current file name (relative/absolute) to system clipboard
" relative path (src/foo.txt)
nnoremap <Leader>cfr :let @+=expand("%")<CR>

" absolute path (/usr/blah/src/foo.txt)
nnoremap <Leader>cfa :let @+=expand("%:p")<CR>

" filename only (foo.txt)
nnoremap <Leader>cff :let @+=expand("%:t")<CR>

" directory name (/usr/blah/src)
nnoremap <Leader>cfd :let @+=expand("%:p:h")<CR>
" }}}

" === FZF and Ag ============== {{{
" Use project root (through git)
function! s:find_git_root()
  return system('git rev-parse --show-toplevel 2> /dev/null')[:-2]
endfunction
command! PF execute 'Files' s:find_git_root()

" Augment Ag with preview window
" Options: delimiter to remove searching file names as well
command! -bang -nargs=* Ag
  \ call fzf#vim#ag(
  \ <q-args>,
  \ <bang>0 ? fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'up:60%')
  \         : fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'right:50%:hidden', '?'),
  \ <bang>0)

" Augment :Files with preview window
command! -bang -nargs=? -complete=dir Files
  \ call fzf#vim#files(<q-args>,
  \                    fzf#vim#with_preview('right:50%:hidden', '?'),
  \                    <bang>0)

" Map fzf most-recently-used file search
noremap <Leader>h :History<CR>
noremap <Leader>f :Files<CR>
" Map silver_searcher
noremap <Leader>g :Ag
" Map buffer list and open (fzf)
noremap <Tab> :Buffers<CR>
" }}}
" }}}

" ========= Commands ====================== {{{

" Calls JSONify to pretty print JSON
command! J :call JSONify()

" Make current buffer executable
command! Chmodx :!chmod a+x %

command! Theme :call SwitchTheme()

" Toggle spellchecker (deprecated, use vim-unimpaired's 'yos')
" command! Spell :setlocal spell! spell?
" }}}

" ========= Autocmds ====================== {{{

augroup js_comment
  autocmd!
  autocmd FileType javascript noremap <Leader>/ I// <Esc><Left><Left>
augroup END

augroup py_ruby_comment
  autocmd!
  autocmd FileType python noremap <Leader>/ I# <Esc><Left><Left>
augroup END

augroup remove_extra_comments_js_c
  autocmd!
  autocmd FileType c,cpp,javascript,javascript.jsx setlocal comments-=:// comments+=f://
augroup END

"augroup remove_extra_comments_ruby_py
"  autocmd!
"  autocmd FileType python,ruby setlocal formatoptions-=c formatoptions-=r formatoptions-=o
"augroup END

" Add rainbow parenthesis and remove autopairs matching for ' and `
augroup rainbow_autopairs_lisp_scheme_clojure
  autocmd!
  autocmd FileType lisp,clojure,scheme
    \ RainbowParentheses |
    \ let b:AutoPairs = {'(':')', '[':']', '{':'}', '"':'"'}
augroup END

augroup save_views_and_folds
  autocmd!
  autocmd BufWinLeave *.* mkview
  autocmd BufWinEnter *.* silent! loadview
augroup END

" Dirvish config
augroup dirvish_config
  autocmd!
  " Map `t` to open in new tab.
  autocmd FileType dirvish
    \  nnoremap <silent><buffer> t :call dirvish#open('tabedit', 0)<CR>
    \ |xnoremap <silent><buffer> t :call dirvish#open('tabedit', 0)<CR>
  " Map `gh` to hide dot-prefixed files.  Press `R` to 'toggle' (reload).
  autocmd FileType dirvish nnoremap <silent><buffer>
    \  gh :silent keeppatterns g@\v/\.[^\/]+/?$@d _<CR>
augroup END

" Go config
augroup golang_config
  autocmd!
  autocmd FileType go setlocal noet ts=8 sw=8 sts=8
augroup END
" }}}

" Rust Analyzer / ALE mappings
augroup rust_config
  autocmd!
  autocmd FileType rust nnoremap <silent>gd :ALEGoToDefinition<CR>
  autocmd FileType rust nnoremap <silent>gD :ALEFindReferences<CR>
augroup END
" vim: foldmarker={{{,}}}:foldmethod=marker: