503 lines
13 KiB
Text
503 lines
13 KiB
Text
" Max's .vimrc
|
||
|
||
""""""""""""""""""""""
|
||
" Plugins
|
||
""""""""""""""""""""""
|
||
|
||
execute pathogen#infect()
|
||
|
||
""""""""""""""""""""""
|
||
" Basic editing config
|
||
""""""""""""""""""""""
|
||
|
||
set term=xterm-256color
|
||
|
||
set nocompatible
|
||
|
||
colorscheme maxbucknell
|
||
|
||
" Leader
|
||
"
|
||
" Using space as leader is actually a terrific idea. It's one of the
|
||
" easiest things to hit on the keyboard.
|
||
let mapleader = "\<space>"
|
||
|
||
" Don't wrap lines
|
||
"
|
||
" I look at a lot of CSV files and logs, which are generally the only
|
||
" times I see long lines. If code is too long, I shorten it. As such,
|
||
" having lines artificially wrapping only gets in my way.
|
||
set nowrap
|
||
|
||
" Line numbering
|
||
"
|
||
" This shows the real line number of the current line, and relative
|
||
" line numbers on the other lines. Relative line numbers are good to
|
||
" know how many lines to yank, delete, or move.
|
||
set number
|
||
set relativenumber
|
||
|
||
" Write before commands
|
||
"
|
||
" This means that if I have unsaved changes, they get saved before
|
||
" executing a git commit, or something like that.
|
||
set autowrite
|
||
|
||
" Open splits in better places
|
||
"
|
||
" This seems to be the most logical way to split, in the direction
|
||
" that we read, and in agreement with Tmux.
|
||
set splitbelow
|
||
set splitright
|
||
|
||
" Quicker window movement
|
||
"
|
||
" Just remove an extra keystroke
|
||
nnoremap <C-j> <C-w>j
|
||
nnoremap <C-k> <C-w>k
|
||
nnoremap <C-h> <C-w>h
|
||
nnoremap <C-l> <C-w>l
|
||
|
||
" Set editor shell to bash, for Syntastic compatibility
|
||
set shell=bash
|
||
|
||
" Allow visual block mode to select anywhere.
|
||
"
|
||
" I want to use this to manage my ascii drawings
|
||
set virtualedit=block
|
||
|
||
" Swap block and visual block
|
||
nnoremap v <C-V>
|
||
nnoremap <C-V> v
|
||
|
||
vnoremap v <C-V>
|
||
vnoremap <C-V> v
|
||
|
||
" Automatically read on update
|
||
set autoread
|
||
|
||
" I am always adding /g. No longer, suckers!
|
||
set gdefault
|
||
|
||
" Set comment line length
|
||
set tw=72
|
||
set fo=c
|
||
|
||
" Navigate to test, and back
|
||
|
||
" Find test counterpart.
|
||
"
|
||
" This works by replacing src/ with test/, and test/ with src/
|
||
function! FindTestFilename(filename)
|
||
" Replace src/ with t_est/
|
||
let first = substitute(a:filename, 'src/', 't_est/', '')
|
||
" Replace test/ with src/
|
||
let second = substitute(first, 'test/', 'src/', '')
|
||
" Replace t_est/ with test/
|
||
let third = substitute(second, 't_est/', 'test/', '')
|
||
|
||
return third
|
||
endfunction
|
||
|
||
nnoremap <c-t> :exec ":e " . FindTestFilename(expand('%')) <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.
|
||
nnoremap <leader>t :call SelectaCommand("find * -type f", "", ":e")<cr>
|
||
|
||
" Git blame
|
||
"
|
||
" I used to do this by just filling in my buffer, but this is nicer.
|
||
nnoremap <leader>a :Gblame<cr>
|
||
|
||
" Tab config options
|
||
"
|
||
" In general, I prefer spaces to tabs, and 2-space indentation. These
|
||
" settings just make that consistent, so I rarely have to think about
|
||
" it.
|
||
set expandtab
|
||
set tabstop=2
|
||
set shiftwidth=2
|
||
set softtabstop=2
|
||
set autoindent
|
||
|
||
" Disable creation of swap files.
|
||
"
|
||
" Swap files serve a purpose, but not to me. I write often, and so
|
||
" these just get in the way.
|
||
set nobackup
|
||
set nowritebackup
|
||
set noswapfile
|
||
|
||
" What the hell is ex mode
|
||
"
|
||
" Whatever it is, I don't like it.
|
||
nnoremap Q <nop>
|
||
|
||
" Faster highlight removal than ;noh
|
||
"
|
||
" :noh is the command one should run to remove highlighted search
|
||
" terms. I search for things so often, that I got sick of typing it
|
||
" so much. So I made a short cut.
|
||
nnoremap <silent> <leader>/ :noh<cr>
|
||
|
||
" Remap semi-colon to colon.
|
||
"
|
||
" Colon is the starting point of a lot of actions in Vim. And I
|
||
" shouldn't have to hold a modifier key to access so much
|
||
" essential functionality.
|
||
noremap ; :
|
||
noremap ;; ;
|
||
|
||
" Quick exit insert mode
|
||
"
|
||
" Escape is at the far corner of my keyboard, and having it so far away
|
||
" was discouraging my from exiting insert mode. Qwerty users can remap
|
||
" jk to <esc>, which is a far better solution. The keys are next to each
|
||
" other, and it makes exiting insert mode a pleasant rolling motion.
|
||
" Moreover, when in normal mode, jk is a no-op.
|
||
"
|
||
" As a dvorak user, jk was too cumbersome, but there were no other
|
||
" suitable candidates. hh is inferior in that it is not a no-op in
|
||
" normal mode, but it is just as easy to type. The only caveat is when
|
||
" an edit ends with h, which is why hhh will expand to place an h in
|
||
" the buffer before exiting.
|
||
"
|
||
" To encourage me to adopt the new style, I disable escape. That one is
|
||
" sure to mess up someone not familiar with my setup.
|
||
inoremap hh <esc>
|
||
inoremap hhh h<esc>
|
||
" inoremap <esc> <nop>
|
||
inoremap uu \
|
||
|
||
" Bad arrow keys
|
||
"
|
||
" This will disable use of arrow keys in normal and insert modes. This
|
||
" is a good idea to get into the vim way. I don’t really use the arrow
|
||
" keys anymore.
|
||
"
|
||
" That said, I have reservations about the apparently egregious nature
|
||
" of the arrow keys. On my MacBook, they are quite close. Still, I can
|
||
" understand that it is better to rely only on the core keys that you
|
||
" know are within reach, not just the ones that happen to be on one
|
||
" computer.
|
||
inoremap <up> <nop>
|
||
inoremap <down> <nop>
|
||
inoremap <left> <nop>
|
||
inoremap <right> <nop>
|
||
noremap <up> <nop>
|
||
noremap <down> <nop>
|
||
noremap <left> <nop>
|
||
noremap <right> <nop>
|
||
|
||
" Move lines up and down
|
||
"
|
||
" These are very useful commands, especially for re-ordering things. I
|
||
" would like to make it possible to move hunks of code with similar
|
||
" shortcuts, but I haven't thought it through yet. I would also like
|
||
" to have something automated, wherein I could sort a list of things
|
||
" alphabetically.
|
||
noremap - ddp
|
||
noremap _ ddkP
|
||
|
||
" Uppercase an entire word.
|
||
"
|
||
" This is handy for things like constants. I have no caps lock, and
|
||
" holding shift can be a pain.
|
||
nnoremap <leader>u viwU
|
||
|
||
" Show me when my lines are too long
|
||
"
|
||
" I wish to limit my lines to 80 characters long. However, Vim creates
|
||
" the n+1th character when you have n characters in a line. Hence, when
|
||
" my line is 80 characters long, I see the red line. So, this is set to
|
||
" 82, meaning that I only see the line when my lines actually are too long.
|
||
call matchadd('ColorColumn', '\%82v', 100)
|
||
|
||
" Prevent K from being annoying
|
||
noremap K <nop>
|
||
|
||
" Edit and Reload .vimrc files
|
||
"
|
||
" When I hit something that bugs me, I usually think about what I can
|
||
" do to make it better. Then I forget. This keeps happening and I keep
|
||
" getting annoyed. These commands make it simple to quickly edit my
|
||
" vimrc, and then reload it.
|
||
nmap <silent> <Leader>ev :e $MYVIMRC<CR>
|
||
nmap <silent> <Leader>es :so $MYVIMRC<CR>
|
||
|
||
" Search options
|
||
"
|
||
" Show partial matches while searching
|
||
set incsearch
|
||
|
||
" Highlight other matches in the file
|
||
set hlsearch
|
||
|
||
" Show the next search result.
|
||
" By Damian Conway.
|
||
"
|
||
" This rewires n and N to do their normal thing, and then call the
|
||
" HLNext routine. This temporarily adds a new style to the next
|
||
" highlight.
|
||
nnoremap <silent> n n:call HLNext(0.2)<cr>
|
||
nnoremap <silent> N N:call HLNext(0.2)<cr>
|
||
|
||
" Blink the next match
|
||
function! HLNext (blinktime)
|
||
let [bufnum, lnum, col, off] = getpos('.')
|
||
let matchlen = strlen(matchstr(strpart(getline('.'),col-1),@/))
|
||
let target_pat = '\c\%#'.@/
|
||
let ring = matchadd('MBSearchNext', target_pat, 101)
|
||
redraw
|
||
exec 'sleep ' . float2nr(a:blinktime * 1000) . 'm'
|
||
call matchdelete(ring)
|
||
redraw
|
||
endfunction
|
||
|
||
" Disable match-paren
|
||
"
|
||
" It has really bad colours and it displays terribly.
|
||
" let loaded_matchparen = 1
|
||
|
||
" Make searches case sensitive only if an upper case character has been typed
|
||
set ignorecase smartcase
|
||
|
||
" Prevent Vim from clobbering the scrollback buffer.
|
||
"
|
||
" This means that all of Vim's output is shown in the terminal screen
|
||
" history. This is ugly, but it's saved my bacon a few times. See
|
||
" http://www.shallowsky.com/linux/noaltscreen.html
|
||
set t_ti= t_te=
|
||
|
||
" Highlight current line
|
||
"
|
||
" It's good to have a sense of place.
|
||
set cursorline
|
||
|
||
" Ensure that the cursor never touches top or bottom of screen
|
||
"
|
||
" This controls the distance that the current line must maintain
|
||
" between the top and bottom of the screen. Setting this to a very
|
||
" large number will always keep the cursor vertically centered.
|
||
"
|
||
" I don't do this, because sometimes I wish to see something at the
|
||
" bottom of the buffer, so I can copy it at the top.
|
||
set scrolloff=4
|
||
|
||
" Allow backspacing over everything in insert mode
|
||
"
|
||
" By default, Vim will stop when it gets to the beginning of a line,
|
||
" throw its arms in the air and give up.
|
||
set backspace=indent,eol,start
|
||
|
||
" Display incomplete commands and the lines they apply to.
|
||
set showcmd
|
||
|
||
" Allow hidden buffers
|
||
"
|
||
" If this is off, buffers are destroyed when they fade out of view. We
|
||
" have the memory to spare to keep them around.
|
||
set hidden
|
||
|
||
" Enable highlighting for syntax
|
||
syntax on
|
||
|
||
" Enable file type detection.
|
||
"
|
||
" Use the default filetype settings, so that mail gets 'tw' set to 72,
|
||
" 'cindent' is on in C files, etc.
|
||
" Also load indent files, to automatically do language-dependent
|
||
" indenting.
|
||
filetype plugin indent on
|
||
|
||
" Insert only one space when joining lines that contain
|
||
" sentence-terminating punctuation like `.`.
|
||
set nojoinspaces
|
||
|
||
" If a file is changed outside of vim, automatically reload it
|
||
set autoread
|
||
|
||
" Show trailing whitespace, since it's a crime
|
||
set list
|
||
set listchars=trail:·,tab:‣\
|
||
|
||
" Turn off code folding
|
||
"
|
||
" I hate code folding. It makes me mad. I just want a buffer with all
|
||
" of my text in it, no funny business.
|
||
set foldmethod=manual
|
||
set nofoldenable
|
||
let g:vim_markdown_folding_disabled=1
|
||
let g:vimtex_fold_enabled=0
|
||
|
||
" Always show status bar
|
||
set laststatus=2
|
||
|
||
" Pastetoggle to let Vim paste things without auto stuff
|
||
set pastetoggle=<F2>
|
||
|
||
""""""""""""""""""
|
||
" Ultisnips, y'all
|
||
""""""""""""""""""
|
||
|
||
let g:UltiSnipsExpandTrigger="<tab>"
|
||
let g:UltiSnipsJumpForwardTrigger="<tab>"
|
||
let g:UltiSnipsJumpBackwardTrigger="<S-tab>"
|
||
|
||
""""""""
|
||
" VDebug
|
||
""""""""
|
||
|
||
let g:vdebug_options={}
|
||
let g:vdebug_options['break_on_open']=1
|
||
let g:vdebug_options['ide_key']='docker'
|
||
let g:vdebug_options['port']=9000
|
||
let g:vdebug_options['timeout']=300
|
||
let g:vdebug_options['path_maps']={
|
||
\'/mnt/www': getcwd()
|
||
\}
|
||
|
||
"""""""""""""
|
||
" Local vimrc
|
||
"""""""""""""
|
||
|
||
" Just load automatically, never ask me.
|
||
let g:localvimrc_ask=0
|
||
|
||
""""""""
|
||
" Python
|
||
""""""""
|
||
|
||
let g:pymode_python = 'python3'
|
||
|
||
"""""""""""""""""
|
||
" Custom autocmds
|
||
"""""""""""""""""
|
||
|
||
augroup vimrcEx
|
||
" Clear all autocmds in the group
|
||
autocmd!
|
||
autocmd FileType text setlocal textwidth=78
|
||
" 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
|
||
|
||
" Language whitespace settings
|
||
autocmd FileType dockerfile,less,snippets,json,c,xml,java,php,python setl et sw=4 sts=4
|
||
autocmd FileType make,markdown setl noet sw=8 sts=8 ts=8
|
||
|
||
" Hard wrap prose
|
||
"
|
||
" This will automatically insert a new line in insert mode when a
|
||
" line gets too long (above 80 characters). I can also run gqap
|
||
" in normal mode to reflow a paragraph.
|
||
autocmd FileType
|
||
\ markdown,
|
||
\ setl tw=80 fo=t1
|
||
|
||
augroup END
|
||
|
||
" Make directories in a filename if they don't exist.
|
||
|
||
function! AskQuit (msg, options, quit_option)
|
||
if confirm(a:msg, a:options) == a:quit_option
|
||
exit
|
||
endif
|
||
endfunction
|
||
|
||
function! EnsureDirExists ()
|
||
let required_dir = expand("%:h")
|
||
if !isdirectory(required_dir)
|
||
try
|
||
call mkdir( required_dir, 'p' )
|
||
catch
|
||
echom "Could not create directory"
|
||
exit
|
||
endtry
|
||
endif
|
||
endfunction
|
||
|
||
augroup AutoMkdir
|
||
autocmd!
|
||
autocmd BufNewFile * :call EnsureDirExists()
|
||
augroup END
|
||
|
||
" Set the statusline.
|
||
" This shows something like:
|
||
"
|
||
" [vim/vimrc.symlink] [351,30] [vim]
|
||
set statusline=[%f] " filename
|
||
set statusline+=\ [%l,\ %c] "line and column number
|
||
set statusline+=\ %y " filetype
|
||
set statusline+=\ %{ALEGetStatusLine()}
|
||
|
||
" Ale
|
||
"
|
||
" An asynchronous linting engine.
|
||
let g:ale_lint_on_text_changed = 1
|
||
let g:ale_linters = {
|
||
\ 'javascript': [ 'eslint' ],
|
||
\ 'php': [ 'php', 'phpcs' ],
|
||
\ 'json': [ 'jsonlint' ]
|
||
\ }
|
||
|
||
" Hallelujah!
|
||
let g:ale_set_signs = 1
|
||
let g:ale_sign_column_always = 1
|
||
let g:ale_sign_error = '--'
|
||
let g:ale_sign_warning = '--'
|
||
|
||
let g:ale_php_phpcs_standard = 'PSR2'
|
||
let g:ale_javascript_eslint_options = '--no-ignore '
|
||
|
||
" Gitgutter
|
||
|
||
let g:gitgutter_realtime = 1
|
||
let g:gitgutter_eager = 1
|
||
|
||
" JSX in mah JavaScript
|
||
let g:jsx_ext_required = 0
|
||
|
||
" Copy visual selection to clipboard.
|
||
noremap <leader>y "*y
|
||
|
||
" Go to most recently edited file
|
||
nnoremap <leader><leader> <c-^>
|
||
|
||
" Disable syntax hiding in JSON
|
||
"
|
||
" Vim JSON provides a fancy way of viewing, where it hides quotes and
|
||
" just shows you data. I don't want that.
|
||
let g:vim_json_syntax_conceal = 0
|
||
|
||
" Show syntax highlighting groups for word under cursor
|
||
"
|
||
" This is useful for finding rogue elements I forgot in my colour
|
||
" scheme.
|
||
nnoremap <leader>\ :call <SID>SynStack()<CR>
|
||
function! <SID>SynStack()
|
||
if !exists("*synstack")
|
||
return
|
||
endif
|
||
echo map(synstack(line('.'), col('.')), 'synIDattr(v:val,"name")')
|
||
endfunc
|
||
|
||
|