Jay Taylor's notes

back to listing index

garybernhardt/dotfiles

[web search]
Original source (github.com)
Tags: vim vimrc scrollback-buffer github.com
Clipped on: 2016-03-02

Skip to content
b3ff433 on May 22, 2015
7 contributors Image (Asset 3/8) alt= garybernhardt Image (Asset 4/8) alt= Who828 Image (Asset 5/8) alt= jamesnvc Image (Asset 6/8) alt= tcrayford Image (Asset 7/8) alt= cutalion Image (Asset 8/8) alt= theotherzach bekacho
Open this file in GitHub Desktop
525 lines (477 sloc) 17.8 KB
1 " This is Gary Bernhardt's .vimrc file
2 " vim:set ts=2 sts=2 sw=2 expandtab:
3
4 autocmd!
5
6 call pathogen#incubate()
7
8 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
9 " BASIC EDITING CONFIGURATION
10 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
11 set nocompatible
12 " allow unsaved background buffers and remember marks/undo for them
13 set hidden
14 " remember more commands and search history
15 set history=10000
16 set expandtab
17 set tabstop=4
18 set shiftwidth=4
19 set softtabstop=4
20 set autoindent
21 set laststatus=2
22 set showmatch
23 set incsearch
24 set hlsearch
25 " make searches case-sensitive only if they contain upper-case characters
26 set ignorecase smartcase
27 " highlight current line
28 set cursorline
29 set cmdheight=1
30 set switchbuf=useopen
31 set showtabline=2
32 set winwidth=79
33 " This makes RVM work inside Vim. I have no idea why.
34 set shell=bash
35 " Prevent Vim from clobbering the scrollback buffer. See
36 " http://www.shallowsky.com/linux/noaltscreen.html
37 set t_ti= t_te=
38 " keep more context when scrolling off the end of a buffer
39 set scrolloff=3
40 " Don't make backups at all
41 set nobackup
42 set nowritebackup
43 set backupdir=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp
44 set directory=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp
45 " allow backspacing over everything in insert mode
46 set backspace=indent,eol,start
47 " display incomplete commands
48 set showcmd
49 " Enable highlighting for syntax
50 syntax on
51 " Enable file type detection.
52 " Use the default filetype settings, so that mail gets 'tw' set to 72,
53 " 'cindent' is on in C files, etc.
54 " Also load indent files, to automatically do language-dependent indenting.
55 filetype plugin indent on
56 " use emacs-style tab completion when selecting files, etc
57 set wildmode=longest,list
58 " make tab completion for files/buffers act like bash
59 set wildmenu
60 let mapleader=","
61 " Fix slow O inserts
62 :set timeout timeoutlen=1000 ttimeoutlen=100
63 " Normally, Vim messes with iskeyword when you open a shell file. This can
64 " leak out, polluting other file types even after a 'set ft=' change. This
65 " variable prevents the iskeyword change so it can't hurt anyone.
66 let g:sh_noisk=1
67 " Modelines (comments that set vim options on a per-file basis)
68 set modeline
69 set modelines=3
70 " Turn folding off for real, hopefully
71 set foldmethod=manual
72 set nofoldenable
73 " Insert only one space when joining lines that contain sentence-terminating
74 " punctuation like `.`.
75 set nojoinspaces
76 " If a file is changed outside of vim, automatically reload it without asking
77 set autoread
78
79 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
80 " CUSTOM AUTOCMDS
81 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
82 augroup vimrcEx
83 " Clear all autocmds in the group
84 autocmd!
85 autocmd FileType text setlocal textwidth=78
86 " Jump to last cursor position unless it's invalid or in an event handler
87 autocmd BufReadPost *
88 \ if line("'\"") > 0 && line("'\"") <= line("$") |
89 \ exe "normal g`\"" |
90 \ endif
91
92 "for ruby, autoindent with two spaces, always expand tabs
93 autocmd FileType ruby,haml,eruby,yaml,html,javascript,sass,cucumber set ai sw=2 sts=2 et
94 autocmd FileType python set sw=4 sts=4 et
95
96 autocmd! BufRead,BufNewFile *.sass setfiletype sass
97
98 autocmd BufRead *.mkd set ai formatoptions=tcroqn2 comments=n:&gt;
99 autocmd BufRead *.markdown set ai formatoptions=tcroqn2 comments=n:&gt;
100
101 " Indent p tags
102 " autocmd FileType html,eruby if g:html_indent_tags !~ '\\|p\>' | let g:html_indent_tags .= '\|p\|li\|dt\|dd' | endif
103
104 " Don't syntax highlight markdown because it's often wrong
105 autocmd! FileType mkd setlocal syn=off
106
107 " Leave the return key alone when in command line windows, since it's used
108 " to run commands there.
109 autocmd! CmdwinEnter * :unmap <cr>
110 autocmd! CmdwinLeave * :call MapCR()
111
112 " *.md is markdown
113 autocmd! BufNewFile,BufRead *.md setlocal ft=
114
115 " indent slim two spaces, not four
116 autocmd! FileType *.slim set sw=2 sts=2 et
117 augroup END
118
119 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
120 " COLOR
121 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
122 :set t_Co=256 " 256 colors
123 :set background=dark
124 :color grb256
125
126 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
127 " STATUS LINE
128 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
129 :set statusline=%<%f\ (%{&ft})\ %-4(%m%)%=%-19(%3l,%02c%03V%)
130
131 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
132 " MISC KEY MAPS
133 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
134 map <leader>y "*y
135 " Move around splits with <c-hjkl>
136 nnoremap <c-j> <c-w>j
137 nnoremap <c-k> <c-w>k
138 nnoremap <c-h> <c-w>h
139 nnoremap <c-l> <c-w>l
140 " Insert a hash rocket with <c-l>
141 imap <c-l> <space>=><space>
142 " Can't be bothered to understand ESC vs <c-c> in insert mode
143 imap <c-c> <esc>
144 nnoremap <leader><leader> <c-^>
145 " Close all other windows, open a vertical split, and open this file's test
146 " alternate in it.
147 nnoremap <leader>s :call FocusOnFile()<cr>
148 function! FocusOnFile()
149 tabnew %
150 normal! v
151 normal! l
152 call OpenTestAlternate()
153 normal! h
154 endfunction
155 " Reload in chrome
156 map <leader>l :w\|:silent !reload-chrome<cr>
157 " Align selected lines
158 vnoremap <leader>ib :!align<cr>
159
160 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
161 " MULTIPURPOSE TAB KEY
162 " Indent if we're at the beginning of a line. Else, do completion.
163 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
164 function! InsertTabWrapper()
165 let col = col('.') - 1
166 if !col || getline('.')[col - 1] !~ '\k'
167 return "\<tab>"
168 else
169 return "\<c-p>"
170 endif
171 endfunction
172 inoremap <expr> <tab> InsertTabWrapper()
173 inoremap <s-tab> <c-n>
174
175 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
176 " OPEN FILES IN DIRECTORY OF CURRENT FILE
177 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
178 cnoremap <expr> %% expand('%:h').'/'
179 map <leader>e :edit %%
180 map <leader>v :view %%
181
182 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
183 " RENAME CURRENT FILE
184 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
185 function! RenameFile()
186 let old_name = expand('%')
187 let new_name = input('New file name: ', expand('%'), 'file')
188 if new_name != '' && new_name != old_name
189 exec ':saveas ' . new_name
190 exec ':silent !rm ' . old_name
191 redraw!
192 endif
193 endfunction
194 map <leader>n :call RenameFile()<cr>
195
196 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
197 " PROMOTE VARIABLE TO RSPEC LET
198 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
199 function! PromoteToLet()
200 :normal! dd
201 " :exec '?^\s*it\>'
202 :normal! P
203 :.s/\(\w\+\) = \(.*\)$/let(:\1) { \2 }/
204 :normal ==
205 endfunction
206 :command! PromoteToLet :call PromoteToLet()
207 :map <leader>p :PromoteToLet<cr>
208
209 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
210 " EXTRACT VARIABLE (SKETCHY)
211 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
212 function! ExtractVariable()
213 let name = input("Variable name: ")
214 if name == ''
215 return
216 endif
217 " Enter visual mode (not sure why this is needed since we're already in
218 " visual mode anyway)
219 normal! gv
220
221 " Replace selected text with the variable name
222 exec "normal c" . name
223 " Define the variable on the line above
224 exec "normal! O" . name . " = "
225 " Paste the original selected text to be the variable value
226 normal! $p
227 endfunction
228 vnoremap <leader>rv :call ExtractVariable()<cr>
229
230 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
231 " INLINE VARIABLE (SKETCHY)
232 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
233 function! InlineVariable()
234 " Copy the variable under the cursor into the 'a' register
235 :let l:tmp_a = @a
236 :normal "ayiw
237 " Delete variable and equals sign
238 :normal 2daW
239 " Delete the expression into the 'b' register
240 :let l:tmp_b = @b
241 :normal "bd$
242 " Delete the remnants of the line
243 :normal dd
244 " Go to the end of the previous line so we can start our search for the
245 " usage of the variable to replace. Doing '0' instead of 'k$' doesn't
246 " work; I'm not sure why.
247 normal k$
248 " Find the next occurence of the variable
249 exec '/\<' . @a . '\>'
250 " Replace that occurence with the text we yanked
251 exec ':.s/\<' . @a . '\>/' . escape(@b, "/")
252 :let @a = l:tmp_a
253 :let @b = l:tmp_b
254 endfunction
255 nnoremap <leader>ri :call InlineVariable()<cr>
256
257 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
258 " MAPS TO JUMP TO SPECIFIC COMMAND-T TARGETS AND FILES
259 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
260 map <leader>gr :topleft :split config/routes.rb<cr>
261 function! ShowRoutes()
262 " Requires 'scratch' plugin
263 :topleft 100 :split __Routes__
264 " Make sure Vim doesn't write __Routes__ as a file
265 :set buftype=nofile
266 " Delete everything
267 :normal 1GdG
268 " Put routes output in buffer
269 :0r! rake -s routes
270 " Size window to number of lines (1 plus rake output length)
271 :exec ":normal " . line("$") . "_ "
272 " Move cursor to bottom
273 :normal 1GG
274 " Delete empty trailing line
275 :normal dd
276 endfunction
277 map <leader>gR :call ShowRoutes()<cr>
278
279 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
280 " SWITCH BETWEEN TEST AND PRODUCTION CODE
281 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
282 function! OpenTestAlternate()
283 let new_file = AlternateForCurrentFile()
284 exec ':e ' . new_file
285 endfunction
286 function! AlternateForCurrentFile()
287 let current_file = expand("%")
288 let new_file = current_file
289 let in_spec = match(current_file, '^spec/') != -1
290 let going_to_spec = !in_spec
291 let in_app = match(current_file, '\<controllers\>') != -1 || match(current_file, '\<models\>') != -1 || match(current_file, '\<views\>') != -1 || match(current_file, '\<helpers\>') != -1
292 if going_to_spec
293 if in_app
294 let new_file = substitute(new_file, '^app/', '', '')
295 end
296 let new_file = substitute(new_file, '\.e\?rb$', '_spec.rb', '')
297 let new_file = 'spec/' . new_file
298 else
299 let new_file = substitute(new_file, '_spec\.rb$', '.rb', '')
300 let new_file = substitute(new_file, '^spec/', '', '')
301 if in_app
302 let new_file = 'app/' . new_file
303 end
304 endif
305 return new_file
306 endfunction
307 nnoremap <leader>. :call OpenTestAlternate()<cr>
308
309 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
310 " RUNNING TESTS
311 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
312 function! MapCR()
313 nnoremap <cr> :call RunTestFile()<cr>
314 endfunction
315 call MapCR()
316 nnoremap <leader>T :call RunNearestTest()<cr>
317 nnoremap <leader>a :call RunTests('')<cr>
318 nnoremap <leader>c :w\|:!script/features<cr>
319 nnoremap <leader>w :w\|:!script/features --profile wip<cr>
320
321 function! RunTestFile(...)
322 if a:0
323 let command_suffix = a:1
324 else
325 let command_suffix = ""
326 endif
327
328 " Run the tests for the previously-marked file.
329 let in_test_file = match(expand("%"), '\(.feature\|_spec.rb\|_test.py\)$') != -1
330 if in_test_file
331 call SetTestFile(command_suffix)
332 elseif !exists("t:grb_test_file")
333 return
334 end
335 call RunTests(t:grb_test_file)
336 endfunction
337
338 function! RunNearestTest()
339 let spec_line_number = line('.')
340 call RunTestFile(":" . spec_line_number)
341 endfunction
342
343 function! SetTestFile(command_suffix)
344 " Set the spec file that tests will be run for.
345 let t:grb_test_file=@% . a:command_suffix
346 endfunction
347
348 function! RunTests(filename)
349 " Write the file and run tests for the given filename
350 if expand("%") != ""
351 :w
352 end
353 if match(a:filename, '\.feature$') != -1
354 exec ":!script/features " . a:filename
355 else
356 " First choice: project-specific test script
357 if filereadable("script/test")
358 exec ":!script/test " . a:filename
359 " Fall back to the .test-commands pipe if available, assuming someone
360 " is reading the other side and running the commands
361 elseif filewritable(".test-commands")
362 let cmd = 'rspec --color --format progress --require "~/lib/vim_rspec_formatter" --format VimFormatter --out tmp/quickfix'
363 exec ":!echo " . cmd . " " . a:filename . " > .test-commands"
364
365 " Write an empty string to block until the command completes
366 sleep 100m " milliseconds
367 :!echo > .test-commands
368 redraw!
369 " Fall back to a blocking test run with Bundler
370 elseif filereadable("Gemfile")
371 exec ":!bundle exec rspec --color " . a:filename
372 " If we see python-looking tests, assume they should be run with Nose
373 elseif strlen(glob("test/**/*.py") . glob("tests/**/*.py"))
374 exec "!nosetests " . a:filename
375 " Fall back to a normal blocking test run
376 else
377 exec ":!rspec --color " . a:filename
378 end
379 end
380 endfunction
381
382
383 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
384 " Md5 COMMAND
385 " Show the MD5 of the current buffer
386 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
387 command! -range Md5 :echo system('echo '.shellescape(join(getline(<line1>, <line2>), '\n')) . '| md5')
388
389 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
390 " OpenChangedFiles COMMAND
391 " Open a split for each dirty file in git
392 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
393 function! OpenChangedFiles()
394 only " Close all windows, unless they're modified
395 let status = system('git status -s | grep "^ \?\(M\|A\|UU\)" | sed "s/^.\{3\}//"')
396 let filenames = split(status, "\n")
397 exec "edit " . filenames[0]
398 for filename in filenames[1:]
399 exec "sp " . filename
400 endfor
401 endfunction
402 command! OpenChangedFiles :call OpenChangedFiles()
403
404 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
405 " InsertTime COMMAND
406 " Insert the current time
407 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
408 command! InsertTime :normal a<c-r>=strftime('%F %H:%M:%S.0 %z')<cr>
409
410 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
411 " FindConditionals COMMAND
412 " Start a search for conditional branches, both implicit and explicit
413 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
414 command! FindConditionals :normal /\<if\>\|\<unless\>\|\<and\>\|\<or\>\|||\|&&<cr>
415
416 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
417 " Diff tab management: open the current git diff in a tab
418 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
419 command! GdiffInTab tabedit %|vsplit|Gdiff
420 nnoremap <leader>d :GdiffInTab<cr>
421 nnoremap <leader>D :tabclose<cr>
422
423 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
424 " Test quickfix list management
425 "
426 " If the tests write a tmp/quickfix file, these mappings will navigate through
427 " it
428 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
429 function! GetBufferList()
430 redir =>buflist
431 silent! ls
432 redir END
433 return buflist
434 endfunction
435
436 function! BufferIsOpen(bufname)
437 let buflist = GetBufferList()
438 for bufnum in map(filter(split(buflist, '\n'), 'v:val =~ "'.a:bufname.'"'), 'str2nr(matchstr(v:val, "\\d\\+"))')
439 if bufwinnr(bufnum) != -1
440 return 1
441 endif
442 endfor
443 return 0
444 endfunction
445
446 function! ToggleQuickfix()
447 if BufferIsOpen("Quickfix List")
448 cclose
449 else
450 call OpenQuickfix()
451 endif
452 endfunction
453
454 function! OpenQuickfix()
455 cgetfile tmp/quickfix
456 topleft cwindow
457 if &ft == "qf"
458 cc
459 endif
460 endfunction
461
462 nnoremap <leader>q :call ToggleQuickfix()<cr>
463 nnoremap <leader>Q :cc<cr>
464 nnoremap <leader>j :cnext<cr>
465 nnoremap <leader>k :cprev<cr>
466
467 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
468 " RemoveFancyCharacters COMMAND
469 " Remove smart quotes, etc.
470 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
471 function! RemoveFancyCharacters()
472 let typo = {}
473 let typo["“"] = '"'
474 let typo["”"] = '"'
475 let typo["‘"] = "'"
476 let typo["’"] = "'"
477 let typo["–"] = '--'
478 let typo["—"] = '---'
479 let typo["…"] = '...'
480 :exe ":%s/".join(keys(typo), '\|').'/\=typo[submatch(0)]/ge'
481 endfunction
482 command! RemoveFancyCharacters :call RemoveFancyCharacters()
483
484 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
485 " Selecta Mappings
486 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
487 " Run a given vim command on the results of fuzzy selecting from a given shell
488 " command. See usage below.
489 function! SelectaCommand(choice_command, selecta_args, vim_command)
490 try
491 let selection = system(a:choice_command . " | selecta " . a:selecta_args)
492 catch /Vim:Interrupt/
493 " Swallow the ^C so that the redraw below happens; otherwise there will be
494 " leftovers from selecta on the screen
495 redraw!
496 return
497 endtry
498 redraw!
499 exec a:vim_command . " " . selection
500 endfunction
501
502 function! SelectaFile(path)
503 call SelectaCommand("find " . a:path . "/* -type f", "", ":e")
504 endfunction
505
506 nnoremap <leader>f :call SelectaFile(".")<cr>
507 nnoremap <leader>gv :call SelectaFile("app/views")<cr>
508 nnoremap <leader>gc :call SelectaFile("app/controllers")<cr>
509 nnoremap <leader>gm :call SelectaFile("app/models")<cr>
510 nnoremap <leader>gh :call SelectaFile("app/helpers")<cr>
511 nnoremap <leader>gl :call SelectaFile("lib")<cr>
512 nnoremap <leader>gp :call SelectaFile("public")<cr>
513 nnoremap <leader>gs :call SelectaFile("public/stylesheets")<cr>
514 nnoremap <leader>gf :call SelectaFile("features")<cr>
515
516 "Fuzzy select
517 function! SelectaIdentifier()
518 " Yank the word under the cursor into the z register
519 normal "zyiw
520 " Fuzzy match files in the current directory, starting with the word under
521 " the cursor
522 call SelectaCommand("find * -type f", "-s " . @z, ":e")
523 endfunction
524 nnoremap <c-g> :call SelectaIdentifier()<cr>