filetype plugin indent on if has("termguicolors") set termguicolors endif syntax enable set background=dark colorscheme neodark set backspace=indent,eol,start set hidden set wildmenu set wildignorecase set wildmode=list:longest,full set wildignore+=tags,cscope.* set wildignore+=*/min/* set wildignore+=*/.git/**/* set wildignore+=*/node_modules/**/* set wildignore+=*/tmp/**/* set path=.,, set complete-=i " Don't look in included files. set completeopt=menu set nrformats-=octal set signcolumn=yes set splitbelow set splitright " Ideally I'd like: " - case-sensitive insert-mode completion " - smart case-insensitive searching " It looks like you can't have both through configuration; " you have to write a customer completion function. " For now I prioritise the first requirement. " set ignorecase " Case-insensitive searching. " set smartcase " But case-sensitive if expression contains a capital letter. set number set ruler set laststatus=2 set fillchars+=stl:\ ,stlnc:\ hi clear StatusLine hi clear StatusLineNC hi StatusLine term=bold cterm=bold ctermfg=White ctermbg=235 hi StatusLineNC term=bold cterm=bold ctermfg=White ctermbg=235 " highlight values in terminal vim, colorscheme solarized hi User1 ctermfg=4 guifg=#40ffff " Identifier hi User2 ctermfg=2 gui=bold guifg=#ffff60 " Statement hi User3 term=bold cterm=bold ctermfg=1 guifg=White guibg=Red " Error hi User4 ctermfg=1 guifg=Orange " Special hi User5 ctermfg=10 guifg=#80a0ff " Comment hi User6 term=bold cterm=bold ctermfg=1 guifg=Red " WarningMsg function! WindowNumber() return tabpagewinnr(tabpagenr()) endfunction function! TrailingSpaceWarning() if !exists("b:statusline_trailing_space_warning") let lineno = search('\s$', 'nw') if lineno != 0 let b:statusline_trailing_space_warning = '[trailing:'.lineno.']' else let b:statusline_trailing_space_warning = '' endif endif return b:statusline_trailing_space_warning endfunction " recalculate when idle, and after saving augroup statusline_trail autocmd! autocmd CursorHold,BufWritePost * unlet! b:statusline_trailing_space_warning augroup END set statusline= set statusline+=%6*%m%r%* " modified, readonly set statusline+=\ set statusline+=%5*%{expand('%:h')}/ " relative path to file's directory set statusline+=%1*%t%* " file name set statusline+=\ set statusline+=\ set statusline+=%3*%{TrailingSpaceWarning()}%* " trailing whitespace set statusline+=\ set statusline+=%{kite#statusline()} set statusline+=%= " switch to RHS set statusline+=%5*%{empty(&titlestring)?'':&titlestring}%* set statusline+=\ set statusline+=%{exists('*CapsLockStatusline')?CapsLockStatusline():''} set statusline+=\ set statusline+=\ set statusline+=%5*%L\ lines%* " number of lines set statusline+=\ set statusline+=\ set statusline+=\ set statusline+=%2*%-2.2{WindowNumber()}%* " window number set incsearch set hlsearch set wrap set breakindent set breakindentopt=sbr " Unicode curly arrow, space set showbreak=↪> set scrolloff=3 set display+=lastline set shiftwidth=2 set tabstop=2 set expandtab set title if has('nvim') autocmd VimLeave * set titleold=:) endif set visualbell set belloff+=ctrlg " prevent beeping during completion set nobackup set nowritebackup set noswapfile set shortmess=atIc set noequalalways set autoread set updatetime=100 set notimeout set ttimeout if !has('nvim') " Avoid delay with O immediately after Esc. " http://stackoverflow.com/a/2158610/151007 set noesckeys endif set tags=.git/tags,tags set clipboard=unnamed " Ensure pathogen can load plugins when restoring a vim session. set sessionoptions-=options set cpo+=J " Two spaces delimit my sentences. set formatoptions+=j " Remove comment leaders when joining lines. set grepprg=rg\ --vimgrep\ --smart-case set grepformat=%f:%l:%c:%m " :Grep pattern [directory] " " Escaping is problematic. command! -bang -nargs=+ -complete=file Grep silent grep! <args> | \ if !empty(getqflist()) | \ let @/=split("<args>")[0] | \ call feedkeys(":let &hlsearch=1\<CR>", "n") | \ copen | \ redraw! | \ endif nnoremap <Leader>g :Grep " Project-specific vimrc set exrc set secure nnoremap gK K " Opposite of join (breaK?). " A space is replaced with a carriage return; otherwise a carriage return is inserted. nnoremap <expr> K getline('.')[col('.') - 1] == ' ' ? "r<CR>" : "i<CR><ESC>l" " Show tabs and trailing whitespace visually. if &listchars ==# 'eol:$' set listchars=tab:>\ ,trail:-,extends:>,precedes:<,nbsp:+ if &termencoding ==# 'utf-8' || &encoding ==# 'utf-8' let &listchars = "tab:\u21e5 ,trail:\u2423,extends:\u21c9,precedes:\u21c7,nbsp:\u26ad" endif endif autocmd InsertEnter * set nolist autocmd InsertLeave * set list " Highlight non-ASCII characters. " syntax match nonascii "[^\x00-\x7F]" " highlight link nonascii ErrorMsg autocmd BufEnter * syn match ErrorMsg /[^\x00-\x7F]/ " Treat buffers from stdin as scratch. au StdinReadPost * :set buftype=nofile " Writing help files " https://vi.stackexchange.com/a/3698/1643 augroup help_start autocmd! autocmd FileType help call SetHelpFiletype() augroup END function! SetHelpFiletype() augroup help_insert autocmd! autocmd InsertEnter <buffer> setlocal conceallevel=0 | highlight clear Ignore autocmd InsertLeave <buffer> setlocal conceallevel=2 augroup END endfunction " Windowing. nnoremap <Tab> <C-W>w nnoremap <S-Tab> <C-W>W " Use | and _ to split windows (while preserving original behaviour of [count]bar and [count]_). nnoremap <expr><silent> <Bar> v:count == 0 ? "<C-W>v" : ":<C-U>normal! 0".v:count."<Bar><CR>" nmap <expr><silent> _ v:count == 0 ? "<C-W>s" : ":<C-U>normal! ".v:count."_<CR>" " Jump to window <n>: " http://stackoverflow.com/a/6404246/151007 for i in range(1, 9) execute 'nnoremap <Leader>'.i.' :'.i.'wincmd w<CR>' endfor " Jump to previous window: execute 'nnoremap <Leader>0 :wincmd p<CR>' " Move current line / visual line selection up or down. nnoremap <C-j> :m+<CR>== nnoremap <C-k> :m-2<CR>== xnoremap <C-j> :m'>+<CR>gv=gv xnoremap <C-k> :m-2<CR>gv=gv " gm jumps to middle of current screen line's text. " " (Middle of entire line is easier: virtcol('$')/2) function! GotoMiddle() " Get buffer width. (http://stackoverflow.com/a/26318602/151007) redir => signlist execute "silent sign place buffer=".bufnr('') redir end let signlist = split(signlist, '\n') let width = winwidth(0) - &numberwidth - &foldcolumn - (len(signlist) > 2 ? 2 : 0) normal g^ let first_non_blank_char = col('.') % width normal g$ let last_non_blank_char = 1 + ((col('.')-1) % width) let middle_non_blank_char = first_non_blank_char + (last_non_blank_char - first_non_blank_char) / 2 execute "normal g0".middle_non_blank_char."l" endfunction nnoremap <silent> gm :call GotoMiddle()<CR> " OS X-like space bar to scroll. nnoremap <Space> <C-F> " <Leader><space> turns off search highlighting and enable CSS highlighting. if exists("*css_color#enable()") nnoremap <Leader><space> :call css_color#enable()<CR>:noh<CR> else nnoremap <Leader><space> :noh<CR> endif " Hide CSS highlight when searching so search highlight is visible if exists("*css_color#disable()") nnoremap / :call css_color#disable()<CR>/ endif " Directory of current file. cnoremap %% <C-R>=expand("%:h")."/"<CR> " Make Y consistent with D and C (instead of yy) nnoremap Y y$ " ~ toggles ' and " in addition to its normal behaviour " TODO toggle - and _ nnoremap <expr> ~ getline('.')[col('.')-1] == "'" ? "r\"l" : getline('.')[col('.')-1] == '"' ? "r'l" : '~' " Visually select the text that was most recently edited/pasted. " Note: gv selects previously selected area. nmap gV `[v`] " Retain cursor position when visually yanking. xnoremap <expr> y 'my"'.v:register.'y`y' xnoremap <expr> Y 'my"'.v:register.'Y`y' " Make * and # work with visual selection. " For anything more sophisticated, try: " - https://github.com/nelstrom/vim-visual-star-search " - https://github.com/thinca/vim-visualstar xnoremap <silent> * yq/p<CR> xnoremap <silent> # yq?p<CR> " Backspace closes buffer. nnoremap <BS> :Bclose<CR> " Prevent Vim from scrolling original window when splitting horizontally. " See example 'Restoring the View' in Vim manual chapter 41.10. nnoremap <C-W>s Hmx``:split<CR>`xzt`` " Save all buffers when focus lost, ignoring warnings, " and return to normal mode. " " Ideally we'd have: " " autocmd FocusLost * silent! wa stopinsert " " but stopinsert doesn't seem to work inside a FocusLost autocommand. " So we use a long-winded approach instead. " " http://tech.groups.yahoo.com/group/vim/message/94986 autocmd FocusLost * nested silent! wa autocmd FocusLost * if mode()[0] =~ 'i\|R' | call feedkeys("\<Esc>") | endif " Wipe all hidden buffers. command! Only call CloseHiddenBuffers() function! CloseHiddenBuffers() let visible = [] for i in range(1, tabpagenr('$')) call extend(visible, tabpagebuflist(i)) endfor for b in filter(range(1, bufnr('$')), {_,b -> bufloaded(b) && index(visible,b) == -1}) execute 'bw' b endfor endfunction function! Browse(url) if !exists('g:loaded_netrw') runtime! autoload/netrw.vim endif if exists('*netrw#BrowseX') call netrw#BrowseX(a:url, 0) else call netrw#NetrwBrowseX(a:url, 0) endif endfunction nnoremap gb :<C-U>call Browse(expand('<cfile>'))<CR> " " Filetypes " au FileType css setlocal iskeyword+=- au FileType ruby setlocal iskeyword+=_ au BufEnter *.js syn match ErrorMsg /console.log/ au FileType coffee syn match ErrorMsg /console.log/ au FileType ruby syn match ErrorMsg /puts/ au Filetype eruby.yaml,yaml,yml setlocal commentstring=#\ %s au FileType javascript nnoremap <buffer> <leader>L iconsole.log()<Esc> au FileType javascript inoremap <buffer> <leader>L console.log()<Left> au FileType ruby nnoremap <buffer> <leader>L iRails.logger.info("[aws]" )<Esc> au FileType ruby inoremap <buffer> <leader>L Rails.logger.info.("[aws] ")<Left><Left> " " Colours " " hi clear Search " hi Search guifg=#ffffff guibg=#789abc function! s:Pulse() setlocal cursorline redraw sleep 100m setlocal nocursorline redraw sleep 100m setlocal cursorline redraw sleep 100m setlocal nocursorline redraw endfunction autocmd FocusGained * call s:Pulse() " i18n " 'foo' -> t('.') " nmap <Leader>t ysa')it<Esc>f'ci'. iab han human_attribute_name iab mnh model_name.human " syntax checker nnoremap <Leader>s :w \| !sinter %<CR> " " Text objects " " Extra text objects. " Thanks romainl (https://stackoverflow.com/a/44109750) for char in [ '_', '.', ':', ',', ';', '<bar>', '/', '<bslash>', '*', '+', '%', '-', '#' ] execute 'xnoremap i'.char.' :<C-U>normal! T'.char.'vt'.char.'<CR>' execute 'onoremap i'.char.' :normal vi'.char.'<CR>' " The 'around' text objects exclude the end character " (so they work better with lists). execute 'xnoremap a'.char.' :<C-U>normal! F'.char.'vt'.char.'<CR>' execute 'onoremap a'.char.' :normal va'.char.'<CR>' endfor " Narrow word text object: optional upper-case letter followed by lower-case letters " Thanks DJMcMayhem (https://vi.stackexchange.com/a/12491) " Thanks Rich (https://vi.stackexchange.com/a/12502) " On MacVim the forward-search matches are highlighted so turn off the " highlighting. xnoremap in :<C-U>normal! l?\a\l\+?s<C-V><CR>v/\L/s-<C-V><CR>v:nohlsearch<C-V><CR>gv<CR> onoremap in :normal vin<CR> function! s:indentation(inner) let indent = indent(line('.')) if indent == 0 if !empty(getline('.')) return endif let line = line('.') while empty(getline(line)) normal! j let line += 1 endwhile return s:indentation(a:inner) endif let first_line = search('\v^\s{,'.(indent-1).'}\S', 'nWb') + 1 let last_line = search('\v^\s{,'.(indent-1).'}\S', 'nW') - 1 if a:inner while empty(getline(first_line)) let first_line += 1 endwhile while empty(getline(last_line)) let last_line -= 1 endwhile endif " line-wise execute 'normal! '.first_line.'GV'.last_line.'G' endfunction xnoremap <silent> ii :<c-u>call <sid>indentation(1)<cr> onoremap <silent> ii :<c-u>call <sid>indentation(1)<cr> xnoremap <silent> ai :<c-u>call <sid>indentation(0)<cr> onoremap <silent> ai :<c-u>call <sid>indentation(0)<cr> " " Plugins " packadd! matchit " Disable unwanted built-in plugins. let g:loaded_2html_plugin = 1 let g:loaded_getscriptPlugin = 1 let g:loaded_gzip = 1 let g:loaded_netrwPlugin = 1 let g:loaded_rrhelper = 1 let g:loaded_spellfile_plugin = 1 let g:loaded_tarPlugin = 1 let g:loaded_vimballPlugin = 1 let g:loaded_zipPlugin = 1 " Helpful.vim let g:helpful=1 " Any Jump let g:any_jump_results_ui_style = 'filename_last' let g:any_jump_grouping_enabled = 1 " BufExplorer configuration nmap <expr> <script> <silent> <unique> <CR> &buftype ==? '' ? ':BufExplorer<CR>' : '<CR>' let g:bufExplorerDefaultHelp=0 let g:bufExplorerDisableDefaultKeyMapping=1 let g:bufExplorerShowRelativePath=1 let g:bufExplorerShowDirectories=0 let g:bufExplorerShowNoName=1 " vim-gitgutter xmap ghs <Plug>(GitGutterStageHunk) nmap ghs <Plug>(GitGutterStageHunk) nmap ghu <Plug>(GitGutterUndoHunk) nmap ghp <Plug>(GitGutterPreviewHunk) " vim-localorie nnoremap <silent> <leader>lt :call localorie#translate()<CR> nnoremap <silent> <leader>le :echo localorie#expand_key()<CR> autocmd CursorMoved *.yml echo localorie#expand_key() " vim-rooter let g:rooter_patterns = ['!^fixtures','.git'] let g:rooter_change_directory_for_non_project_files = 'current' " vim-surround " Add replacement on # for ruby string interplation. let g:surround_35 = "#{\r}" " Open a gem's homepage in the browser. This is a bit of a hack :/ " TODO: gemfile only " nmap <silent> <Leader>g :call system("open $(gem list -d " . expand('<cword>') . " \| awk '/Homepage/ {print $2}')")<CR> " vim-projectionist let g:projectionist_heuristics = { \ "Gemfile&config/application.rb": { \ "app/models/*.rb": { \ "template": ["class {camelcase|capitalize} < ApplicationRecord", "end"] \ }, \ "app/controllers/*.rb": { \ "template": ["class {camelcase|capitalize} < ApplicationController", "end"], \ }, \ "app/jobs/*.rb": { \ "template": ["class {camelcase|capitalize} < ApplicationJob", "end"], \ "type": "presenter" \ }, \ "app/presenters/*_presenter.rb": { \ "template": ["class {camelcase|capitalize}", "end"], \ "type": "presenter" \ }, \ "app/frontend/styles/*.sass": { \ "type": "sass" \ }, \ "app/frontend/javascripts/controllers/*_controller.js": { \ "type": "stimulus", \ "template": [ \ "import {open} Controller {close} from 'stimulus'", \ "", \ "export default class extends Controller {", \ "", \ " static targets = []", \ "", \ "}"] \ }, \ "config/*": { \ "type": "config" \ }, \ }, \ "plugin/": { \ "plugin/*.vim": { \ "type": "plugin" \ }, \ "autoload/*.vim": { \ "type": "autoload" \ }, \ "doc/*.text": { \ "type": "doc" \ }, \ } \ } " vim-dirvish " sort directories before files, alphabetical let g:dirvish_mode = ':sort /^.*[\/]/' " from dirvish faq augroup my_dirvish_events autocmd! " Map `gh` to hide dotfiles. " To "toggle" this, just press `R` to reload. autocmd FileType dirvish nnoremap <silent><buffer> gh :silent :keeppatterns g@\v/\.[^\/]+/?$@d<cr> autocmd FileType dirvish nnoremap <buffer> + :edit % augroup END " vim-illuminate let g:Illuminate_highlightUnderCursor = 0 let g:Illuminate_delay = 5000 " indentLine let g:indentLine_char = '⋮' " ¦ let g:indentLine_fileType = ['slim', 'sass', 'yml', 'erb'] let g:indentLine_setColors = 0 highlight! link Conceal EndOfBuffer " vim-prettier let g:prettier#autoformat=0 let g:prettier#config#bracket_spacing = 'true' let g:prettier#config#semi = 'false' let g:prettier#config#trailing_comma = 'none' " autocmd BufWritePost *.js,*.json Prettier " Create directories as needed when writing files. autocmd BufWritePre,FileWritePre * silent! call mkdir(expand('<afile>:p:h'), 'p') iab DA DoubleAgent iab FA FreeAgent iab GC GoCardless iab tx transaction let g:dash_scopes = { \ 'ruby': 'r', \ 'javascript': 'js', \ 'css': 'css', \ } command! Dash call SearchDash(g:dash_scopes[&filetype]) function SearchDash(scope) let url = 'dash://'.a:scope.':'.expand('<cword>') call system('open '.url) endfunction " fzf.vim set rtp+=/usr/local/opt/fzf map <leader>f :Files<CR> let g:fzf_preview_window = '' let g:fzf_layout = { 'window': { \ 'width': 0.5, \ 'height': 0.1, \ 'highlight': 'Comment', \ 'border': 'sharp' } } " git-messenger let g:git_messenger_preview_mods = 'botright' " Stop the preview window closing immediately (unexplained interaction with vim-gitgutter): " https://github.com/rhysd/git-messenger.vim/issues/54 let g:git_messenger_close_on_cursor_moved = v:false " vim-test nmap <silent> <Leader>tt :wa\|:TestNearest<CR> nmap <silent> <Leader>tf :wa\|:TestFile<CR> let test#strategy = 'iterm' " basic | vimterminal let g:test#preserve_screen = 1 let g:kite_supported_languages = ['python','javascript','go', 'css', 'html', 'ruby']