summaryrefslogtreecommitdiffstats
path: root/indent/vala.vim
blob: 60afaac60fa487e887cbe111fc50acacec42c481 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
if has_key(g:polyglot_is_disabled, 'vala')
  finish
endif

" Vim indent file
" Language:         Vala
" Author:           Adrià Arrufat <adria.arrufat@protonmail.ch>
" Last Change:      2016 Dec 04

" Only load this indent file when no other was loaded.
if exists("b:did_indent")
  finish
endif
let b:did_indent = 1

setlocal cindent
setlocal cinoptions=L0,(0,Ws,J1,j1
setlocal cinkeys=0{,0},!^F,o,O,0[,0]

" Some preliminary settings
setlocal nolisp		" Make sure lisp indenting doesn't supersede us
setlocal autoindent	" indentexpr isn't much help otherwise

setlocal indentexpr=GetValaIndent(v:lnum)

" Only define the function once.
if exists("*GetValaIndent")
  finish
endif

" Come here when loading the script the first time.

function GetValaIndent(lnum)

	" Hit the start of the file, use zero indent.
	if a:lnum == 0
		return 0
	endif

	" Starting assumption: cindent (called at the end) will do it right
	" normally. We just want to fix up a few cases.

	let line = getline(a:lnum)
	" Search backwards for the previous non-empty line.
	let prevlinenum = prevnonblank(a:lnum - 1)
	let prevline = getline(prevlinenum)
	while prevlinenum > 1 && prevline !~ '[^[:blank:]]'
		let prevlinenum = prevnonblank(prevlinenum - 1)
		let prevline = s:getline(prevlinenum)
	endwhile

	" If previous line contains a code attribute (e.g. [CCode (...)])
	" don't increase the indentation
	if prevline =~? '^\s*\[[A-Za-z]' && prevline =~? '\]$'
		return indent(prevlinenum)
	endif

	" cindent gets lambda body wrong, as it treats the comma as indicating an
	" unfinished statement (fix borrowed from rust.vim indent file):
	"
	" list.foreach ((entry) => {
	"		stdout.puts (entry);
	"		stdout.putc ('\n');
	"		if (entry == null) {
	" 		print ("empty entry\n");
	"		}
	" });
	"
	" and we want it to be:
	" list.foreach ((entry) => {
	"	stdout.puts (entry);
	"	stdout.putc ('\n');
	" 	if (entry == null) {
	" 		print ("empty entry\n");
	" 	}
	" });

	if prevline[len(prevline) - 1] == ","
				\ && line !~ '^\s*[\[\]{}]'
				\ && prevline !~ '([^()]\+,$'
				\ && line !~ '^\s*\S\+\s*=>'
		return indent(prevlinenum)
	endif

	" Fall back on cindent, which does it mostly right
	return cindent(a:lnum)
endfunction