blob: a118eb8b60922f24d2962f80d15e6d8780fa8869 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" MetaPost indent file
2" Language: MetaPost
3" Maintainer: Eugene Minkovskii <emin@mccme.ru>
Bram Moolenaar8e52a592012-05-18 21:49:28 +02004" Last Change: 2012 May 18
Bram Moolenaar071d4272004-06-13 20:20:40 +00005" Version: 0.1
6" ==========================================================================
7
8" Identation Rules: {{{1
9" First of all, MetaPost language don't expect any identation rules.
10" This screept need for you only if you (not MetaPost) need to do
11" exactly code. If you don't need to use indentation, see
12" :help filetype-indent-off
13"
14" Note: Every rules of identation in MetaPost or TeX languages (and in some
15" other of course) is very subjective. I can release only my vision of this
16" promlem.
17"
18" ..........................................................................
19" Example of correct (by me) identation {{{2
20" shiftwidth=4
21" ==========================================================================
22" for i=0 upto 99:
23" z[i] = (0,1u) rotated (i*360/100);
24" endfor
25" draw z0 -- z10 -- z20
26" withpen ... % <- 2sw because breaked line
27" withcolor ...; % <- same as previous
28" draw z0 for i=1 upto 99:
29" -- z[i] % <- 1sw from left end of 'for' satement
30" endfor withpen ... % <- 0sw from left end of 'for' satement
31" withcolor ...; % <- 2sw because breaked line
32" draw if One: % <- This is internal if (like 'for' above)
33" one
34" elsif Other:
35" other
36" fi withpen ...;
37" if one: % <- This is external if
38" draw one;
39" elseif other:
40" draw other;
41" fi
42" draw z0; draw z1;
43" }}}
44" }}}
45
46" Only load this indent file when no other was loaded.
47if exists("b:did_indent")
48 finish
49endif
50let b:did_indent = 1
51
52setlocal indentexpr=GetMetaPostIndent()
53setlocal indentkeys+=;,<:>,=if,=for,=def,=end,=else,=fi
54
55" Only define the function once.
56if exists("*GetMetaPostIndent")
57 finish
58endif
Bram Moolenaar8e52a592012-05-18 21:49:28 +020059let s:keepcpo= &cpo
60set cpo&vim
Bram Moolenaar071d4272004-06-13 20:20:40 +000061
62" Auxiliary Definitions: {{{1
63function! MetaNextNonblankNoncomment(pos)
64 " Like nextnonblank() but ignore comment lines
65 let tmp = nextnonblank(a:pos)
66 while tmp && getline(tmp) =~ '^\s*%'
67 let tmp = nextnonblank(tmp+1)
68 endwhile
69 return tmp
70endfunction
71
72function! MetaPrevNonblankNoncomment(pos)
73 " Like prevnonblank() but ignore comment lines
74 let tmp = prevnonblank(a:pos)
75 while tmp && getline(tmp) =~ '^\s*%'
76 let tmp = prevnonblank(tmp-1)
77 endwhile
78 return tmp
79endfunction
80
81function! MetaSearchNoncomment(pattern, ...)
82 " Like search() but ignore commented areas
83 if a:0
84 let flags = a:1
85 elseif &wrapscan
86 let flags = "w"
87 else
88 let flags = "W"
89 endif
90 let cl = line(".")
91 let cc = col(".")
92 let tmp = search(a:pattern, flags)
93 while tmp && synIDattr(synID(line("."), col("."), 1), "name") =~
94 \ 'm[fp]\(Comment\|TeXinsert\|String\)'
95 let tmp = search(a:pattern, flags)
96 endwhile
97 if !tmp
98 call cursor(cl,cc)
99 endif
100 return tmp
101endfunction
102" }}}
103
104function! GetMetaPostIndent()
105 " not indent in comment ???
106 if synIDattr(synID(line("."), col("."), 1), "name") =~
107 \ 'm[fp]\(Comment\|TeXinsert\|String\)'
108 return -1
109 endif
110 " Some RegExps: {{{1
111 " end_of_item: all of end by ';'
112 " + all of end by :endfor, :enddef, :endfig, :endgroup, :fi
113 " + all of start by :beginfig(num), :begingroup
114 " + all of start by :for, :if, :else, :elseif and end by ':'
115 " + all of start by :def, :vardef and end by '='
116 let end_of_item = '\(' .
117 \ ';\|' .
118 \ '\<\(end\(for\|def\|fig\|group\)\|fi\)\>\|' .
119 \ '\<begin\(group\>\|fig\s*(\s*\d\+\s*)\)\|' .
120 \ '\<\(for\|if\|else\(if\)\=\)\>.\+:\|' .
121 \ '\<\(var\)\=def\>.\+=' . '\)'
122 " }}}
123 " Save: current position {{{1
124 let cl = line (".")
125 let cc = col (".")
126 let cs = getline(".")
127 " if it is :beginfig or :endfig use zero indent
128 if cs =~ '^\s*\(begin\|end\)fig\>'
129 return 0
130 endif
131 " }}}
132 " Initialise: ind variable {{{1
133 " search previous item not in current line
134 let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
135 while p_semicol_l == cl
136 let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
137 endwhile
138 " if this is first item in program use zero indent
139 if !p_semicol_l
140 return 0
141 endif
142 " if this is multiline item, remember first indent
143 if MetaNextNonblankNoncomment(p_semicol_l+1) < cl
144 let ind = indent(MetaNextNonblankNoncomment(p_semicol_l+1))
145 " else --- search pre-previous item for search first line in previous item
146 else
147 " search pre-previous item not in current line
148 let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
149 while pp_semicol_l == p_semicol_l
150 let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
151 endwhile
152 " if we find pre-previous item, remember indent of previous item
153 " else --- remember zero
154 if pp_semicol_l
155 let ind = indent(MetaNextNonblankNoncomment(line(".")+1))
156 else
157 let ind = 0
158 endif
159 endif
160 " }}}
161 " Increase Indent: {{{1
162 " if it is an internal/external :for or :if statements {{{2
163 let pnn_s = getline(MetaPrevNonblankNoncomment(cl-1))
164 if pnn_s =~ '\<\(for\|if\)\>.\+:\s*\($\|%\)'
165 let ind = match(pnn_s, '\<\(for\|if\)\>.\+:\s*\($\|%\)') + &sw
166 " }}}
167 " if it is a :def, :vardef, :beginfig, :begingroup, :else, :elseif {{{2
168 elseif pnn_s =~ '^\s*\(' .
169 \ '\(var\)\=def\|' .
170 \ 'begin\(group\|fig\s*(\s*\d\+\s*)\)\|' .
171 \ 'else\(if\)\=' . '\)\>'
172 let ind = ind + &sw
173 " }}}
174 " if it is a broken line {{{2
175 elseif pnn_s !~ end_of_item.'\s*\($\|%\)'
176 let ind = ind + (2 * &sw)
177 endif
178 " }}}
179 " }}}
180 " Decrease Indent: {{{1
181 " if this is :endfor or :enddef statements {{{2
182 " this is correct because :def cannot be inside :for
183 if cs =~ '\<end\(for\|def\)\=\>'
184 call MetaSearchNoncomment('\<for\>.\+:\s*\($\|%\)' . '\|' .
185 \ '^\s*\(var\)\=def\>',"bW")
186 if col(".") > 1
187 let ind = col(".") - 1
188 else
189 let ind = indent(".")
190 endif
191 " }}}
192 " if this is :fi, :else, :elseif statements {{{2
193 elseif cs =~ '\<\(else\(if\)\=\|fi\)\>'
194 call MetaSearchNoncomment('\<if\>.\+:\s*\($\|%\)',"bW")
195 let ind = col(".") - 1
196 " }}}
197 " if this is :endgroup statement {{{2
198 elseif cs =~ '^\s*endgroup\>'
199 let ind = ind - &sw
200 endif
201 " }}}
202 " }}}
203
204 return ind
205endfunction
206"
207
Bram Moolenaar8e52a592012-05-18 21:49:28 +0200208let &cpo = s:keepcpo
209unlet s:keepcpo
210
Bram Moolenaar071d4272004-06-13 20:20:40 +0000211" vim:sw=2:fdm=marker