3 " Maintainer: Eugene Minkovskii <emin@mccme.ru>
4 " Last Change: 2003 Nov 21
6 " ==========================================================================
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
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
18 " ..........................................................................
19 " Example of correct (by me) identation {{{2
21 " ==========================================================================
23 " z[i] = (0,1u) rotated (i*360/100);
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)
37 " if one: % <- This is external if
46 " Only load this indent file when no other was loaded.
47 if exists("b:did_indent")
52 setlocal indentexpr=GetMetaPostIndent()
53 setlocal indentkeys+=;,<:>,=if,=for,=def,=end,=else,=fi
55 " Only define the function once.
56 if exists("*GetMetaPostIndent")
60 " Auxiliary Definitions: {{{1
61 function! MetaNextNonblankNoncomment(pos)
62 " Like nextnonblank() but ignore comment lines
63 let tmp = nextnonblank(a:pos)
64 while tmp && getline(tmp) =~ '^\s*%'
65 let tmp = nextnonblank(tmp+1)
70 function! MetaPrevNonblankNoncomment(pos)
71 " Like prevnonblank() but ignore comment lines
72 let tmp = prevnonblank(a:pos)
73 while tmp && getline(tmp) =~ '^\s*%'
74 let tmp = prevnonblank(tmp-1)
79 function! MetaSearchNoncomment(pattern, ...)
80 " Like search() but ignore commented areas
90 let tmp = search(a:pattern, flags)
91 while tmp && synIDattr(synID(line("."), col("."), 1), "name") =~
92 \ 'm[fp]\(Comment\|TeXinsert\|String\)'
93 let tmp = search(a:pattern, flags)
102 function! GetMetaPostIndent()
103 " not indent in comment ???
104 if synIDattr(synID(line("."), col("."), 1), "name") =~
105 \ 'm[fp]\(Comment\|TeXinsert\|String\)'
109 " end_of_item: all of end by ';'
110 " + all of end by :endfor, :enddef, :endfig, :endgroup, :fi
111 " + all of start by :beginfig(num), :begingroup
112 " + all of start by :for, :if, :else, :elseif and end by ':'
113 " + all of start by :def, :vardef and end by '='
114 let end_of_item = '\(' .
116 \ '\<\(end\(for\|def\|fig\|group\)\|fi\)\>\|' .
117 \ '\<begin\(group\>\|fig\s*(\s*\d\+\s*)\)\|' .
118 \ '\<\(for\|if\|else\(if\)\=\)\>.\+:\|' .
119 \ '\<\(var\)\=def\>.\+=' . '\)'
121 " Save: current position {{{1
124 let cs = getline(".")
125 " if it is :beginfig or :endfig use zero indent
126 if cs =~ '^\s*\(begin\|end\)fig\>'
130 " Initialise: ind variable {{{1
131 " search previous item not in current line
132 let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
133 while p_semicol_l == cl
134 let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
136 " if this is first item in program use zero indent
140 " if this is multiline item, remember first indent
141 if MetaNextNonblankNoncomment(p_semicol_l+1) < cl
142 let ind = indent(MetaNextNonblankNoncomment(p_semicol_l+1))
143 " else --- search pre-previous item for search first line in previous item
145 " search pre-previous item not in current line
146 let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
147 while pp_semicol_l == p_semicol_l
148 let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
150 " if we find pre-previous item, remember indent of previous item
151 " else --- remember zero
153 let ind = indent(MetaNextNonblankNoncomment(line(".")+1))
159 " Increase Indent: {{{1
160 " if it is an internal/external :for or :if statements {{{2
161 let pnn_s = getline(MetaPrevNonblankNoncomment(cl-1))
162 if pnn_s =~ '\<\(for\|if\)\>.\+:\s*\($\|%\)'
163 let ind = match(pnn_s, '\<\(for\|if\)\>.\+:\s*\($\|%\)') + &sw
165 " if it is a :def, :vardef, :beginfig, :begingroup, :else, :elseif {{{2
166 elseif pnn_s =~ '^\s*\(' .
168 \ 'begin\(group\|fig\s*(\s*\d\+\s*)\)\|' .
169 \ 'else\(if\)\=' . '\)\>'
172 " if it is a broken line {{{2
173 elseif pnn_s !~ end_of_item.'\s*\($\|%\)'
174 let ind = ind + (2 * &sw)
178 " Decrease Indent: {{{1
179 " if this is :endfor or :enddef statements {{{2
180 " this is correct because :def cannot be inside :for
181 if cs =~ '\<end\(for\|def\)\=\>'
182 call MetaSearchNoncomment('\<for\>.\+:\s*\($\|%\)' . '\|' .
183 \ '^\s*\(var\)\=def\>',"bW")
185 let ind = col(".") - 1
187 let ind = indent(".")
190 " if this is :fi, :else, :elseif statements {{{2
191 elseif cs =~ '\<\(else\(if\)\=\|fi\)\>'
192 call MetaSearchNoncomment('\<if\>.\+:\s*\($\|%\)',"bW")
193 let ind = col(".") - 1
195 " if this is :endgroup statement {{{2
196 elseif cs =~ '^\s*endgroup\>'
206 " vim:sw=2:fdm=marker