-
Notifications
You must be signed in to change notification settings - Fork 0
/
tgfIndent.vim
148 lines (127 loc) · 3.48 KB
/
tgfIndent.vim
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
" indent/tgf.vim
setlocal indentexpr=TgfIndent()
setlocal indentkeys==end,=in,=int,=let,=if,e,=then,O,o,0(,0),0{,0}
function! Regexfy(char)
if (a:char =~ '\v[\{\}\(\)]')
return a:char
else
return "\\\<" . a:char . "\\\>"
endif
endfunction
function! IncrementIndent(line)
return indent(a:line) + &shiftwidth
endfunction
function! IsNotOver(lst, times)
let Count = 1
let NotOver = 1
while Count < len(a:lst)
let NotOver = NotOver && (a:times[a:lst[Count-1]] <= a:times[a:lst[Count]])
let Count = Count + 1
endwhile
return NotOver
endfunction
function! FindLast(...)
let pNum = v:lnum
let times = {}
for i in a:000
let times[i] = 0
endfor
while IsNotOver(a:000, times)
let pNum = prevnonblank(pNum-1)
let pLine = getline(pNum)
echom "FindLast(pLine): " . pLine
for i in a:000
if pLine =~ Regexfy(i)
let times[i] = times[i] + 1
echom "times[" . i . "] : " . times[i]
endif
endfor
if pNum == 1
break
endif
endwhile
return pNum
endfunction
function! TgfIndent()
let thisLine = getline(v:lnum)
let synCount = {}
let synCount['let'] = 0
let synCount['in'] = 0
let synCount['end'] = 0
let synCount['if'] = 0
let synCount['then'] = 0
let synCount['else'] = 0
let synCount['var'] = 0
let synCount['function'] = 0
let synCount['type'] = 0
let synCount['{'] = 0
let synCount['}'] = 0
let synCount['('] = 0
let synCount[')'] = 0
let pNum = prevnonblank(v:lnum - 1)
let pLine = getline(pNum)
echom "tL: " . thisLine
echom "pL: " . pLine
" If the current line has any keywords
if (thisLine !~ '\<let\>' && (thisLine =~ '\<in\>' || thisLine =~ '\<end\>'))
let lastN = FindLast('let', 'in', 'end')
return indent(lastN)
endif
if (thisLine !~ '\<if\>' && thisLine =~ '\<else\>')
let lastN = FindLast('if', 'then', 'else')
return indent(lastN)
elseif (thisLine !~ '\<if\>' && thisLine =~ '\<then\>')
return IncrementIndent(FindLast('if', 'then'))
endif
if (thisLine =~ '\v^\ *[\{\(]\ *$')
return indent(pNum)
endif
if (thisLine =~ '\v^\ *\}\ *$')
let lastN = indent(FindLast('{', '}'))
echom "lN: " . lastN
return lastN
endif
if (thisLine =~ '\v^\ *\)\ *$')
return indent(FindLast('(', ')'))
endif
" If the parent line has this specific keywords
if (pLine =~ '\<function\>' && pLine =~ '\v\=\ *$')
return IncrementIndent(pNum)
endif
if (pLine =~ '\<var\>' && pLine =~ '\v\:\=\ *$')
return IncrementIndent(pNum)
endif
if (pLine =~ '\<type\>' && pLine =~ '\v\=\ *$')
return IncrementIndent(pNum)
endif
if (pLine =~ '\<else\>' && pLine =~ '\Velse\ \*\$')
return IncrementIndent(pNum)
endif
if (pLine =~ '{' && pLine !~ '}') || (pLine =~ '(' && pLine !~ ')')
return IncrementIndent(pNum)
endif
" Find where we are
while pNum > 0
for i in keys(synCount)
if pLine =~ Regexfy(i)
let synCount[i] = synCount[i] + 1
endif
endfor
if (synCount['then'] > synCount['else']) || (synCount['if'] > synCount['then'])
return IncrementIndent(pNum)
endif
if (synCount['in'] > synCount['end']) || (synCount['let'] > synCount['in'])
return IncrementIndent(pNum)
endif
if (synCount['('] > synCount[')']) || (synCount['{'] > synCount['}'])
return IncrementIndent(pNum)
endif
if pNum == 1
let pNum = 0
else
let pNum = prevnonblank(pNum - 1)
let pLine = getline(pNum)
endif
endwhile
return 0
endfunction