" ========= 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: