scripts/dotfiles/vimrc

398 lines
13 KiB
VimL

" Basic settings -------------------------------------------------------------
set shell=/bin/bash " Set default shell
set encoding=utf-8 " Set file encoding to UTF-8
set nomodeline " Disable modeline (run code on file open)
set nocompatible " Reset vi compatibility presets
set backspace=indent,eol,start " Enable backspace key in insert mode
syntax on " Enable syntax highlighting
set clipboard=unnamedplus " Use system clipboard
set textwidth=79 " Column width to 79
set colorcolumn=79 " Set column to highlight for textwidth
set wrap " Visual/soft line wrap
set linebreak " Only insert breaks on breakat chars
set nolist " Disable line break, see:
set wrapmargin=0 " vim.wikia.com > tip 989
set autoindent " Auto-indent on line break
set smartindent " Smart indent
set shiftwidth=2 " Set indentation
set tabstop=2
set softtabstop=2
set expandtab " Convert tab to spaces
set shiftround " Indent in multiples of shiftwidth
set cursorline " Highlight current line
set title " Show file title
set number " Show line numbers
set ruler " Show cursor position
set showbreak=" Show line breaks
set showmatch " Show matching opening/closing char
set showcmd " Show command used (bottom bar)
set showmode " Show current mode (bottom bar)
set wildmenu " Enable menu for autocomplete options
set wildmode=list:longest,full " List matches by longest common sections, all
set wildignore=*.tmp,*~ " Exclude some filetypes from wildmenu
set splitbelow " Horizontal split below
set splitright " Vertical split to the right
set hidden " Switch between buffers without save prompt
" To autosave: :set autowrite or autowriteall
set foldenable " Enable code folding
set foldmethod=indent " See :h foldmethod for other options
set foldlevelstart=10 " 0 = all folds closed, 99 = all folds open
set lazyredraw " No redraw when running macros
set cryptmethod=blowfish " Set default encryption method
set history=1000 " Set no. of lines in undo history
set viminfo= " Disable viminfo
" To move viminfo to ~/.vim instead:
" set viminfo+=n~/.vim/viminfo
set noswapfile " Disable *.swp files
set noerrorbells " Disable sounds
set visualbell
set t_vb=
set incsearch " Start searching on input
set nohlsearch " Disble search highlighting
set ignorecase " Ignore case in search for lowercase input
set smartcase " Case-sensitive search for mixed case input
set spelllang=en_gb " Set spell check language
set timeoutlen=2000 " Set timeout (ms) for key mappings
set autochdir " Change into a file's directory on open
colorscheme gruvbox " See :color <tab> for options
set background=dark " Set light/dark bg for themes that use it
" Highlight trailing whitespace
" https://vi.stackexchange.com/q/8563
highlight ExtraWhitespace guibg=#870000 ctermbg=088
match ExtraWhitespace /\s\+$\|\t/
augroup ExtraWhitespace
au!
au BufWinEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
au InsertLeave * match ExtraWhitespace /\s\+$/
augroup END
if !has('gui_running')
set t_Co=256 " Use 256 colorscheme in terminal mode
set mouse=n " Disable mouse support
endif
" Omni Complete
set omnifunc=syntaxcomplete#Complete " Enable autocompletion
set complete=".,b,i" " Include current buffer, current file
" other loaded buffers
set dictionary+=~/.vim/dict/other " Set custom dict
" Key mappings ---------------------------------------------------------------
" Set <leader> key
let mapleader=','
" Move to beginning/end of line
nmap b 0
nmap e $
" Move to prev/next visual row
nmap j gj
nmap k gk
" Keep indent block selected
" https://github.com/bling/dotvim
vmap < <gv
vmap > >gv
" Remap ctrl+d to toggle between shell and vim
nmap <c-d> :sh<cr>
" Disable ctrl+z to avoid accidentally stopping vim
nmap <c-z> <nop>
" Move page down/up
nmap <c-j> <c-f>
nmap <c-k> <c-b>
" Buffer navigation — go to N, prev, next, left, right
nmap <leader>bg :ls<cr>:b
nmap <leader>bh :bprev<cr>
nmap <leader>bl :bnext<cr>
nmap <space>[ <c-w>h<cr>
nmap <space>] <c-w>l<cr>
" Buffer width resize — decrease, increase
nmap <leader>b- :vertical res -5<cr>
nmap <leader>b= :vertical res +5<cr>
" Buffer loading — close, new (vsplit), reload, new (same split)
nmap <leader>bc :bw<cr>
nmap <leader>bn :enew<cr>
nmap <leader>br :e<cr>
nmap <leader>bv <c-w>v:enew<cr>
" Backup file in current buffer
nmap <leader>bk :call BackupFile()<cr>
" Map delete to a black hole register (separate from cut/paste register)
map <leader>d "_d
" Map expression register (used to evaluate expressions)
imap <leader>ee <c-r>=
" Code folding — collapse all, expand all, toggle current fold
nmap <leader>fc zM<cr>
nmap <leader>fe zR<cr>
nmap <leader>ft za<cr>
" Git commands
nmap <leader>ga :!git add .<cr>
nmap <leader>gb :!git branch -b
nmap <leader>gc :!git commit -m
nmap <leader>gca :!git commit<cr>
nmap <leader>gco :!git checkout
nmap <leader>gd :!git diff<cr>
nmap <leader>gf :!git fetch<cr>
nmap <leader>gg :!git grep
nmap <leader>gl :!git log<cr>
nmap <leader>gm :!git merge<cr>
nmap <leader>gph :!git push<cr>
nmap <leader>gpl :!git pull<cr>
nmap <leader>gs :!git status<cr>
" New markdown note
nmap <leader>md :call AddNewFile('$HOME/', '', 'md')<cr>
" Toggle netrw browser
nmap <silent> <leader>nt :call ToggleNetrw()<cr>
" Map OmniComplete
imap <leader>o <c-x><c-o>
" Insert paste into file from cat input
" https://stackoverflow.com/a/2545242
nmap <leader>pp :r! cat<cr>
" Search for selection, prompt for replacement, replace all in file
" https://stackoverflow.com/a/31172452
vnoremap <leader>sa "0y<esc>:%s/<c-r>0//g<left><left>
" Prompt for search/replace text, replace all in selection
vnoremap <leader>sr :s///g<left><left><left>
" Toggle spell check
nmap <leader>sc :setl spell!<cr>
" Search in current directory
nmap <leader>sd :!grep -R <left>
" Toggle search term highlighting
nmap <leader>sh :set nohlsearch!<cr>
" Sessions — load (waits for file input), save
nmap <leader>sl :source $HOME/.vim/sessions/
nmap <leader>ss :mksession! $HOME/.vim/sessions/
" Tab navigation — close, prev, next, new
" To go directly to tab n: [n]gt
nmap <leader>tc :tabc<cr>
nmap <leader>th :tabp<cr>
nmap <leader>tl :tabn<cr>
nmap <leader>tn :tabe<cr>
" Edit/refresh to apply vimrc changes
nmap <leader>ve :tabe $MYVIMRC<cr>
nmap <leader>vr :source $MYVIMRC<cr>
" Show word count
" https://unix.stackexchange.com/a/145293
nmap <leader>wc g<c-g><cr>
vmap <leader>wc :s/\S\+//gn<cr>
" Trim leading whitespace
" https://unix.stackexchange.com/a/29619
" To reset cursor at first selected line: vmap <leader>wsl :%le<cr>
vmap <leader>wl :normal 0dw<cr>
" Trim trailing whitespace
" http://oualline.com/vim-cook.html#trim
" https://vim.fandom.com/wiki/Remove_unwanted_spaces
nmap <leader>wst :1,$s/[ <tab>]*$//<cr>
vmap <leader>wst :s/\s\+$//<cr>
" Netrw
" ----------------------------------------------------------------------------
" Settings
let g:netrw_banner = 0 " Hide info header
let g:netrw_browse_split = 3 " 0: reuse window, 1: hsplit, 2: vsplit,
" 3: new tab, 4: previous window
let g:netrw_dirhistmax = 0 " 0: disable history/bookmarks
let g:netrw_keepdir = 0 " Sync dir view and change dir paths
let g:netrw_liststyle = 0 " 0: thin, 1: long, 2: wide, 3: tree
let g:netrw_winsize = 25 " Set pane width
" Set the default path for the scratchpad used by buffer functions
" Default path: ~/.vim/scratchpad
let g:scratch_dir = 'scratchpad'
" Map keys within the file browser
" https://vonheikemen.github.io/devlog/tools/using-netrw-vim-builtin-file-explorer/
fun! MapNetrwKeys()
" Toggle hidden file visibility
nmap <buffer> . gh
" Files — copy, delete, move, rename, select
nmap <buffer> fc mc
nmap <buffer> fd D
nmap <buffer> fm mm
nmap <buffer> fr R
nmap <buffer> v mf
" Go back in history
nmap <buffer> h u
" Close file preview buffer
nmap <buffer> P <C-w>z
endfun
aug netrw_keymaps
au!
autocmd filetype netrw call MapNetrwKeys()
augroup END
" Toggle the file browser
" https://stackoverflow.com/questions/5006950/setting-netrw-like-nerdtree
fun! g:ToggleNetrw()
Lexplore
vertical resize 25
endfun
" Functions ------------------------------------------------------------------
" Trim trailing whitespace (can be used on filetype)
" e.g. au BufWrite *.* :call DeleteExtraWS()
" https://amix.dk/vim/vimrc.html
fun! g:DeleteExtraWS()
exe 'normal mz'
%s/\s\+$//ge
exe 'normal `z'
endfun
" Create a new file
fun! g:AddNewFile(path, name, ext)
let date = strftime('%Y-%m-%d')
let fn = '-' . a:name
if a:name == ''
let fn = ''
endif
exe 'tabe' a:path . '/' . date . fn . '.' . a:ext
endfun
" Backup the file in the current buffer
" https://www.ibm.com/developerworks/library/l-vim-script-2/index.html
fun! g:BackupFile()
let b:timestamp = strftime('%Y%m%d%H%M%S')
return writefile(getline(1,'$'), bufname('%') . '-' . b:timestamp)
endfun
" Wrap a word/selection in brackets
" Based on http://learnvimscriptthehardway.stevelosh.com/chapters/09.html
" and https://superuser.com/a/875160
let g:WrapWordChars = {
\ '<':'>', '{':'}', '[':']', '(':')', '"':'"', "'":"'", '`':'`',
\ }
fun! g:WrapWord(prefix)
" Temporarily disable Auto Pairs plugin if enabled
if exists('b:autopairs_enabled')
let l:isapenabled = b:autopairs_enabled
let b:autopairs_enabled = 0
endif
" Add key mappings to prefix + char for insert and select modes
for c in keys(g:WrapWordChars)
exe 'inoremap <silent>' . a:prefix . c . ' <esc>viw<esc>a' .
\ g:WrapWordChars[c] . '<esc>bi' . c . '<esc>ea<right>'
exe 'vnoremap <silent>' . a:prefix . c . ' xi' . c .
\ g:WrapWordChars[c] . '<esc>P'
endfor
" Restore user settings
if exists('b:autopairs_enabled')
let b:autopairs_enabled = l:isapenabled
endif
endfun
call g:WrapWord('<leader>w')
" Filetypes ------------------------------------------------------------------
filetype plugin indent on
" Group autocommand calls to avoid duplicates whenever writing to buffer
" http://learnvimscriptthehardway.stevelosh.com/chapters/14.html
" Set indentation by filetype (not set with other basic settings as they will
" override filetype setl whenever vimrc is reloaded)
" shiftwidth: indent/unindent width
" tabstop: tab width in spaces (view)
" softtabstop: tab width in spaces (edit)
augroup Filetypes
au!
" CSS/Sass
au FileType css,sass,scss setl shiftwidth=2 tabstop=2 softtabstop=2
\ omnifunc=csscomplete#CompleteCSS
" Gophermap needs real <tab> to convert maps
au BufRead,BufNewFile gophermap setl noexpandtab shiftwidth=4 tabstop=4
\ softtabstop=0 textwidth=70 colorcolumn=70
" HTML
au Filetype htm,html setl
\ foldmethod=indent indentkeys= shiftwidth=2 tabstop=2 softtabstop=2
" Markdown
au FileType markdown,md,mkd setl spell shiftwidth=2 tabstop=2 softtabstop=2
" Vim-inspired app configs
au BufRead,BufNewFile vifmrc set filetype=vim
au BufRead,BufNewFile vimperatorrc set filetype=vim
au FileType vim,vimrc,vimrc* set shiftwidth=2 tabstop=2 softtabstop=2
augroup END
" Plugins --------------------------------------------------------------------
" vim-emoji-complete — insert emoji
let g:emoji_complete_overwrite_standard_keymaps = 0
imap <leader>em <Plug>(emoji-start-complete)
" ALE — syntax check/linting
" Run lint manually
let g:ale_lint_on_enter = 0
let g:ale_lint_on_save = 0
let g:ale_lint_on_text_changed = 'never'
nmap <leader>ld :call ale#cursor#ShowCursorDetail()<cr>
nmap <leader>li :ALELint<cr>
nmap <leader>lj <Plug>(ale_next_wrap)
nmap <leader>lk <Plug>(ale_previous_wrap)
" Auto Pairs — auto-close brackets
let g:AutoPairs = {
\ '<':'>', '{':'}', '[':']', '(':')',
\ '"':'"', "'":"'", '`':'`',
\ '<!--':'-->',
\ '{%':'%}', '{#':'#}',
\ }
" Remap/disable unneeded mappings
let g:AutoPairsMapCR = 0
let g:AutoPairsMultilineClose = 0
let g:AutoPairsShortcutFastWrap = '<nop>'
let g:AutoPairsShortcutJump = '<leader>aj'
let g:AutoPairsShortcutToggle = '<leader>ap'
" commentary.vim — code commenting
imap <leader>/ :Commentary<cr>
vmap <leader>/ :Commentary<cr>
" snippet.vim — code/template expansion
" Key mappings in snipmate.vim/after/plugin/snipMate.vim
let g:snippets_dir = '~/.vim/snippets'
imap <leader>. <c-r>=TriggerSnippet()<cr>