aboutsummaryrefslogtreecommitdiff
path: root/vim/vimrc
blob: 70f72ed6c849be02b435fda46b5f3b4dcd2af77b (plain) (blame)
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
" Tom Ryder (tejr)'s vimrc: <https://sanctum.geek.nz/cgit/dotfiles.git>
"
" This file is not truly self-contained; it should run without errors on its
" own without the accompanying plugins to which it refers near the end of this
" file, but you'll get errors for some of the leader maps, for example.

" If we're in compatible mode, ensure that the 'C' option that disallows line
" continuations is stripped out, as they're heavily used in this configuration
" for readability; we'll put it back later. Yes, this is necessary, for
" example if this file is :sourced while &compatible, or if Vim is invoked
" under its other name--we are out there, we ex(1)ist!

" Use UTF-8 by default wherever possible
if has('multi_byte')
  set encoding=utf-8
  scriptencoding utf-8
endif

" Use different keys for global and local leaders
if has('eval')
  let g:mapleader = '\'
  let g:maplocalleader = '_'
endif

" Load filetype settings, including filetype plugins and indent settings
if has('autocmd')
  filetype plugin indent on
endif

" Let me backspace over pretty much anything
set backspace=
" Allow backspacing over autoindent
set backspace+=indent
" Allow backspacing over line breaks
set backspace+=eol
" Allow backspacing over the start of the insert operation
set backspace+=start

" Default to no backup files at all, in a way that even ancient/tiny Vims will
" understand; the auto_cache_dirs.vim plugin will take care of re-enabling
" this with a 'backupdir' setting
set nobackup
set nowritebackup

" If backups are enabled, use a more explicit and familiar backup suffix
set backupext=.bak

" Don't back up files in anything named */shm/; they might be password
" files
set backupskip+=*/shm/*

" Allow jumping between windows and tabs to find an open instance of a given
" buffer with :sbuffer.
set switchbuf=useopen
if v:version >= 701
  set switchbuf+=usetab
endif

" Cycle back and forth through buffers.
nnoremap <silent> [b :<C-U>bprevious<CR>
nnoremap <silent> ]b :<C-U>bnext<CR>

" Keep plenty of command and search history, because disk space is cheap
set history=2000

" Always tell me the number of lines changed by a command
set report=0

" Command-line based features
if has('cmdline_info')

  " Show my current position in the status bar
  set ruler

  " Show the keystrokes being entered in the screen
  set showcmd

  " Show the mode we're using if not normal mode (e.g. --INSERT--)
  set showmode

endif

" \d inserts the current local date from date(1)
nnoremap <silent> <Leader>d :<C-U>read !date<CR>
" \D inserts the current UTC date from date(1)
nnoremap <silent> <Leader>D :<C-U>read !date -u<CR>

" Don't try to complete strings from included files, just use the strings in
" the open buffers; I'll open the file if I want to complete from it
set complete-=i

" Configuration for the command completion feature; rather than merely cycling
" through possible completions with Tab, show them above the command line
if has('wildmenu')

  " Use the wild menu, both completing and showing all possible completions
  " with a single Tab press, just as I've configured Bash to do
  set wildmenu
  set wildmode=list:longest

  " Don't complete certain files that I'm not likely to want to manipulate
  " from within Vim:
  if has('wildignore')
    set wildignore+=*.a,*.o
    set wildignore+=*.bmp,*.gif,*.ico,*.jpg,*.png
    set wildignore+=.DS_Store,.git,.hg,.svn
    set wildignore+=*~,*.swp,*.tmp
  endif

  " Complete files without case sensitivity, if the option is available
  if exists('+wildignorecase')
    set wildignorecase
  endif

endif

" A few very important custom digraphs
if has('digraphs')
  digraph ./ 8230  " Ellipsis (HORIZONTAL ELLIPSIS U+2026)
  digraph %% 8984  " Mac command key (PLACE OF INTEREST SIGN U+2318)
  digraph 8: 9731  " Snowman (SNOWMAN U+2603)
endif

" Set up short message settings
set shortmess=
" (file 3 of 5) -> (3 of 5)
set shortmess+=f
" [Incomplete last line] -> [eol]
set shortmess+=i
" I donated to Uganda, thanks Bram
set shortmess+=I
" 999 lines, 888 characters -> 999L, 888C
set shortmess+=l
" [Modified] -> [+]
set shortmess+=m
" [New File] -> [New]
set shortmess+=n
" Don't stack file writing messages
set shortmess+=o
" Don't stack file reading messages
set shortmess+=O
" [readonly] -> [RO]
set shortmess+=r
" Truncate file message at start if too long
set shortmess+=t
" Truncate other message in midle if too long
set shortmess+=T
" written -> [w], appended -> [a]
set shortmess+=w
" [dos format] -> [dos]
set shortmess+=x

" Don't show whitespace characters or end-of-line characters visually by
" default, but make \l toggle between them
set nolist
nnoremap <silent> <Leader>l :<C-U>set list! list?<CR>

" Don't show line numbers by default, but \n toggles them
set nonumber
nnoremap <silent> <Leader>n :<C-U>set number! number?<CR>

" Bind \p to show filetype
nnoremap <silent> <Leader>p :<C-U>set filetype?<CR>

" Use UTF-8 by default wherever possible
if has('multi_byte')
  set encoding=utf-8
endif

" Use all ancestors of current directory for :find
if has('file_in_path')
  set path=**
endif

" If the Vim buffer for a file doesn't have any changes and Vim detects the
" file has been altered, quietly update it
set autoread

" Save a file automatically if I change buffers or perform operations with the
" argument list; this is particularly helpful for me as I don't use 'hidden'
set autowrite

" Don't use modelines at all, they're apparently potential security problems
" and I've never used them anyway
set nomodeline

" I really like ZZ and ZQ, so I wrote a couple more mappings; ZW forces a
" write of the current buffer, but doesn't quit, and ZA forces a write of all
" buffers but doesn't quit
nnoremap <silent> ZW :<C-U>write!<CR>
nnoremap <silent> ZA :<C-U>wall!<CR>

" Don't assume a number with a leading zero is octal; it's far more likely a
" zero-padded decimal, so increment and decrement with ^A and ^X on that basis
set nrformats-=octal

" Try to set the 'j' flag for 'formatoptions', to automatically delete comment
" leaders when joining lines
silent! set formatoptions+=j

" \f shows the current formatoptions at a glance
nnoremap <silent> <Leader>f :<C-U>setlocal formatoptions?<CR>

" Match all forms of brackets in pairs (including angle brackets)
set matchpairs+=<:>

" Change and delete with C and D both cut off the remainder of the line from
" the cursor, but Y yanks the whole line, which is inconsistent (and can be
" done with yy anyway); this fixes it so it only yanks the rest of the line
nnoremap Y y$

" Allow the cursor to get to the top or bottom of the screen before scrolling
" vertically, but set a reasonably wide gutter for scrolling horizontally; no
" particular reason, just suits me better
set scrolloff=0
set sidescrolloff=16

" Rebind <Space> in normal mode as a lazy scroll
nnoremap <Space> <C-f>

" Some special settings for searching, if available
if has('extra_search')

  " Searching as I enter my pattern, \i toggles this
  set incsearch
  nnoremap <silent> <Leader>i :<C-U>set incsearch! incsearch?<CR>

  " Highlight search results, \h toggles this
  set hlsearch
  nnoremap <silent> <Leader>h :<C-U>set hlsearch! hlsearch?<CR>

  " Pressing ^L will clear highlighting until the next search-related
  " operation; quite good because the highlighting gets distracting after
  " you've found what you wanted
  nnoremap <silent> <C-L> :<C-U>nohlsearch<CR><C-L>

endif

" Configure spell checking features, if available
if has('spell')

  " Don't check spelling by default, but bind \s to toggle this
  set nospell
  nnoremap <silent> <Leader>s :<C-U>setlocal spell! spell?<CR>

  " Use New Zealand English for spelling by default (it's almost identical
  " to British English), but bind \u to switch to US English and \z to
  " switch back
  set spelllang=en_nz
  nnoremap <silent> <Leader>u :<C-U>setlocal spelllang=en_us spelllang?<CR>
  nnoremap <silent> <Leader>z :<C-U>setlocal spelllang=en_nz spelllang?<CR>

endif

" Preserve the flags for a pattern when repeating a substitution with &; I
" don't really understand why this isn't a default, but there it is
nnoremap <silent> & :<C-U>&&<CR>

" Same again for visual mode; we use vnoremap rather than xnoremap to stay
" compatible with old Vims without doing :execute dances
vnoremap <silent> & :<C-U>&&<CR>

" Default to no swap files at all, in a way that even ancient/tiny Vims will
" understand; the auto_cache_dirs.vim plugin will take care of re-enabling
" this with a 'directory' setting
set noswapfile

" Options dependent on the syntax feature
if has('syntax') && !has('g:syntax_on')

  " Use syntax highlighting with 100 lines of context
  silent! syntax enable
  silent! syntax sync minlines=100

  " Opinionated; if the author is using color at all, it will probably be with
  " a dark background
  set background=dark

  " The 'sahara' colorscheme only works in the GUI or with 256 colors
  if has('gui_running') || &t_Co >= 256
    silent! colorscheme sahara
  endif

endif

" Start paste mode with F10 to prevent console Vim from confusing a swathe of
" pre-formatted pasted text with actual keyboard input, and thereby attempting
" to indent it inappropriately. If unimpaired.vim is available, it's generally
" nicer to use yo or yO.
set nopaste
set pastetoggle=<F10>

" Don't bother about checking whether Escape is being used as a means to enter
" a Meta-key combination, just register Escape immediately
if exists('+esckeys')
  set noesckeys
endif

" Don't bother drawing the screen while executing macros or other automated or
" scripted processes, just draw the screen as it is when the operation
" completes
set lazyredraw

" Improve redrawing smoothness by assuming that my terminal is reasonably
" fast
set ttyfast

" Never use any kind of bell, visual or not
set visualbell t_vb=

" Require less than one second between keys for mappings to work correctly
set timeout
set timeoutlen=1000

" Require less than a twentieth of a second between keys for key codes to work
" correctly; I don't use Escape as a meta key anyway
set ttimeout
set ttimeoutlen=50

" Rebind Ctrl-C in insert mode to undo the current insert operation
inoremap <C-c> <C-c>u

" Keep screeds of undo history
set undolevels=2000

" 'undodir' and 'undofile' settings will be taken care of by the
" auto_cache_dirs.vim plugin if applicable/possible
if has('persistent_undo')
  set noundofile
endif

" When in visual block mode, let me move the cursor anywhere in the buffer;
" don't restrict me only to regions with text
if has('virtualedit')
  set virtualedit+=block
endif

" Adopt the indent of the last line on new lines
set autoindent

" Use spaces instead of tabs
set expandtab

" Indent with four spaces when an indent operation is used
set shiftwidth=4

" Insert four spaces when Tab is pressed
set softtabstop=4

" When indenting lines with < or >, round the indent to a multiple of
" 'shiftwidth', so even if the line is indented by one space it will indent
" up to 4 and down to 0, for example
set shiftround

" Don't join lines with two spaces at the end of sentences; I don't two-space,
" despite the noble Steve Losh's exhortations
set nojoinspaces

" Configuration for window features
if has('windows')

  " Show the status in a distinct bar above the command line only if there's
  " more than one window on the screen or in the current tab
  set laststatus=1

  " Don't resize windows we're not splitting (Tmux-like; think Mondrian)
  set noequalalways

  " New split windows appear below or to the right of the existing window,
  " not above or to the left per the default
  set splitbelow
  if has('vertsplit')
    set splitright
  endif

  " Only show the tab bar if there's more than one tab
  if exists('+showtabline')
    set showtabline=1
  endif

  " Get rid of visually noisy folding characters
  if has('folding')
    let &fillchars = 'diff: ,fold: ,vert: '
  endif

endif

" Don't wrap by default, but use \w to toggle it on or off quickly
set nowrap
nnoremap <silent> <Leader>w :<C-U>set wrap! wrap?<CR>

" When wrapping text, if a line is so long that not all of it can be shown on
" the screen, show as much as possible anyway; by default Vim fills the left
" column with @ symbols instead, which I don't find very helpful
set display=lastline

" Clearly show when the start or end of the row does not correspond to the
" start and end of the line
set listchars+=precedes:<,extends:>

" Swap the j/gj and k/gk command pairs so that we move by screen row, not
" buffer line, with j/k
nnoremap j gj
nnoremap k gk
nnoremap gj j
nnoremap gk k

" Line break settings and mappings
if has('linebreak')

  " Break lines at word boundaries if possible
  set linebreak

  " Precede continued lines with '...'
  set showbreak=...

  " If we have the option, indent wrapped lines as much as the first line
  if exists('+breakindent')
    set breakindent
  endif

endif

" Disable most core plugin stuff that I don't use; after/plugin/dist.vim
" clears these variables later
if has('eval')

  " 2html.vim is often useful, so keep that
  " matchparen.vim I use constantly

  " I handle versioning plugins manually, and have never used .vba
  let g:loaded_getscriptPlugin = 1
  let g:loaded_vimballPlugin = 1

  " This is what grep, sed, Awk, and Perl are for
  let g:loaded_logiPat = 1

  " ^Z, my dudes
  let g:loaded_netrwPlugin = 1

  " Vim servers? What is this, Emacs?
  let g:loaded_rrhelper = 1

  " System dictionaries plus custom per-machine spell files are fine
  let g:loaded_spellfile_plugin = 1

  " If I want to read a file or a file archived within it I'll decompress or
  " unarchive it myself; a text editor should not do this
  let g:loaded_gzip = 1
  let g:loaded_tarPlugin = 1
  let g:loaded_zipPlugin = 1

endif

" Insert blank lines above and below via my custom unimpaired.vim rip
nmap [<Space> <Plug>PutBlankLinesAbove
nmap ]<Space> <Plug>PutBlankLinesBelow

" \b toggles copy-pasteable linebreak settings
nmap <Leader>b <Plug>CopyLinebreakToggle

" \m in visual/select mode starts a mail message with the selected lines
vmap <Leader>m <Plug>MailMuttSelected
" \m in normal mode starts a mail message with the current line
nmap <Leader>m <Plug>MailMuttLine
" \M in normal mode starts a mail message with the whole buffer
nmap <Leader>M <Plug>MailMuttBuffer

" \x strips trailing whitespace via a custom plugin
nmap <Leader>x <Plug>StripTrailingWhitespace

" Use toggle_option_flag.vim plugin to bind quick toggle actions for some
" 'formatoptions' flags
if has('user_commands')

  " \a: Reformat paragraphs to 'textwidth' on all insert or delete operations
  nnoremap <silent> <Leader>a :<C-U>ToggleOptionFlagLocal formatoptions a<CR>
  " \c: Reformat comments to 'textwidth'
  nnoremap <silent> <Leader>c :<C-U>ToggleOptionFlagLocal formatoptions c<CR>
  " \j: Delete comment leaders when joining lines
  nnoremap <silent> <Leader>j :<C-U>ToggleOptionFlagLocal formatoptions j<CR>
  " \t: Reformat non-comment text to 'textwidth'
  nnoremap <silent> <Leader>t :<C-U>ToggleOptionFlagLocal formatoptions t<CR>

endif

" Add the packaged version of matchit.vim included in the distribution, if
" possible; plugin/macros.vim loads this for older Vims
if has('packages')
  silent! packadd! matchit
endif

" Source all .vim files from ~/.vim/config, which may override any of the
" above
runtime! config/*.vim