1" MetaPost indent file 2" Language: MetaPost 3" Maintainer: Eugene Minkovskii <[email protected]> 4" Last Change: 2012 May 18 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 59let s:keepcpo= &cpo 60set cpo&vim 61 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 208let &cpo = s:keepcpo 209unlet s:keepcpo 210 211" vim:sw=2:fdm=marker 212