xref: /vim-8.2.3635/runtime/indent/go.vim (revision 3ec574f2)
1" Vim indent file
2" Language:	Go
3" Maintainer:	David Barnett (https://github.com/google/vim-ft-go)
4" Last Change:	2017 Jun 13
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
26function! GoIndent(lnum)
27  let l:prevlnum = prevnonblank(a:lnum-1)
28  if l:prevlnum == 0
29    " top of file
30    return 0
31  endif
32
33  " grab the previous and current line, stripping comments.
34  let l:prevl = substitute(getline(l:prevlnum), '//.*$', '', '')
35  let l:thisl = substitute(getline(a:lnum), '//.*$', '', '')
36  let l:previ = indent(l:prevlnum)
37
38  let l:ind = l:previ
39
40  if l:prevl =~ '[({]\s*$'
41    " previous line opened a block
42    let l:ind += shiftwidth()
43  endif
44  if l:prevl =~# '^\s*\(case .*\|default\):$'
45    " previous line is part of a switch statement
46    let l:ind += shiftwidth()
47  endif
48  " TODO: handle if the previous line is a label.
49
50  if l:thisl =~ '^\s*[)}]'
51    " this line closed a block
52    let l:ind -= shiftwidth()
53  endif
54
55  " Colons are tricky.
56  " We want to outdent if it's part of a switch ("case foo:" or "default:").
57  " We ignore trying to deal with jump labels because (a) they're rare, and
58  " (b) they're hard to disambiguate from a composite literal key.
59  if l:thisl =~# '^\s*\(case .*\|default\):$'
60    let l:ind -= shiftwidth()
61  endif
62
63  return l:ind
64endfunction
65
66" vim: sw=2 sts=2 et
67