forked from ryanb/dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path.vimrc
executable file
·401 lines (333 loc) · 12 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
let mapleader=","
set t_Co=256
" make it possible to get to system clipboard with *
set clipboard=unnamed
set mouse=a
set spell spelllang=en_us
" set number
set ruler
syntax on
" would python be good enough? maybe I don't need that plugin...
autocmd BufNewFile,BufRead *.tilt set syntax=starlark
set undofile
set undodir=~/.vim/undodir
" Set encoding
set encoding=utf-8
" Whitespace stuff
set winwidth=80
set tabstop=2
set shiftwidth=2
set softtabstop=2
set expandtab
set list listchars=tab:\ \ ,trail:·
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" MISC KEY MAPS
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" remove trailing whitespace
nnoremap <leader><Space> :%s/\s\+$//e<CR>
nnoremap <leader>w :w<CR>
" Can't be bothered to understand ESC vs <c-c> in insert mode
" this is helpful since the escape key is not a physical key on my
" current laptop
imap <c-c> <esc>
augroup vimrcEx
" Clear all autocmds in the group
autocmd!
autocmd FileType haml setlocal nowrap
"for ruby, autoindent with two spaces, always expand tabs
autocmd FileType ruby,haml,eruby,yaml,html,sass,cucumber set ai sw=2 sts=2 et
" Jump to last cursor position unless it's invalid or in an event handler
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal g`\"" |
\ endif
augroup END
set nowrap
" Searching
set hlsearch
set incsearch
set ignorecase
set smartcase
" show count when using *
map * *<C-O>:%s///gn<CR>
" automatically reload files that have changed outside of vim
" e.g. when switching branches or stashing changes
set autoread
" Use the old vim regex engine (version 1, as opposed to version 2, which was
" introduced in Vim 7.3.969). The Ruby syntax highlighting is significantly
" slower with the new regex engine.
set re=1
" Tab completion
set wildmode=list:longest,list:full
set wildignore+=*.o,*.obj,.git,*.rbc,*.class,.svn,vendor/gems/*,tmp
" Status bar - always show
set laststatus=2
filetype off "required by Vundle
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" let Vundle manage Vundle
Plugin 'altercation/vim-colors-solarized'
Plugin 'VundleVim/Vundle.vim'
Plugin 'scrooloose/nerdcommenter'
Plugin 'tpope/vim-dispatch'
Plugin 'tpope/vim-fugitive'
Plugin 'tpope/vim-unimpaired'
Plugin 'mileszs/ack.vim'
Plugin 'vim-scripts/scratch.vim'
Plugin 'tpope/vim-rhubarb'
Plugin 'tpope/vim-endwise'
Plugin 'cappyzawa/starlark.vim'
Plugin 'solarnz/thrift.vim'
Plugin 'hashivim/vim-terraform'
Plugin 'psf/black'
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
map <Leader>g :.GBrowse<CR>
nnoremap <Leader>n :noh<CR>
nnoremap <Leader>b :Black<CR>
" Run a given vim command on the results of fuzzy selecting from a given shell
" command. See usage below.
function! SelectaCommand(choice_command, selecta_args, vim_command)
try
let selection = system(a:choice_command . " | selecta " . a:selecta_args)
catch /Vim:Interrupt/
" Swallow the ^C so that the redraw below happens; otherwise there will be
" leftovers from selecta on the screen
redraw!
return
endtry
redraw!
exec a:vim_command . " " . selection
endfunction
" Find all files in all non-dot directories starting in the working directory.
" Fuzzy select one of those. Open the selected file with :e.
let find_command = "git ls-files"
nnoremap <leader>t :call SelectaCommand(escape(find_command, "()"), "", ":e")<cr>
let g:github_enterprise_urls = ['https://github.snooguts.net']
" CTags
" consider remapping this to something else
" because it is causing my <leader>r mapping to be slow (rename a file)
" not sure what I would map this to
" map <Leader>rt :Dispatch bundle show --paths \| xargs ctags -f \.tags -R && ctags --extra=+f -R -a *<CR><CR>
map <Leader>ct :Dispatch ctags --extra=+f -R -a *<CR><CR>
map <c-b> :tprevious<CR>
map <c-n> :tnext<CR>
map tt <c-]>
" using custom tag filename
"set tags=tags
set tags^=./.git/tags;
" highlight the 80th column
"set colorcolumn=80
" Thorfile, Rakefile, Vagrantfile and Gemfile are Ruby
au BufRead,BufNewFile {Gemfile,Rakefile,Vagrantfile,Thorfile,config.ru,*.watchr,Guardfile,*.thor,*.rabl} set ft=ruby
au BufRead,BufNewFile *.scss.erb set ft=scss
" add json syntax highlighting
au BufNewFile,BufRead *.json set ft=javascript
au BufNewFile,BufRead *.handlebars set ft=mustache
" allow backspacing over everything in insert mode
set backspace=indent,eol,start
" load the plugin and indent settings for the detected filetype
filetype plugin indent on
" Inserts the path of the currently edited file into a command
" Command mode: Ctrl+P
cmap <C-P> <C-R>=expand("%:p:h") . "/" <CR>
" Use modeline overrides
set modeline
set modelines=10
" Directories for swp files
set backupdir=~/.vim/backup
set directory=~/.vim/backup
" Turn off jslint errors by default
let g:JSLintHighlightErrorLine = 0
" % to bounce from do to end etc.
runtime! macros/matchit.vim
" Show (partial) command in the status line
set showcmd
" I don't like folds
set nofoldenable
set background=dark
color solarized
nnoremap <leader><leader> <c-^>
" Don't beep
set visualbell
" Maps to make handling windows a bit easier
noremap <silent> ,h :wincmd h<CR>
noremap <silent> ,j :wincmd j<CR>
noremap <silent> ,k :wincmd k<CR>
noremap <silent> ,l :wincmd l<CR>
" commands to enter blank lines and stay in normal mode
nnoremap - o<esc>k
nnoremap _ O<esc>j
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" MULTIPURPOSE TAB KEY
" Indent if we're at the beginning of a line. Else, do completion.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! InsertTabWrapper()
let col = col('.') - 1
if !col
return "\<tab>"
endif
let char = getline('.')[col - 1]
if char =~ '\k'
" There's an identifier before the cursor, so complete the identifier.
return "\<c-p>"
else
return "\<tab>"
endif
endfunction
inoremap <expr> <tab> InsertTabWrapper()
inoremap <s-tab> <c-n>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" PROMOTE VARIABLE TO RSPEC LET
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! PromoteToLet()
:normal! dd
" :exec '?^\s*it\>'
:normal! P
:.s/\(\w\+\) = \(.*\)$/let(:\1) { \2 }/
:normal ==
endfunction
:command! PromoteToLet :call PromoteToLet()
:map <leader>p :PromoteToLet<cr>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" RUNNING TESTS
"
" Test running here is contextual in two different ways:
"
" 1. It will guess at how to run the tests. E.g., if there's a Gemfile
" present, it will `bundle exec rspec` so the gems are respected.
"
" 2. It remembers which tests have been run. E.g., if I'm editing user_spec.rb
" and hit enter, it will run rspec on user_spec.rb. If I then navigate to a
" non-test file, like routes.rb, and hit return again, it will re-run
" user_spec.rb. It will continue using user_spec.rb as my 'default' test
" until I hit enter in some other test file, at which point that test file
" is run immediately and becomes the default. This is complex to describe
" fully, but simple to use in practice: always hit enter to run tests. It
" will run either the test file you're in or the last test file you hit
" enter in.
"
" 3. Sometimes you want to run just one test. For that, there's <leader>T,
" which passes the current line number to the test runner. RSpec knows what
" to do with this (it will run the first test it finds at or below the
" given line number). It probably won't work with other test runners.
" 'Focusing' on a single test in this way will be remembered if you hit
" enter from non-test files, as described above.
"
" 4. Sometimes you don't want contextual test running. In that case, there's
" <leader>T, which runs everything.
"
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! MapCR()
nnoremap <cr> :call RunTestFile()<cr>
endfunction
call MapCR()
nnoremap <leader>S :call RunNearestTest()<cr>
nnoremap <leader>T :call RunTests('')<cr>
" write and run the current file
" nnoremap <cr> :w \| !clear && python %<cr>
function! RunTestFile(...)
if a:0
let command_suffix = a:1
else
let command_suffix = ""
endif
" Are we in a test file?
let in_test_file = match(expand("%"), '\(_spec.rb\|_test.rb\|test_.*\.py\|_test.py\)$') != -1
" Run the tests for the previously-marked file (or the current file if
" it's a test).
if in_test_file
call SetTestFile(command_suffix)
elseif !exists("t:aeo_test_file")
return
end
call RunTests(t:aeo_test_file)
endfunction
function! RunNearestTest()
let spec_line_number = line('.')
call RunTestFile(":" . spec_line_number)
endfunction
function! SetTestFile(command_suffix)
" Set the spec file that tests will be run for.
let t:aeo_test_file=@% . a:command_suffix
endfunction
function! RunTests(filename)
" Write the file and run tests for the given filename
if expand("%") != ""
:w
end
if filereadable("bin/test")
exec ":!bin/test " . a:filename
" Fall back
else
exec ":!py.test -v " . a:filename
end
endfunction
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" SWITCH BETWEEN TEST AND PRODUCTION CODE
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! OpenTestAlternate()
let new_file = AlternateForCurrentFile()
exec ':e ' . new_file
endfunction
function! AlternateForCurrentFile()
let current_file = expand("%")
let new_file = current_file
let in_test = match(current_file, '^tests/') != -1
let going_to_test = !in_test
if going_to_test
let new_file = substitute(new_file, expand('%:t'), 'test_' . expand('%:t'), '')
let new_file = 'tests/' . new_file
else
let new_file = substitute(new_file, 'test_', '', '')
let new_file = substitute(new_file, '^tests/', '', '')
endif
return new_file
endfunction
nnoremap <leader>. :call OpenTestAlternate()<cr>
let g:ackprg = "rg --vimgrep --no-heading --hidden -g '!*git' -T pdf -T svg"
map <leader>a :Ack!<space>
" wrapping just used for markdown
function s:setupWrapping()
set wrap
set wrapmargin=2
set textwidth=80
endfunction
function s:setupMarkup()
call s:setupWrapping()
endfunction
au BufRead,BufNewFile *.{md,markdown,mdown,mkd,mkdn} call s:setupMarkup()
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" RENAME CURRENT FILE
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! RenameFile()
let old_name = expand('%')
let new_name = input('New file name: ', expand('%'), 'file')
if new_name != '' && new_name != old_name
exec ':saveas ' . new_name
exec ':silent !rm ' . old_name
redraw!
endif
endfunction
map <leader>r :call RenameFile()<cr>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" FIND AND REPLACE ACROSS FILES
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! FindAndReplace()
let find_this = input('Replace : ')
let replace_with = input('Replace "'. find_this .'" with: ')
:exec "args `" . 'rg -l ' . find_this . "`"
" eventignore-=Syntax enables syntax highlighting w/argdo
:exec "argdo set eventignore-=Syntax \| %s/" . find_this ."/" . replace_with . "/gc " . "\| w"
endfunction
map <leader>f :call FindAndReplace()<cr>
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" SHORTCUT TO REFERENCE CURRENT FILE'S PATH IN COMMAND LINE MODE
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
cnoremap <expr> %% expand('%:h').'/'
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" FindConditionals COMMAND
" Start a search for conditional branches, both implicit and explicit
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
command! FindConditionals :normal /\<if\>\|\<unless\>\|\<and\>\|\<or\>\|||\|&&<cr>