Created
December 16, 2017 20:55
-
-
Save robvolk/64c0b1adaaf00aa7576d40d887c5d379 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Rob Volk's .vimrc, completely based off of " This is Rob Volk's .vimrc, completely based off of Gary Bernhardt's .vimrc file | |
" vim:set ts=2 sts=2 sw=2 expandtab: | |
autocmd! | |
call pathogen#infect('bundle/{}') | |
call plug#begin('~/.vim/plugged') | |
Plug 'prettier/vim-prettier', { | |
\ 'do': 'yarn install', | |
\ 'for': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'graphql'] } | |
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } | |
call plug#end() | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" BASIC EDITING CONFIGURATION | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
set nocompatible | |
" allow unsaved background buffers and remember marks/undo for them | |
set hidden | |
" remember more commands and search history | |
set history=10000 | |
set expandtab | |
set tabstop=4 | |
set shiftwidth=4 | |
set softtabstop=4 | |
set autoindent | |
set laststatus=2 | |
set showmatch | |
set incsearch | |
set hlsearch | |
" make searches case-sensitive only if they contain upper-case characters | |
set ignorecase smartcase | |
" highlight current line | |
set cmdheight=1 | |
set switchbuf=useopen | |
set showtabline=2 | |
set winwidth=79 | |
" This makes RVM work inside Vim. I have no idea why. | |
set shell=bash | |
" Prevent Vim from clobbering the scrollback buffer. See | |
" http://www.shallowsky.com/linux/noaltscreen.html | |
set t_ti= t_te= | |
" keep more context when scrolling off the end of a buffer | |
set scrolloff=3 | |
" Don't make backups at all | |
set nobackup | |
set nowritebackup | |
set backupdir=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp | |
set directory=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp | |
" allow backspacing over everything in insert mode | |
set backspace=indent,eol,start | |
" display incomplete commands | |
set showcmd | |
" 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 | |
" use emacs-style tab completion when selecting files, etc | |
set wildmode=longest,list | |
" make tab completion for files/buffers act like bash | |
set wildmenu | |
let mapleader="," | |
" Fix slow O inserts | |
:set timeout timeoutlen=1000 ttimeoutlen=100 | |
" Normally, Vim messes with iskeyword when you open a shell file. This can | |
" leak out, polluting other file types even after a 'set ft=' change. This | |
" variable prevents the iskeyword change so it can't hurt anyone. | |
let g:sh_noisk=1 | |
" Modelines (comments that set vim options on a per-file basis) | |
set modeline | |
set modelines=3 | |
" Turn folding off for real, hopefully | |
set foldmethod=manual | |
set nofoldenable | |
" 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 without asking | |
set autoread | |
" Function to trim trailing whitespaces | |
" fun! <SID>StripTrailingWhitespaces() | |
" let l = line(".") | |
" let c = col(".") | |
" %s/\s\+$//e | |
" call cursor(l, c) | |
" endfun | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" 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 | |
"for ruby, autoindent with two spaces, always expand tabs | |
autocmd FileType ruby,haml,eruby,yaml,html,javascript,sass,cucumber,markdown,liquid,typescript set ai sw=2 sts=2 et | |
autocmd FileType python set sw=4 sts=4 et | |
autocmd! BufRead,BufNewFile *.sass setfiletype sass | |
autocmd BufRead *.mkd set ai formatoptions=tcroqn2 comments=n:> | |
autocmd BufRead *.markdown set ai formatoptions=tcroqn2 comments=n:> | |
" Indent p tags | |
" autocmd FileType html,eruby if g:html_indent_tags !~ '\\|p\>' | let g:html_indent_tags .= '\|p\|li\|dt\|dd' | endif | |
" Don't syntax highlight markdown because it's often wrong | |
autocmd! FileType mkd setlocal syn=off | |
" Leave the return key alone when in command line windows, since it's used | |
" to run commands there. | |
autocmd! CmdwinEnter * :unmap <cr> | |
autocmd! CmdwinLeave * :call MapCR() | |
" *.md is markdown | |
autocmd! BufNewFile,BufRead *.md setlocal ft= | |
" indent slim two spaces, not four | |
autocmd! FileType *.slim set sw=2 sts=2 et | |
" auto trim whitespaces on save | |
" autocmd FileType c,cpp,java,php,ruby,python,javascript,haml,yaml,html,sass,cucumber,slim autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces() | |
augroup END | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" COLOR | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
:set t_Co=256 " 256 colors | |
:set background=dark | |
:color grb256 | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" STATUS LINE | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
:set statusline=%<%f\ (%{&ft})\ %-4(%m%)%=%-19(%3l,%02c%03V%) | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" MISC KEY MAPS | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
map <leader>y "*y | |
" Move around splits with <c-hjkl> | |
nnoremap <c-j> <c-w>j | |
nnoremap <c-k> <c-w>k | |
nnoremap <c-h> <c-w>h | |
nnoremap <c-l> <c-w>l | |
" Insert a hash rocket with <c-l> | |
imap <c-l> <space>=><space> | |
" Can't be bothered to understand ESC vs <c-c> in insert mode | |
imap <c-c> <esc> | |
nnoremap <leader><leader> <c-^> | |
" Close all other windows, open a vertical split, and open this file's test | |
" alternate in it. | |
nnoremap <leader>s :call FocusOnFile()<cr> | |
function! FocusOnFile() | |
tabnew % | |
normal! v | |
normal! l | |
call OpenTestAlternate() | |
normal! h | |
endfunction | |
" Reload in chrome | |
map <leader>l :w\|:silent !reload-chrome<cr> | |
" Align selected lines | |
vnoremap <leader>ib :!align<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" MULTIPURPOSE TAB KEY | |
" Indent if we're at the beginning of a line. Else, do completion. | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
function! InsertTabWrapper() | |
let col = col('.') - 1 | |
if !col || getline('.')[col - 1] !~ '\k' | |
return "\<tab>" | |
else | |
return "\<c-p>" | |
endif | |
endfunction | |
inoremap <expr> <tab> InsertTabWrapper() | |
inoremap <s-tab> <c-n> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" OPEN FILES IN DIRECTORY OF CURRENT FILE | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
cnoremap <expr> %% expand('%:h').'/' | |
map <leader>e :edit %% | |
map <leader>v :view %% | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" 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>n :call RenameFile()<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" 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> | |
" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" " EXTRACT VARIABLE (SKETCHY) | |
" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" function! ExtractVariable() | |
" let name = input("Variable name: ") | |
" if name == '' | |
" return | |
" endif | |
" " Enter visual mode (not sure why this is needed since we're already in | |
" " visual mode anyway) | |
" normal! gv | |
" " Replace selected text with the variable name | |
" exec "normal c" . name | |
" " Define the variable on the line above | |
" exec "normal! O" . name . " = " | |
" " Paste the original selected text to be the variable value | |
" normal! $p | |
" endfunction | |
" vnoremap <leader>rv :call ExtractVariable()<cr> | |
" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" " INLINE VARIABLE (SKETCHY) | |
" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" function! InlineVariable() | |
" " Copy the variable under the cursor into the 'a' register | |
" :let l:tmp_a = @a | |
" :normal "ayiw | |
" " Delete variable and equals sign | |
" :normal 2daW | |
" " Delete the expression into the 'b' register | |
" :let l:tmp_b = @b | |
" :normal "bd$ | |
" " Delete the remnants of the line | |
" :normal dd | |
" " Go to the end of the previous line so we can start our search for the | |
" " usage of the variable to replace. Doing '0' instead of 'k$' doesn't | |
" " work; I'm not sure why. | |
" normal k$ | |
" " Find the next occurence of the variable | |
" exec '/\<' . @a . '\>' | |
" " Replace that occurence with the text we yanked | |
" exec ':.s/\<' . @a . '\>/' . escape(@b, "/") | |
" :let @a = l:tmp_a | |
" :let @b = l:tmp_b | |
" endfunction | |
" nnoremap <leader>ri :call InlineVariable()<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Md5 COMMAND | |
" Show the MD5 of the current buffer | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
command! -range Md5 :echo system('echo '.shellescape(join(getline(<line1>, <line2>), '\n')) . '| md5') | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" OpenChangedFiles COMMAND | |
" Open a split for each dirty file in git | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
function! OpenChangedFiles() | |
only " Close all windows, unless they're modified | |
let status = system('git status -s | grep "^ \?\(M\|A\|UU\)" | sed "s/^.\{3\}//"') | |
let filenames = split(status, "\n") | |
exec "edit " . filenames[0] | |
for filename in filenames[1:] | |
exec "sp " . filename | |
endfor | |
endfunction | |
command! OpenChangedFiles :call OpenChangedFiles() | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" InsertTime COMMAND | |
" Insert the current time | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
command! InsertTime :normal a<c-r>=strftime('%F %H:%M:%S.0 %z')<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" FindConditionals COMMAND | |
" Start a search for conditional branches, both implicit and explicit | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
command! FindConditionals :normal /\<if\>\|\<unless\>\|\<and\>\|\<or\>\|||\|&&<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Diff tab management: open the current git diff in a tab | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
command! GdiffInTab tabedit %|vsplit|Gdiff | |
nnoremap <leader>d :GdiffInTab<cr> | |
nnoremap <leader>D :tabclose<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Test quickfix list management | |
" | |
" If the tests write a tmp/quickfix file, these mappings will navigate through | |
" it | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
function! GetBufferList() | |
redir =>buflist | |
silent! ls | |
redir END | |
return buflist | |
endfunction | |
function! BufferIsOpen(bufname) | |
let buflist = GetBufferList() | |
for bufnum in map(filter(split(buflist, '\n'), 'v:val =~ "'.a:bufname.'"'), 'str2nr(matchstr(v:val, "\\d\\+"))') | |
if bufwinnr(bufnum) != -1 | |
return 1 | |
endif | |
endfor | |
return 0 | |
endfunction | |
function! ToggleQuickfix() | |
if BufferIsOpen("Quickfix List") | |
cclose | |
else | |
call OpenQuickfix() | |
endif | |
endfunction | |
function! OpenQuickfix() | |
cgetfile tmp/quickfix | |
topleft cwindow | |
if &ft == "qf" | |
cc | |
endif | |
endfunction | |
nnoremap <leader>q :call ToggleQuickfix()<cr> | |
nnoremap <leader>Q :cc<cr> | |
nnoremap <leader>j :cnext<cr> | |
nnoremap <leader>k :cprev<cr> | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" RemoveFancyCharacters COMMAND | |
" Remove smart quotes, etc. | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
function! RemoveFancyCharacters() | |
let typo = {} | |
let typo["“"] = '"' | |
let typo["”"] = '"' | |
let typo["‘"] = "'" | |
let typo["’"] = "'" | |
let typo["–"] = '--' | |
let typo["—"] = '---' | |
let typo["…"] = '...' | |
:exe ":%s/".join(keys(typo), '\|').'/\=typo[submatch(0)]/ge' | |
endfunction | |
command! RemoveFancyCharacters :call RemoveFancyCharacters() | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Selecta Mappings | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" 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 | |
function! SelectaFile(path) | |
call SelectaCommand("find " . a:path . "/* -type f", "", ":e") | |
endfunction | |
nnoremap <leader>f :call SelectaFile(".")<cr> | |
nnoremap <leader>gv :call SelectaFile("app/views")<cr> | |
nnoremap <leader>gc :call SelectaFile("app/controllers")<cr> | |
nnoremap <leader>gm :call SelectaFile("app/models")<cr> | |
nnoremap <leader>gh :call SelectaFile("app/helpers")<cr> | |
nnoremap <leader>gl :call SelectaFile("lib")<cr> | |
nnoremap <leader>gp :call SelectaFile("public")<cr> | |
nnoremap <leader>gs :call SelectaFile("public/stylesheets")<cr> | |
nnoremap <leader>gf :call SelectaFile("features")<cr> | |
"Fuzzy select | |
function! SelectaIdentifier() | |
" Yank the word under the cursor into the z register | |
normal "zyiw | |
" Fuzzy match files in the current directory, starting with the word under | |
" the cursor | |
call SelectaCommand("find * -type f", "-s " . @z, ":e") | |
endfunction | |
nnoremap <c-g> :call SelectaIdentifier()<cr> | |
"""""""""""""""""""""" | |
" Rob's stuff | |
"""""""""""""""""""""" | |
:set autoread | |
nmap <silent> <leader>t :FZF<CR> | |
let g:ackprg = 'ag --nogroup --nocolor --column' | |
" navigate between buffers | |
nmap <tab> :bnext<cr> | |
" vim-test | |
nmap <silent> <leader>r :TestNearest<CR> | |
nmap <silent> <leader>T :TestFile<CR> | |
nmap <silent> <leader>a :TestSuite<CR> | |
nmap <silent> <leader>l :TestLast<CR> | |
nmap <silent> <leader>g :TestVisit<CR> | |
function! RunTestFile() | |
:wa | |
:TestLast | |
endfunction | |
function! MapCR() | |
nnoremap <cr> :call RunTestFile() <cr> | |
endfunction | |
call MapCR() | |
let g:easytags_cmd = '/usr/local/bin/ctags' | |
let g:easytags_async=1 | |
let g:easytags_on_cursorhold=0 | |
let g:easytags_by_filetype='~/.vim/tags' | |
let g:easytags_syntax_keyword = 'always' | |
let g:easytags_auto_highlight = 0 | |
" Quickly edit/reload the vimrc file | |
nmap <silent> <leader>ev :e $MYVIMRC<CR> | |
nmap <silent> <leader>sv :so $MYVIMRC<CR> | |
map <C-n> :NERDTreeToggle<CR> | |
" Trim trailing whitespace on save | |
autocmd BufWritePre * :%s/\s\+$//e | |
" run docker tests | |
function! RunDockerTests() | |
:wa | |
:! docker-compose run test | |
endfunction | |
nmap <silent> <leader>tt :call RunDockerTests() <cr> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment