1" MetaPost indent file 2" Language: MetaPost 3" Maintainer: Eugene Minkovskii <emin@mccme.ru> 4" Last Change: 2003 Nov 21 5" 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 59 60" Auxiliary Definitions: {{{1 61function! 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) 66 endwhile 67 return tmp 68endfunction 69 70function! 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) 75 endwhile 76 return tmp 77endfunction 78 79function! MetaSearchNoncomment(pattern, ...) 80 " Like search() but ignore commented areas 81 if a:0 82 let flags = a:1 83 elseif &wrapscan 84 let flags = "w" 85 else 86 let flags = "W" 87 endif 88 let cl = line(".") 89 let cc = col(".") 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) 94 endwhile 95 if !tmp 96 call cursor(cl,cc) 97 endif 98 return tmp 99endfunction 100" }}} 101 102function! GetMetaPostIndent() 103 " not indent in comment ??? 104 if synIDattr(synID(line("."), col("."), 1), "name") =~ 105 \ 'm[fp]\(Comment\|TeXinsert\|String\)' 106 return -1 107 endif 108 " Some RegExps: {{{1 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 = '\(' . 115 \ ';\|' . 116 \ '\<\(end\(for\|def\|fig\|group\)\|fi\)\>\|' . 117 \ '\<begin\(group\>\|fig\s*(\s*\d\+\s*)\)\|' . 118 \ '\<\(for\|if\|else\(if\)\=\)\>.\+:\|' . 119 \ '\<\(var\)\=def\>.\+=' . '\)' 120 " }}} 121 " Save: current position {{{1 122 let cl = line (".") 123 let cc = col (".") 124 let cs = getline(".") 125 " if it is :beginfig or :endfig use zero indent 126 if cs =~ '^\s*\(begin\|end\)fig\>' 127 return 0 128 endif 129 " }}} 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") 135 endwhile 136 " if this is first item in program use zero indent 137 if !p_semicol_l 138 return 0 139 endif 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 144 else 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") 149 endwhile 150 " if we find pre-previous item, remember indent of previous item 151 " else --- remember zero 152 if pp_semicol_l 153 let ind = indent(MetaNextNonblankNoncomment(line(".")+1)) 154 else 155 let ind = 0 156 endif 157 endif 158 " }}} 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 164 " }}} 165 " if it is a :def, :vardef, :beginfig, :begingroup, :else, :elseif {{{2 166 elseif pnn_s =~ '^\s*\(' . 167 \ '\(var\)\=def\|' . 168 \ 'begin\(group\|fig\s*(\s*\d\+\s*)\)\|' . 169 \ 'else\(if\)\=' . '\)\>' 170 let ind = ind + &sw 171 " }}} 172 " if it is a broken line {{{2 173 elseif pnn_s !~ end_of_item.'\s*\($\|%\)' 174 let ind = ind + (2 * &sw) 175 endif 176 " }}} 177 " }}} 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") 184 if col(".") > 1 185 let ind = col(".") - 1 186 else 187 let ind = indent(".") 188 endif 189 " }}} 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 194 " }}} 195 " if this is :endgroup statement {{{2 196 elseif cs =~ '^\s*endgroup\>' 197 let ind = ind - &sw 198 endif 199 " }}} 200 " }}} 201 202 return ind 203endfunction 204" 205 206" vim:sw=2:fdm=marker 207