1" Vim indent file 2" Language: Go 3" Maintainer: David Barnett (https://github.com/google/vim-ft-go) 4" Last Change: 2014 Aug 16 5" 6" TODO: 7" - function invocations split across lines 8" - general line splits (line ends in an operator) 9 10if exists('b:did_indent') 11 finish 12endif 13let b:did_indent = 1 14 15" C indentation is too far off useful, mainly due to Go's := operator. 16" Let's just define our own. 17setlocal nolisp 18setlocal autoindent 19setlocal indentexpr=GoIndent(v:lnum) 20setlocal indentkeys+=<:>,0=},0=) 21 22if exists('*GoIndent') 23 finish 24endif 25 26" The shiftwidth() function is relatively new. 27" Don't require it to exist. 28if exists('*shiftwidth') 29 function s:sw() abort 30 return shiftwidth() 31 endfunction 32else 33 function s:sw() abort 34 return &shiftwidth 35 endfunction 36endif 37 38function! GoIndent(lnum) 39 let l:prevlnum = prevnonblank(a:lnum-1) 40 if l:prevlnum == 0 41 " top of file 42 return 0 43 endif 44 45 " grab the previous and current line, stripping comments. 46 let l:prevl = substitute(getline(l:prevlnum), '//.*$', '', '') 47 let l:thisl = substitute(getline(a:lnum), '//.*$', '', '') 48 let l:previ = indent(l:prevlnum) 49 50 let l:ind = l:previ 51 52 if l:prevl =~ '[({]\s*$' 53 " previous line opened a block 54 let l:ind += s:sw() 55 endif 56 if l:prevl =~# '^\s*\(case .*\|default\):$' 57 " previous line is part of a switch statement 58 let l:ind += s:sw() 59 endif 60 " TODO: handle if the previous line is a label. 61 62 if l:thisl =~ '^\s*[)}]' 63 " this line closed a block 64 let l:ind -= s:sw() 65 endif 66 67 " Colons are tricky. 68 " We want to outdent if it's part of a switch ("case foo:" or "default:"). 69 " We ignore trying to deal with jump labels because (a) they're rare, and 70 " (b) they're hard to disambiguate from a composite literal key. 71 if l:thisl =~# '^\s*\(case .*\|default\):$' 72 let l:ind -= s:sw() 73 endif 74 75 return l:ind 76endfunction 77 78" vim: sw=2 sts=2 et 79