Mercurial > vim
comparison runtime/indent/sml.vim @ 532:7052f11a3dc9
updated for version 7.0150
author | vimboss |
---|---|
date | Sun, 25 Sep 2005 22:16:38 +0000 |
parents | |
children | 1f3b1021f002 |
comparison
equal
deleted
inserted
replaced
531:da9142bd190a | 532:7052f11a3dc9 |
---|---|
1 " Vim indent file | |
2 " Language: SML | |
3 " Maintainer: Saikat Guha <sg266@cornell.edu> | |
4 " Hubert Chao <hc85@cornell.edu> | |
5 " Original OCaml Version: | |
6 " Jean-Francois Yuen <jfyuen@ifrance.com> | |
7 " Mike Leary <leary@nwlink.com> | |
8 " Markus Mottl <markus@oefai.at> | |
9 " OCaml URL: http://www.oefai.at/~markus/vim/indent/ocaml.vim | |
10 " Last Change: 2003 Jan 04 - Adapted to SML | |
11 " 2002 Nov 06 - Some fixes (JY) | |
12 " 2002 Oct 28 - Fixed bug with indentation of ']' (MM) | |
13 " 2002 Oct 22 - Major rewrite (JY) | |
14 | |
15 " Only load this indent file when no other was loaded. | |
16 if exists("b:did_indent") | |
17 finish | |
18 endif | |
19 let b:did_indent = 1 | |
20 | |
21 setlocal expandtab | |
22 setlocal indentexpr=GetSMLIndent() | |
23 setlocal indentkeys+=0=and,0=else,0=end,0=handle,0=if,0=in,0=let,0=then,0=val,0=fun,0=\|,0=*),0) | |
24 setlocal nolisp | |
25 setlocal nosmartindent | |
26 setlocal textwidth=80 | |
27 setlocal shiftwidth=2 | |
28 | |
29 " Comment formatting | |
30 if (has("comments")) | |
31 set comments=sr:(*,mb:*,ex:*) | |
32 set fo=cqort | |
33 endif | |
34 | |
35 " Only define the function once. | |
36 "if exists("*GetSMLIndent") | |
37 "finish | |
38 "endif | |
39 | |
40 " Define some patterns: | |
41 let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|;\)\s*$' | |
42 let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>' | |
43 let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$' | |
44 let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>' | |
45 let s:module = '\<\%(let\|sig\|struct\)\>' | |
46 let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$' | |
47 let s:type = '^\s*\%(let\|type\)\>.*=' | |
48 let s:val = '^\s*\(val\|external\)\>.*:' | |
49 | |
50 " Skipping pattern, for comments | |
51 function! s:SkipPattern(lnum, pat) | |
52 let def = prevnonblank(a:lnum - 1) | |
53 while def > 0 && getline(def) =~ a:pat | |
54 let def = prevnonblank(def - 1) | |
55 endwhile | |
56 return def | |
57 endfunction | |
58 | |
59 " Indent for ';;' to match multiple 'let' | |
60 function! s:GetInd(lnum, pat, lim) | |
61 let llet = search(a:pat, 'bW') | |
62 let old = indent(a:lnum) | |
63 while llet > 0 | |
64 let old = indent(llet) | |
65 let nb = s:SkipPattern(llet, '^\s*(\*.*\*)\s*$') | |
66 if getline(nb) =~ a:lim | |
67 return old | |
68 endif | |
69 let llet = search(a:pat, 'bW') | |
70 endwhile | |
71 return old | |
72 endfunction | |
73 | |
74 " Indent pairs | |
75 function! s:FindPair(pstart, pmid, pend) | |
76 call search(a:pend, 'bW') | |
77 " return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) | |
78 let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"') | |
79 if lno == -1 | |
80 return indent(lno) | |
81 else | |
82 return col(".") - 1 | |
83 endif | |
84 endfunction | |
85 | |
86 function! s:FindLet(pstart, pmid, pend) | |
87 call search(a:pend, 'bW') | |
88 " return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) | |
89 let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"') | |
90 let moduleLine = getline(lno) | |
91 if lno == -1 || moduleLine =~ '^\s*\(fun\|structure\|signature\)\>' | |
92 return indent(lno) | |
93 else | |
94 return col(".") - 1 | |
95 endif | |
96 endfunction | |
97 | |
98 " Indent 'let' | |
99 "function! s:FindLet(pstart, pmid, pend) | |
100 " call search(a:pend, 'bW') | |
101 " return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ "^\\s*let\\>.*=\\s*$\\|" . s:beflet')) | |
102 "endfunction | |
103 | |
104 function! GetSMLIndent() | |
105 " Find a non-blank line above the current line. | |
106 let lnum = prevnonblank(v:lnum - 1) | |
107 | |
108 " At the start of the file use zero indent. | |
109 if lnum == 0 | |
110 return 0 | |
111 endif | |
112 | |
113 let ind = indent(lnum) | |
114 let lline = getline(lnum) | |
115 | |
116 " Return double 'shiftwidth' after lines matching: | |
117 if lline =~ '^\s*|.*=>\s*$' | |
118 return ind + &sw + &sw | |
119 elseif lline =~ '^\s*val\>.*=\s*$' | |
120 return ind + &sw | |
121 endif | |
122 | |
123 let line = getline(v:lnum) | |
124 | |
125 " Indent lines starting with 'end' to matching module | |
126 if line =~ '^\s*end\>' | |
127 return s:FindLet(s:module, '', '\<end\>') | |
128 | |
129 " Match 'else' with 'if' | |
130 elseif line =~ '^\s*else\>' | |
131 if lline !~ '^\s*\(if\|else\|then\)\>' | |
132 return s:FindPair('\<if\>', '', '\<then\>') | |
133 else return ind | |
134 endif | |
135 | |
136 " Match 'then' with 'if' | |
137 elseif line =~ '^\s*then\>' | |
138 if lline !~ '^\s*\(if\|else\|then\)\>' | |
139 return s:FindPair('\<if\>', '', '\<then\>') | |
140 else return ind | |
141 endif | |
142 | |
143 " Indent if current line begins with ']' | |
144 elseif line =~ '^\s*\]' | |
145 return s:FindPair('\[','','\]') | |
146 | |
147 " Indent current line starting with 'in' to last matching 'let' | |
148 elseif line =~ '^\s*in\>' | |
149 let ind = s:FindLet('\<let\>','','\<in\>') | |
150 | |
151 " Indent from last matching module if line matches: | |
152 elseif line =~ '^\s*\(fun\|val\|open\|structure\|and\|datatype\|type\|exception\)\>' | |
153 cursor(lnum,1) | |
154 let lastModule = indent(searchpair(s:module, '', '\<end\>', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) | |
155 if lastModule == -1 | |
156 return 0 | |
157 else | |
158 return lastModule + &sw | |
159 endif | |
160 | |
161 " Indent lines starting with '|' from matching 'case', 'handle' | |
162 elseif line =~ '^\s*|' | |
163 " cursor(lnum,1) | |
164 let lastSwitch = search('\<\(case\|handle\|fun\|datatype\)\>','bW') | |
165 let switchLine = getline(lastSwitch) | |
166 let switchLineIndent = indent(lastSwitch) | |
167 if lline =~ '^\s*|' | |
168 return ind | |
169 endif | |
170 if switchLine =~ '\<case\>' | |
171 return col(".") + 2 | |
172 elseif switchLine =~ '\<handle\>' | |
173 return switchLineIndent + &sw | |
174 elseif switchLine =~ '\<datatype\>' | |
175 call search('=') | |
176 return col(".") - 1 | |
177 else | |
178 return switchLineIndent + 2 | |
179 endif | |
180 | |
181 | |
182 " Indent if last line ends with 'sig', 'struct', 'let', 'then', 'else', | |
183 " 'in' | |
184 elseif lline =~ '\<\(sig\|struct\|let\|in\|then\|else\)\s*$' | |
185 let ind = ind + &sw | |
186 | |
187 " Indent if last line ends with 'of', align from 'case' | |
188 elseif lline =~ '\<\(of\)\s*$' | |
189 call search('\<case\>',"bW") | |
190 let ind = col(".")+4 | |
191 | |
192 " Indent if current line starts with 'of' | |
193 elseif line =~ '^\s*of\>' | |
194 call search('\<case\>',"bW") | |
195 let ind = col(".")+1 | |
196 | |
197 | |
198 " Indent if last line starts with 'fun', 'case', 'fn' | |
199 elseif lline =~ '^\s*\(fun\|fn\|case\)\>' | |
200 let ind = ind + &sw | |
201 | |
202 endif | |
203 | |
204 " Don't indent 'let' if last line started with 'fun', 'fn' | |
205 if line =~ '^\s*let\>' | |
206 if lline =~ '^\s*\(fun\|fn\)' | |
207 let ind = ind - &sw | |
208 endif | |
209 endif | |
210 | |
211 return ind | |
212 | |
213 endfunction | |
214 | |
215 " vim:sw=2 |