diff options
Diffstat (limited to 'runtime/indent/mp.vim')
-rw-r--r-- | runtime/indent/mp.vim | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/runtime/indent/mp.vim b/runtime/indent/mp.vim new file mode 100644 index 000000000..1aea4f809 --- /dev/null +++ b/runtime/indent/mp.vim @@ -0,0 +1,206 @@ +" MetaPost indent file +" Language: MetaPost +" Maintainer: Eugene Minkovskii <emin@mccme.ru> +" Last Change: 2003 Nov 21 +" Version: 0.1 +" ========================================================================== + +" Identation Rules: {{{1 +" First of all, MetaPost language don't expect any identation rules. +" This screept need for you only if you (not MetaPost) need to do +" exactly code. If you don't need to use indentation, see +" :help filetype-indent-off +" +" Note: Every rules of identation in MetaPost or TeX languages (and in some +" other of course) is very subjective. I can release only my vision of this +" promlem. +" +" .......................................................................... +" Example of correct (by me) identation {{{2 +" shiftwidth=4 +" ========================================================================== +" for i=0 upto 99: +" z[i] = (0,1u) rotated (i*360/100); +" endfor +" draw z0 -- z10 -- z20 +" withpen ... % <- 2sw because breaked line +" withcolor ...; % <- same as previous +" draw z0 for i=1 upto 99: +" -- z[i] % <- 1sw from left end of 'for' satement +" endfor withpen ... % <- 0sw from left end of 'for' satement +" withcolor ...; % <- 2sw because breaked line +" draw if One: % <- This is internal if (like 'for' above) +" one +" elsif Other: +" other +" fi withpen ...; +" if one: % <- This is external if +" draw one; +" elseif other: +" draw other; +" fi +" draw z0; draw z1; +" }}} +" }}} + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetMetaPostIndent() +setlocal indentkeys+=;,<:>,=if,=for,=def,=end,=else,=fi + +" Only define the function once. +if exists("*GetMetaPostIndent") + finish +endif + +" Auxiliary Definitions: {{{1 +function! MetaNextNonblankNoncomment(pos) + " Like nextnonblank() but ignore comment lines + let tmp = nextnonblank(a:pos) + while tmp && getline(tmp) =~ '^\s*%' + let tmp = nextnonblank(tmp+1) + endwhile + return tmp +endfunction + +function! MetaPrevNonblankNoncomment(pos) + " Like prevnonblank() but ignore comment lines + let tmp = prevnonblank(a:pos) + while tmp && getline(tmp) =~ '^\s*%' + let tmp = prevnonblank(tmp-1) + endwhile + return tmp +endfunction + +function! MetaSearchNoncomment(pattern, ...) + " Like search() but ignore commented areas + if a:0 + let flags = a:1 + elseif &wrapscan + let flags = "w" + else + let flags = "W" + endif + let cl = line(".") + let cc = col(".") + let tmp = search(a:pattern, flags) + while tmp && synIDattr(synID(line("."), col("."), 1), "name") =~ + \ 'm[fp]\(Comment\|TeXinsert\|String\)' + let tmp = search(a:pattern, flags) + endwhile + if !tmp + call cursor(cl,cc) + endif + return tmp +endfunction +" }}} + +function! GetMetaPostIndent() + " not indent in comment ??? + if synIDattr(synID(line("."), col("."), 1), "name") =~ + \ 'm[fp]\(Comment\|TeXinsert\|String\)' + return -1 + endif + " Some RegExps: {{{1 + " end_of_item: all of end by ';' + " + all of end by :endfor, :enddef, :endfig, :endgroup, :fi + " + all of start by :beginfig(num), :begingroup + " + all of start by :for, :if, :else, :elseif and end by ':' + " + all of start by :def, :vardef and end by '=' + let end_of_item = '\(' . + \ ';\|' . + \ '\<\(end\(for\|def\|fig\|group\)\|fi\)\>\|' . + \ '\<begin\(group\>\|fig\s*(\s*\d\+\s*)\)\|' . + \ '\<\(for\|if\|else\(if\)\=\)\>.\+:\|' . + \ '\<\(var\)\=def\>.\+=' . '\)' + " }}} + " Save: current position {{{1 + let cl = line (".") + let cc = col (".") + let cs = getline(".") + " if it is :beginfig or :endfig use zero indent + if cs =~ '^\s*\(begin\|end\)fig\>' + return 0 + endif + " }}} + " Initialise: ind variable {{{1 + " search previous item not in current line + let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW") + while p_semicol_l == cl + let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW") + endwhile + " if this is first item in program use zero indent + if !p_semicol_l + return 0 + endif + " if this is multiline item, remember first indent + if MetaNextNonblankNoncomment(p_semicol_l+1) < cl + let ind = indent(MetaNextNonblankNoncomment(p_semicol_l+1)) + " else --- search pre-previous item for search first line in previous item + else + " search pre-previous item not in current line + let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW") + while pp_semicol_l == p_semicol_l + let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW") + endwhile + " if we find pre-previous item, remember indent of previous item + " else --- remember zero + if pp_semicol_l + let ind = indent(MetaNextNonblankNoncomment(line(".")+1)) + else + let ind = 0 + endif + endif + " }}} + " Increase Indent: {{{1 + " if it is an internal/external :for or :if statements {{{2 + let pnn_s = getline(MetaPrevNonblankNoncomment(cl-1)) + if pnn_s =~ '\<\(for\|if\)\>.\+:\s*\($\|%\)' + let ind = match(pnn_s, '\<\(for\|if\)\>.\+:\s*\($\|%\)') + &sw + " }}} + " if it is a :def, :vardef, :beginfig, :begingroup, :else, :elseif {{{2 + elseif pnn_s =~ '^\s*\(' . + \ '\(var\)\=def\|' . + \ 'begin\(group\|fig\s*(\s*\d\+\s*)\)\|' . + \ 'else\(if\)\=' . '\)\>' + let ind = ind + &sw + " }}} + " if it is a broken line {{{2 + elseif pnn_s !~ end_of_item.'\s*\($\|%\)' + let ind = ind + (2 * &sw) + endif + " }}} + " }}} + " Decrease Indent: {{{1 + " if this is :endfor or :enddef statements {{{2 + " this is correct because :def cannot be inside :for + if cs =~ '\<end\(for\|def\)\=\>' + call MetaSearchNoncomment('\<for\>.\+:\s*\($\|%\)' . '\|' . + \ '^\s*\(var\)\=def\>',"bW") + if col(".") > 1 + let ind = col(".") - 1 + else + let ind = indent(".") + endif + " }}} + " if this is :fi, :else, :elseif statements {{{2 + elseif cs =~ '\<\(else\(if\)\=\|fi\)\>' + call MetaSearchNoncomment('\<if\>.\+:\s*\($\|%\)',"bW") + let ind = col(".") - 1 + " }}} + " if this is :endgroup statement {{{2 + elseif cs =~ '^\s*endgroup\>' + let ind = ind - &sw + endif + " }}} + " }}} + + return ind +endfunction +" + +" vim:sw=2:fdm=marker |