-
-
Notifications
You must be signed in to change notification settings - Fork 90
/
vimrc
541 lines (478 loc) · 19.4 KB
/
vimrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
" _
" __ _(_)_ __ ___ _ __ ___
" \ \ / / | '_ ` _ \| '__/ __|
" \ V /| | | | | | | | | (__
" \_/ |_|_| |_| |_|_| \___|
"
" Ian's .vimrc file
"
" ----------------------------------------------------------------------------
" KEY MAPS
" ----------------------------------------------------------------------------
let mapleader = ','
" Useful macros I use the most
nmap \A :set formatoptions+=a<CR>:echo "autowrap enabled"<CR>
nmap \F :NERDTreeFind<CR>
nmap \M :set noexpandtab tabstop=8 softtabstop=4 shiftwidth=4<CR>
nmap \T :set expandtab tabstop=8 shiftwidth=8 softtabstop=4<CR>
nmap \W mt:Goyo<CR>'tzz
nmap \a :set formatoptions-=a<CR>:echo "autowrap disabled"<CR>
nmap \b :set nocin tw=80<CR>:set formatoptions+=a<CR>
nmap \c :call TmuxPaneClear()<CR>
nmap \e :NERDTreeToggle<CR>
nmap \g :GitGutterToggle<CR>
nmap \i vip:sort<CR>
nmap \l :setlocal number!<CR>:setlocal number?<CR>
nmap \m :set expandtab tabstop=2 shiftwidth=2 softtabstop=2<CR>
nmap \o :set paste!<CR>:set paste?<CR>
nmap \p :ProseMode<CR>
nmap \q :nohlsearch<CR>
nmap \r :call TmuxPaneRepeat()<CR>
nmap \s :setlocal invspell<CR>
nmap \t :set expandtab tabstop=4 shiftwidth=4 softtabstop=4<CR>
nmap \u :setlocal list!<CR>:setlocal list?<CR>
nmap \w :setlocal wrap!<CR>:setlocal wrap?<CR>
nmap \x :cclose<CR>
nmap \z :w<CR>:!open %<CR><CR>
" Turn off linewise keys. Normally, the `j' and `k' keys move the cursor down one entire line. with
" line wrapping on, this can cause the cursor to actually skip a few lines on the screen because
" it's moving from line N to line N+1 in the file. I want this to act more visually -- I want `down'
" to mean the next line on the screen
nmap j gj
nmap k gk
" Marks should go to the column, not just the line. Why isn't this the default?
nnoremap ' `
" You don't know what you're missing if you don't use this.
nmap <C-e> :e#<CR>
" Move between open buffers.
nmap <C-n> :bnext<CR>
nmap <C-p> :bprev<CR>
" Emacs-like bindings in normal mode
nmap <C-x>0 <C-w>c
nmap <C-x>1 <C-w>o
nmap <C-x>1 <C-w>s
nmap <C-x>1 <C-w>v
nmap <C-x>o <C-w><C-w>
nmap <M-o> <C-w><C-w>
" Emacs-like bindings in insert mode
imap <C-e> <C-o>$
imap <C-a> <C-o>0
" Emacs-like bindings in the command line from `:h emacs-keys`
cnoremap <C-a> <Home>
cnoremap <C-b> <Left>
cnoremap <C-f> <Right>
cnoremap <C-d> <Del>
cnoremap <C-e> <End>
cnoremap <M-b> <S-Left>
cnoremap <M-f> <S-Right>
cnoremap <M-d> <S-right><Delete>
cnoremap <Esc>b <S-Left>
cnoremap <Esc>f <S-Right>
cnoremap <Esc>d <S-right><Delete>
cnoremap <C-g> <C-c>
" Use the space key to toggle folds
nnoremap <space> za
vnoremap <space> zf
" Super fast window movement shortcuts
nmap <C-j> <C-W>j
nmap <C-k> <C-W>k
nmap <C-h> <C-W>h
nmap <C-l> <C-W>l
" Resize panes when window/terminal gets resize
autocmd VimResized * :wincmd =
" Search for the word under the cursor in the current directory
nmap <M-k> :Rg <C-R><C-W><CR>
nmap <Esc>k :Rg <C-R><C-W><CR>
nmap ˚ :Rg <C-R><C-W><CR>
" Alt-W to delete a buffer and remove it from the list but keep the window via bufkill.vim
nmap <Esc>w :BD<CR>
nmap <M-w> :BD<CR>
nmap ∑ :BD<CR>
" Quickly fix spelling errors choosing the first result
nmap <Leader>z z=1<CR><CR>
" Fix annoyances in the QuickFix window, like scrolling too much
autocmd FileType qf setlocal number nolist
autocmd Filetype qf wincmd J " Makes sure it's at the bottom of the vim window
" Commands to send common keystrokes using tmux
let g:tmux_console_pane = '0:0.0'
let g:tmux_server_pane = '0:0.0'
function TmuxPaneRepeat()
write
silent execute ':!tmux send-keys -t' g:tmux_console_pane 'C-p' 'C-j'
redraw!
endfunction
function TmuxPaneClear()
silent execute ':!tmux send-keys -t' g:tmux_server_pane 'C-j' 'C-j' 'C-j' 'C-j' 'C-j' 'C-j' 'C-j'
redraw!
endfunction
" These are things that I mistype and want ignored.
nmap Q <silent>
nmap q: <silent>
nmap K <silent>
" Make the cursor stay on the same line when window switching
function! KeepCurrentLine(motion)
let theLine = line('.')
let theCol = col('.')
exec 'wincmd ' . a:motion
if &diff
call cursor(theLine, theCol)
endif
endfunction
nnoremap <C-w>h :silent call KeepCurrentLine('h')<CR>
nnoremap <C-w>l :silent call KeepCurrentLine('l')<CR>
" ----------------------------------------------------------------------------
" ABBREVATIONS
" ----------------------------------------------------------------------------
" Typing `$c` on the command line expands to `:e` + the current path, so it's easy to edit a file in
" the same directory as the current file.
cnoremap $c e <C-\>eCurrentFileDir()<CR>
function! CurrentFileDir()
return "e " . expand("%:p:h") . "/"
endfunction
" I can't spell :(
abbr conosle console
abbr comopnent component
" Debugging helpers
autocmd BufEnter *.py iabbr xxx print('XXX
autocmd BufEnter *.py iabbr yyy print('YYY
autocmd BufEnter *.py iabbr zzz print('ZZZ
autocmd BufEnter *.coffee iabbr xxx console.log 'XXX',
autocmd BufEnter *.coffee iabbr yyy console.log 'YYY',
autocmd BufEnter *.coffee iabbr zzz console.log 'ZZZ',
autocmd BufEnter *.js iabbr xxx console.log('XXX',
autocmd BufEnter *.js iabbr yyy console.log('YYY',
autocmd BufEnter *.js iabbr zzz console.log('ZZZ',
autocmd BufEnter *.ts iabbr xxx console.log('XXX',
autocmd BufEnter *.ts iabbr yyy console.log('YYY',
autocmd BufEnter *.ts iabbr zzz console.log('ZZZ',
autocmd BufEnter *.rb iabbr xxx puts "XXX
autocmd BufEnter *.rb iabbr yyy puts "YYY
autocmd BufEnter *.rb iabbr zzz puts "ZZZ
autocmd BufEnter *.rb iabbr ppp require 'pp'; pp
" ----------------------------------------------------------------------------
" OPTIONS
" ----------------------------------------------------------------------------
set autoindent " Carry over indenting from previous line
set autoread " Don't bother me hen a file changes
set autowrite " Write on :next/:prev/^Z
set backspace=indent,eol,start
" Allow backspace beyond insertion point
set cindent " Automatic program indenting
set cinkeys-=0# " Comments don't fiddle with indenting
set cino= " See :h cinoptions-values
set commentstring=\ \ #%s " When folds are created, add them to this
set copyindent " Make autoindent use the same chars as prev line
set cryptmethod=blowfish2 " Use a stronger cipher than the default
set directory-=. " Don't store temp files in cwd
set encoding=utf8 " UTF-8 by default
set expandtab " No tabs
set fileformats=unix,dos,mac " Prefer Unix
set fillchars=vert:\ ,stl:\ ,stlnc:\ ,fold:-,diff:┄
" Unicode chars for diffs/folds, and rely on
" Colors for window borders
silent! set foldmethod=marker " Use braces by default
set formatoptions=tcqn1 " t - autowrap normal text
" c - autowrap comments
" q - gq formats comments
" n - autowrap lists
" 1 - break _before_ single-letter words
" 2 - use indenting from 2nd line of para
set hidden " Don't prompt to save hidden windows until exit
set history=200 " How many lines of history to save
set hlsearch " Hilight searching
set ignorecase " Case insensitive
set incsearch " Search as you type
set infercase " Completion recognizes capitalization
set laststatus=2 " Always show the status bar
set linebreak " Break long lines by word, not char
set list " Show whitespace as special chars - see listchars
set listchars=tab:»\ ,extends:›,precedes:‹,nbsp:·,trail:· " Unicode characters for various things
set matchtime=2 " Tenths of second to hilight matching paren
set nomodeline " teh hackerz!!!1
silent! set mouse=nvc " Use the mouse, but not in insert mode
set nobackup " No backups left after done editing
set nonumber " No line numbers to start
set visualbell t_vb= " No flashing or beeping at all
set nowritebackup " No backups made while editing
set printoptions=paper:letter " US paper
set ruler " Show row/col and percentage
set scroll=4 " Number of lines to scroll with ^U/^D
set scrolloff=15 " Keep cursor away from this many chars top/bot
set sessionoptions-=options " Don't save runtimepath in Vim session (see tpope/vim-pathogen docs)
set shiftround " Shift to certain columns, not just n spaces
set shiftwidth=2 " Number of spaces to shift for autoindent or >,<
set shortmess+=A " Don't bother me when a swapfile exists
set showbreak= " Show for lines that have been wrapped, like Emacs
set showmatch " Hilight matching braces/parens/etc.
set sidescrolloff=3 " Keep cursor away from this many chars left/right
set smartcase " Lets you search for ALL CAPS
set softtabstop=2 " Spaces 'feel' like tabs
set suffixes+=.pyc " Ignore these files when tab-completing
set tabstop=2 " The One True Tab
set textwidth=0 " No wrapping by default
set wildmenu " Show possible completions on command line
set wildmode=list:longest,full " List all options and complete
set wildignore=*.class,*.o,*~,*.pyc,.git,node_modules " Ignore certain files in tab-completion
" Essential for filetype plugins.
filetype plugin indent on
" ----------------------------------------------------------------------------
" CUSTOM COMMANDS AND FUNCTIONS
" ----------------------------------------------------------------------------
" I always hit ":W" instead of ":w" because I linger on the shift key...
command! Q q
command! W w
" Trim spaces at EOL and retab. I run `:CLEAN` a lot to clean up files.
command! TEOL %s/\s\+$//
command! CLEAN retab | TEOL
" Close all buffers except this one
command! BufCloseOthers %bd|e#
" ----------------------------------------------------------------------------
" PLUGIN SETTINGS
" ----------------------------------------------------------------------------
" Use Pathogen for plugin management. See update.sh in this directory.
runtime bundle/vim-pathogen/autoload/pathogen.vim
call pathogen#infect()
call pathogen#helptags()
" For any plugins that use this, make their keymappings use comma
let mapleader = ","
let maplocalleader = ","
" FZF (replaces Ctrl-P, FuzzyFinder and Command-T)
set rtp+=/usr/local/opt/fzf
set rtp+=/opt/homebrew/opt/fzf
set rtp+=~/.fzf
nmap ; :Files<CR>
nmap <Leader>r :Tags<CR>
nmap <Leader>b :Buffers<CR>
nmap <Leader>t :Files<CR>
nmap <Leader>a :Rg!<CR>
nmap <Leader>c :Colors<CR>
let $FZF_DEFAULT_COMMAND = 'rg --files --follow -g "!{.git,node_modules}/*" 2>/dev/null'
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --no-heading --color=always --smart-case -g "!{*.lock,*-lock.json}" '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview('up:40%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" FZF color scheme updater from https://github.com/junegunn/fzf.vim/issues/59
function! s:update_fzf_colors()
let rules =
\ { 'fg': [['Normal', 'fg']],
\ 'bg': [['Normal', 'bg']],
\ 'hl': [['String', 'fg']],
\ 'fg+': [['CursorColumn', 'fg'], ['Normal', 'fg']],
\ 'bg+': [['CursorColumn', 'bg']],
\ 'hl+': [['String', 'fg']],
\ 'info': [['PreProc', 'fg']],
\ 'prompt': [['Conditional', 'fg']],
\ 'pointer': [['Exception', 'fg']],
\ 'marker': [['Keyword', 'fg']],
\ 'spinner': [['Label', 'fg']],
\ 'header': [['Comment', 'fg']] }
let cols = []
for [name, pairs] in items(rules)
for pair in pairs
let code = synIDattr(synIDtrans(hlID(pair[0])), pair[1])
if !empty(name) && code != ''
call add(cols, name.':'.code)
break
endif
endfor
endfor
let s:orig_fzf_default_opts = get(s:, 'orig_fzf_default_opts', $FZF_DEFAULT_OPTS)
let $FZF_DEFAULT_OPTS = s:orig_fzf_default_opts .
\ (empty(cols) ? '' : (' --color='.join(cols, ',')))
endfunction
augroup _fzf
autocmd!
autocmd VimEnter,ColorScheme * call <sid>update_fzf_colors()
augroup END
" Ctrl-C has a long delay in SQL files - https://unix.stackexchange.com/a/150769
let g:ftplugin_sql_omni_key = '<Leader>s'
" More space with NERDTree
let g:NERDTreeMinimalUI = 1
let g:NERDTreeMarkBookmarks = 0
let g:NERDTreeAutoDeleteBuffer = 1
let g:NERDTreeStatusLine = -1
" Tell ack.vim to use ripgrep instead
let g:ackprg = 'rg --vimgrep --no-heading'
" GitGutter styling to use · instead of +/-
let g:gitgutter_sign_added = '▌'
let g:gitgutter_sign_modified = '▌'
let g:gitgutter_sign_removed = '▌'
let g:gitgutter_sign_modified_removed = '∙'
nmap ]g :GitGutterNextHunk<CR>
nmap [g :GitGutterPrevHunk<CR>
augroup VimDiff
autocmd!
autocmd VimEnter,FilterWritePre * if &diff | GitGutterDisable | endif
augroup END
" SuperTab
let g:SuperTabLongestEnhanced = 1
let g:SuperTabLongestHighlight = 1
au Filetype typescript let b:SuperTabDefaultCompletionType = "<C-x><C-o>"
" csv.vim
let g:csv_delim_test = ',|'
let g:csv_no_conceal = 1
highlight link CSVDelimiter Delimiter
highlight link CSVColumnHeaderEven Type
highlight link CSVColumnHeaderOdd Type
" Use incsearch.vim to highlight as I search
map / <Plug>(incsearch-forward)
map ? <Plug>(incsearch-backward)
map g/ <Plug>(incsearch-stay)
" Highlight YAML frontmatter in Markdown files
let g:vim_markdown_frontmatter = 1
" Lightline
let g:lightline = {
\ 'colorscheme': 'wombat',
\ 'active': {
\ 'left': [['mode', 'paste'], ['filename', 'modified']],
\ 'right': [['lineinfo'], ['percent'], ['readonly', 'linter_warnings', 'linter_errors', 'linter_ok']]
\ },
\ 'component_expand': {
\ 'linter_warnings': 'LightlineLinterWarnings',
\ 'linter_errors': 'LightlineLinterErrors',
\ 'linter_ok': 'LightlineLinterOK'
\ },
\ 'component_type': {
\ 'readonly': 'error',
\ 'linter_warnings': 'warning',
\ 'linter_errors': 'error'
\ },
\ }
function! LightlineLinterWarnings() 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 ◆', all_non_errors)
endfunction
function! LightlineLinterErrors() 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 ✗', all_errors)
endfunction
function! LightlineLinterOK() 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 ? '✓ ' : ''
endfunction
" Update and show lightline but only if it's visible (e.g., not in Goyo)
function! s:MaybeUpdateLightline()
if exists('#lightline')
call lightline#update()
end
endfunction
" Update the lightline scheme from the colorscheme. Hopefully.
function! s:UpdateLightlineColorScheme()
let g:lightline.colorscheme = g:colors_name
call lightline#init()
endfunction
augroup _lightline
autocmd!
autocmd ColorScheme * call s:UpdateLightlineColorScheme()
augroup END
" ----------------------------------------------------------------------------
" COLORS
" ----------------------------------------------------------------------------
" Make sure colored syntax mode is on, and make it Just Work with 256-color terminals.
set background=dark
let g:rehash256 = 1 " Something to do with Molokai?
colorscheme molokai
let g:seoul256_background = 233
if !has('gui_running')
let g:solarized_termcolors = 256
if $TERM == "xterm-256color" || $TERM == "screen-256color" || $COLORTERM == "gnome-terminal"
set t_Co=256
elseif has("terminfo")
colorscheme default
set t_Co=8
set t_Sf=[3%p1%dm
set t_Sb=[4%p1%dm
else
colorscheme default
set t_Co=8
set t_Sf=[3%dm
set t_Sb=[4%dm
endif
" Disable Background Color Erase when within tmux - https://stackoverflow.com/q/6427650/102704
if $TMUX != ""
set t_ut=
endif
endif
syntax on
" Make the damned tildes less visible
highlight link EndOfBuffer Comment
" Custom colors for NERDTree
highlight def link NERDTreeRO NERDTreeFile
" Make menu selections visible
highlight PmenuSel ctermfg=black ctermbg=magenta
" Custom mode for distraction-free editing
function! ProseMode()
call goyo#execute(0, [])
set spell noci nosi noai nolist noshowmode noshowcmd
set complete+=s
colors molokai
endfunction
command! ProseMode call ProseMode()
autocmd! User GoyoEnter Limelight
autocmd! User GoyoLeave Limelight!
" ----------------------------------------------------------------------------
" FILE TYPE TRIGGERS
" ----------------------------------------------------------------------------
" Reset all autocommands
augroup vimrc
autocmd!
au BufNewFile,BufRead *.cson set ft=coffee
au BufNewFile,BufRead *.glsl setf glsl
au BufNewFile,BufRead *.gyp set ft=python
au BufNewFile,BufRead *.html setlocal nocindent smartindent
au BufNewFile,BufRead *.i7x setf inform7
au BufNewFile,BufRead *.ini setf conf
au BufNewFile,BufRead *.input setf gnuplot
au BufNewFile,BufRead *.journal setlocal tw=0 ts=4 sw=4 et
au BufNewFile,BufRead *.json set ft=json tw=0
au BufNewFile,BufRead *.less setlocal ft=less nocindent smartindent
au BufNewFile,BufRead *.lkml setf yaml
au BufNewFile,BufRead *.md setlocal ft=markdown nolist spell
au BufNewFile,BufRead *.md,*.markdown setlocal foldlevel=999 tw=0 nocin
au BufNewFile,BufRead *.ni,*.i7x setlocal ft=inform7 fdm=manual nolist ts=2 sw=2 noet spell
au BufNewFile,BufRead *.plist setf xml
au BufNewFile,BufRead *.rb setlocal noai
au BufNewFile,BufRead *.rxml setf ruby
au BufNewFile,BufRead *.sass setf sass
au BufNewFile,BufRead *.ttml setf xml
au BufNewFile,BufRead *.vert,*.frag set ft=glsl
au BufNewFile,BufRead *.xml setlocal ft=xml ts=2 sw=2 et
au BufNewFile,BufRead *.zone setlocal nolist ts=4 sw=4 noet
au BufNewFile,BufRead *.zsh setf zsh
au BufNewFile,BufRead *.ovpn setf openvpn
au BufNewFile,BufRead *templates/*.html setf htmldjango
au BufNewFile,BufRead .conkyrc set ft=lua
au BufNewFile,BufRead .git/config setlocal ft=gitconfig nolist ts=4 sw=4 noet
au BufNewFile,BufRead .gitconfig* setlocal ft=gitconfig nolist ts=4 sw=4 noet
au BufNewFile,BufRead postgres*.conf setlocal nolist ts=8 sw=8 noet
au BufNewFile,BufRead .vimlocal,.gvimlocal setf vim
au BufNewFile,BufRead .zshlocal setf zsh
au BufNewFile,BufRead /tmp/crontab* setf crontab
au BufNewFile,BufRead COMMIT_EDITMSG setlocal nolist nonumber
au BufNewFile,BufRead Makefile setlocal nolist
au BufNewFile,BufRead dist/* set ft=text
au FileType gitcommit setlocal nolist ts=4 sts=4 sw=4 noet
au FileType inform7 setlocal nolist tw=0 ts=4 sw=4 noet foldlevel=999
au FileType json setlocal conceallevel=0 foldmethod=syntax foldlevel=999
au FileType make setlocal nolist ts=4 sts=4 sw=4 noet
au FileType markdown syn sync fromstart
au Filetype gitcommit setlocal tw=80
au Filetype csv setlocal nocursorline
augroup END
" ----------------------------------------------------------------------------
" HOST-SPECIFIC VIM FILE
" ----------------------------------------------------------------------------
" Now load specifics to this host
if filereadable(expand("~/.vimlocal"))
source ~/.vimlocal
endif
" Some plugin seems to search for something at startup, so this fixes that.
silent! nohlsearch