fork for IVI
[profile/ivi/vim.git] / runtime / indent / occam.vim
1 " Vim indent file
2 " Language:     occam
3 " Maintainer:   Mario Schweigler <ms44@kent.ac.uk>
4 " Last Change:  23 April 2003
5
6 " Only load this indent file when no other was loaded.
7 if exists("b:did_indent")
8   finish
9 endif
10 let b:did_indent = 1
11
12 "{{{  Settings
13 " Set the occam indent function
14 setlocal indentexpr=GetOccamIndent()
15 " Indent after new line and after initial colon
16 setlocal indentkeys=o,O,0=:
17 "}}}
18
19 " Only define the function once
20 if exists("*GetOccamIndent")
21   finish
22 endif
23
24 "{{{  Indent definitions
25 " Define carriage return indent
26 let s:FirstLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\|PAR\|SEQ\|PRI\s\+PAR\|WHILE\|VALOF\|CLAIM\|FORKING\)\>\|\(--.*\)\@<!\(\<PROC\>\|??\|\<CASE\>\s*\(--.*\)\=\_$\)'
27 let s:FirstLevelNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>'
28 let s:SecondLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\)\>\|\(--.*\)\@<!?\s*\<CASE\>\s*\(--.*\)\=\_$'
29 let s:SecondLevelNonColonEndIndent = '\(--.*\)\@<!\<\(CHAN\|DATA\)\s\+TYPE\>'
30
31 " Define colon indent
32 let s:ColonIndent = '\(--.*\)\@<!\<PROC\>'
33 let s:ColonNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>'
34
35 let s:ColonEnd = '\(--.*\)\@<!:\s*\(--.*\)\=$'
36 let s:ColonStart = '^\s*:\s*\(--.*\)\=$'
37
38 " Define comment
39 let s:CommentLine = '^\s*--'
40 "}}}
41
42 "{{{  function GetOccamIndent()
43 " Auxiliary function to get the correct indent for a line of occam code
44 function GetOccamIndent()
45
46   " Ensure magic is on
47   let save_magic = &magic
48   setlocal magic
49
50   " Get reference line number
51   let linenum = prevnonblank(v:lnum - 1)
52   while linenum > 0 && getline(linenum) =~ s:CommentLine
53     let linenum = prevnonblank(linenum - 1)
54   endwhile
55
56   " Get current indent
57   let curindent = indent(linenum)
58
59   " Get current line
60   let line = getline(linenum)
61
62   " Get previous line number
63   let prevlinenum = prevnonblank(linenum - 1)
64   while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine
65     let prevlinenum = prevnonblank(prevlinenum - 1)
66   endwhile
67
68   " Get previous line
69   let prevline = getline(prevlinenum)
70
71   " Colon indent
72   if getline(v:lnum) =~ s:ColonStart
73
74     let found = 0
75
76     while found < 1
77
78       if line =~ s:ColonStart
79         let found = found - 1
80       elseif line =~ s:ColonIndent || (line =~ s:ColonNonColonEndIndent && line !~ s:ColonEnd)
81         let found = found + 1
82       endif
83
84       if found < 1
85         let linenum = prevnonblank(linenum - 1)
86         if linenum > 0
87           let line = getline(linenum)
88         else
89           let found = 1
90         endif
91       endif
92
93     endwhile
94
95     if linenum > 0
96       let curindent = indent(linenum)
97     else
98       let colonline = getline(v:lnum)
99       let tabstr = ''
100       while strlen(tabstr) < &tabstop
101         let tabstr = ' ' . tabstr
102       endwhile
103       let colonline = substitute(colonline, '\t', tabstr, 'g')
104       let curindent = match(colonline, ':')
105     endif
106
107     " Restore magic
108     if !save_magic|setlocal nomagic|endif
109
110     return curindent
111   endif
112
113   if getline(v:lnum) =~ '^\s*:'
114     let colonline = getline(v:lnum)
115     let tabstr = ''
116     while strlen(tabstr) < &tabstop
117       let tabstr = ' ' . tabstr
118     endwhile
119     let colonline = substitute(colonline, '\t', tabstr, 'g')
120     let curindent = match(colonline, ':')
121
122     " Restore magic
123     if !save_magic|setlocal nomagic|endif
124
125     return curindent
126   endif
127
128   " Carriage return indenat
129   if line =~ s:FirstLevelIndent || (line =~ s:FirstLevelNonColonEndIndent && line !~ s:ColonEnd)
130         \ || (line !~ s:ColonStart && (prevline =~ s:SecondLevelIndent
131         \ || (prevline =~ s:SecondLevelNonColonEndIndent && prevline !~ s:ColonEnd)))
132     let curindent = curindent + &shiftwidth
133
134     " Restore magic
135     if !save_magic|setlocal nomagic|endif
136
137     return curindent
138   endif
139
140   " Commented line
141   if getline(prevnonblank(v:lnum - 1)) =~ s:CommentLine
142
143     " Restore magic
144     if !save_magic|setlocal nomagic|endif
145
146     return indent(prevnonblank(v:lnum - 1))
147   endif
148
149   " Look for previous second level IF / ALT / PRI ALT
150   let found = 0
151
152   while !found
153
154     if indent(prevlinenum) == curindent - &shiftwidth
155       let found = 1
156     endif
157
158     if !found
159       let prevlinenum = prevnonblank(prevlinenum - 1)
160       while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine
161         let prevlinenum = prevnonblank(prevlinenum - 1)
162       endwhile
163       if prevlinenum == 0
164         let found = 1
165       endif
166     endif
167
168   endwhile
169
170   if prevlinenum > 0
171     if getline(prevlinenum) =~ s:SecondLevelIndent
172       let curindent = curindent + &shiftwidth
173     endif
174   endif
175
176   " Restore magic
177   if !save_magic|setlocal nomagic|endif
178
179   return curindent
180
181 endfunction
182 "}}}