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
88
89
90
91
92
93
94
95
96
97
98
99
|
" Vim Indentation file
" Language: Myrddin
" Maintainer: Ori Bernstein
if exists("b:did_indent")
finish
endif
function! Quoted(lnum, col)
let stk = synstack(a:lnum, a:col)
for id in stk
let a = synIDattr(id, "name")
if a == "myrComment" || a == "myrString" || a == "myrChar"
return 1
endif
endfor
return 0
endfunction
function! s:CountMatches(line, lnum, pats)
let matches = 0
for p in a:pats
let idx = 0
while idx >= 0
let idx = match(a:line, p, idx)
if idx >= 0
let ic = Quoted(a:lnum, idx+1)
if !ic
let matches = matches + 1
endif
let idx = idx + strlen(p)
endif
endwhile
endfor
return matches
endfunction
function! s:LineMatch(line, pats)
for p in a:pats
let pat = '^\s*'.p.'\s*$'
if match(a:line, pat, 0) >= 0
return 1
endif
endfor
return 0
endfunction
function! GetMyrIndent(ln)
let ln = a:ln
if ln == 1
let ind = 0
else
let i = 1
let prevln = ''
while prevln =~ '^\s*$'
let prevln = getline(ln - i)
let ind = indent(ln - i)
let i = i + 1
endwhile
let i = i - 1
let curln = getline(ln)
let inpat = ['\<if\>', '\<elif\>', '\<else\>',
\ '\<while\>','\<for\>', '\<match\>',
\ '\<struct\>', '\<union\>',
\ '{', '\[', '(', '^\s*|', '=\s*$']
let outpat = ['}', ']', '(', ';;']
let outalone = ['\<else\>', '\<elif\>.*', ';;', '|.*',
\ '].*', ').*', '}.*']
let width = &tabstop
let n_in = s:CountMatches(prevln, ln - i, inpat)
let n_out = s:CountMatches(prevln, ln - i, outpat)
" indent escaped line endings
if prevln =~ '\\\s*$' && getline(ln - i - 1) !~ '\\\s*$'
let n_in = n_in + 1
endif
" if we break the set of indented line endings, outdent
if getline(ln - i - 1) =~ '\\\s*$' && getline(ln - i) !~ '\\\s*$'
let n_out = n_out + 1
endif
" avoid double counting outdents that are also outalone
if s:CountMatches(curln, ln, inpat) == 0 && s:LineMatch(prevln, outalone) != 0
let n_out = n_out - 1
endif
let n_out = n_out + s:LineMatch(curln, outalone)
let ind = ind + (n_in - n_out) * &tabstop
endif
return ind
endfunction
setlocal indentkeys+=,;\|],=elif
setlocal indentexpr=GetMyrIndent(v:lnum)
let b:did_indent = 1
|