Updated runtime files.
diff --git a/runtime/indent/fortran.vim b/runtime/indent/fortran.vim
index 00cced4..c9bee78 100644
--- a/runtime/indent/fortran.vim
+++ b/runtime/indent/fortran.vim
@@ -1,11 +1,12 @@
 " Vim indent file
 " Language:	Fortran 2008 (and older: Fortran 2003, 95, 90, and 77)
-" Version:	0.45
-" Last Change:	2016 Aug. 29
+" Version:	0.46
+" Last Change:	2016 Sep. 27
 " Maintainer:	Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/>
 " Usage:	For instructions, do :help fortran-indent from Vim
 " Credits:
-"  Useful suggestions were made by: Albert Oliver Serra and Takuya Fujiwara.
+"  Useful suggestions were made, in chronological order, by:
+"  Albert Oliver Serra, Takuya Fujiwara and Philipp Edelmann.
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
@@ -121,7 +122,8 @@
     let prefix='\(\(pure\|impure\|elemental\|recursive\)\s\+\)\{,2}'
     let type='\(\(integer\|real\|double\s\+precision\|complex\|logical'
           \.'\|character\|type\|class\)\s*\S*\s\+\)\='
-    if prevstat =~? '^\s*\(module\|contains\/submodule\|program\)\>'
+    if prevstat =~? '^\s*\(contains\|submodule\|program\)\>'
+            \ ||prevstat =~? '^\s*'.'module\>\(\s*\procedure\)\@!'
             \ ||prevstat =~? '^\s*'.prefix.'subroutine\>'
             \ ||prevstat =~? '^\s*'.prefix.type.'function\>'
             \ ||prevstat =~? '^\s*'.type.prefix.'function\>'
@@ -129,7 +131,7 @@
     endif
     if getline(v:lnum) =~? '^\s*contains\>'
           \ ||getline(v:lnum)=~? '^\s*end\s*'
-          \ .'\(function\|subroutine\|module\/submodule\|program\)\>'
+          \ .'\(function\|subroutine\|module\|submodule\|program\)\>'
       let ind = ind - shiftwidth()
     endif
   endif
diff --git a/runtime/indent/mf.vim b/runtime/indent/mf.vim
new file mode 100644
index 0000000..88737f4
--- /dev/null
+++ b/runtime/indent/mf.vim
@@ -0,0 +1,6 @@
+" METAFONT indent file
+" Language:    METAFONT
+" Maintainer:  Nicola Vitacolonna <nvitacolonna@gmail.com>
+" Last Change: 2016 Oct 1
+
+runtime! indent/mp.vim
diff --git a/runtime/indent/mp.vim b/runtime/indent/mp.vim
index a118eb8..c9639ef 100644
--- a/runtime/indent/mp.vim
+++ b/runtime/indent/mp.vim
@@ -1,56 +1,19 @@
 " MetaPost indent file
-" Language:	MetaPost
-" Maintainer:	Eugene Minkovskii <emin@mccme.ru>
-" Last Change:	2012 May 18
-" Version: 0.1
-" ==========================================================================
+" Language:           MetaPost
+" Maintainer:         Nicola Vitacolonna <nvitacolonna@gmail.com>
+" Former Maintainers: Eugene Minkovskii <emin@mccme.ru>
+" Last Change:        2016 Oct 01
+" Version: 0.2
 
-" 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
+setlocal indentkeys+==end,=else,=fi,=fill,0),0]
+
+let b:undo_indent = "setl indentkeys< indentexpr<"
 
 " Only define the function once.
 if exists("*GetMetaPostIndent")
@@ -59,151 +22,332 @@
 let s:keepcpo= &cpo
 set cpo&vim
 
-" 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)
+function GetMetaPostIndent()
+  let ignorecase_save = &ignorecase
+  try
+    let &ignorecase = 0
+    return GetMetaPostIndentIntern()
+  finally
+    let &ignorecase = ignorecase_save
+  endtry
+endfunc
+
+" Regexps {{{
+" Note: the next three variables are made global so that a user may add
+" further keywords.
+"
+" Example:
+"
+"    Put these in ~/.vim/after/indent/mp.vim
+"
+"    let g:mp_open_tag .= '\|\<begintest\>'
+"    let g:mp_close_tag .= '\|\<endtest\>'
+
+" Expressions starting indented blocks
+let g:mp_open_tag = ''
+      \ . '\<if\>'
+      \ . '\|\<else\%[if]\>'
+      \ . '\|\<for\%(\|ever\|suffixes\)\>'
+      \ . '\|\<begingroup\>'
+      \ . '\|\<\%(\|var\|primary\|secondary\|tertiary\)def\>'
+      \ . '\|^\s*\<begin\%(fig\|graph\|glyph\|char\|logochar\)\>'
+      \ . '\|[([{]'
+
+" Expressions ending indented blocks
+let g:mp_close_tag = ''
+      \ . '\<fi\>'
+      \ . '\|\<else\%[if]\>'
+      \ . '\|\<end\%(\|for\|group\|def\|fig\|char\|logochar\|glyph\|graph\)\>'
+      \ . '\|[)\]}]'
+
+" Statements that may span multiple lines and are ended by a semicolon. To
+" keep this list short, statements that are unlikely to be very long or are
+" not very common (e.g., keywords like `interim` or `showtoken`) are not
+" included.
+"
+" The regex for assignments and equations (the last branch) is tricky, because
+" it must not match things like `for i :=`, `if a=b`, `def...=`, etc... It is
+" not perfect, but it works reasonably well.
+let g:mp_statement = ''
+      \ . '\<\%(\|un\|cut\)draw\>'
+      \ . '\|\<\%(\|un\)fill\%[draw]\>'
+      \ . '\|\<draw\%(dbl\)\=arrow\>'
+      \ . '\|\<clip\>'
+      \ . '\|\<addto\>'
+      \ . '\|\<save\>'
+      \ . '\|\<setbounds\>'
+      \ . '\|\<message\>'
+      \ . '\|\<errmessage\>'
+      \ . '\|\<errhelp\>'
+      \ . '\|\<fontmapline\>'
+      \ . '\|\<pickup\>'
+      \ . '\|\<show\>'
+      \ . '\|\<special\>'
+      \ . '\|\<write\>'
+      \ . '\|\%(^\|;\)\%([^;=]*\%('.g:mp_open_tag.'\)\)\@!.\{-}:\=='
+
+" A line ends with zero or more spaces, possibly followed by a comment.
+let s:eol = '\s*\%($\|%\)'
+" }}}
+
+" Auxiliary functions {{{
+" Returns 1 if (0-based) position immediately preceding `pos` in `line` is
+" inside a string or a comment; returns 0 otherwise.
+
+" This is the function that is called more often when indenting, so it is
+" critical that it is efficient. The method we use is significantly faster
+" than using syntax attributes, and more general (it does not require
+" syntax_items). It is also faster than using a single regex matching an even
+" number of quotes. It helps that MetaPost strings cannot span more than one
+" line and cannot contain escaped quotes.
+function! s:CommentOrString(line, pos)
+  let in_string = 0
+  let q = stridx(a:line, '"')
+  let c = stridx(a:line, '%')
+  while q >= 0 && q < a:pos
+    if c >= 0 && c < q
+      if in_string " Find next percent symbol
+        let c = stridx(a:line, '%', q + 1)
+      else " Inside comment
+        return 1
+      endif
+    endif
+    let in_string = 1 - in_string
+    let q = stridx(a:line, '"', q + 1) " Find next quote
   endwhile
-  return tmp
+  return in_string || (c >= 0 && c <= a:pos)
 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)
+" Find the first non-comment non-blank line before the current line. Skip also
+" verbatimtex/btex... etex blocks.
+function! s:PrevNonBlankNonComment(lnum)
+  let l:lnum = prevnonblank(a:lnum - 1)
+  while getline(l:lnum) =~# '^\s*%' ||
+        \ synIDattr(synID(a:lnum, 1, 1), "name") =~# '^mpTeXinsert$\|^tex\|^Delimiter'
+    let l:lnum = prevnonblank(l:lnum - 1)
   endwhile
-  return tmp
+  return l:lnum
 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)
+" Returns true if the last tag appearing in the line is an open tag; returns
+" false otherwise.
+function! s:LastTagIsOpen(line)
+  let o = s:LastValidMatchEnd(a:line, g:mp_open_tag, 0)
+  if o == - 1 | return v:false | endif
+  return s:LastValidMatchEnd(a:line, g:mp_close_tag, o) < 0
+endfunction
+
+" A simple, efficient and quite effective heuristics is used to test whether
+" a line should cause the next line to be indented: count the "opening tags"
+" (if, for, def, ...) in the line, count the "closing tags" (endif, endfor,
+" ...) in the line, and compute the difference. We call the result the
+" "weight" of the line. If the weight is positive, then the next line should
+" most likely be indented. Note that `else` and `elseif` are both opening and
+" closing tags, so they "cancel out" in almost all cases, the only exception
+" being a leading `else[if]`, which is counted as an opening tag, but not as
+" a closing tag (so that, for instance, a line containing a single `else:`
+" will have weight equal to one, not zero). We do not treat a trailing
+" `else[if]` in any special way, because lines ending with an open tag are
+" dealt with separately before this function is called (see
+" GetMetaPostIndentIntern()).
+"
+" Example:
+"
+"     forsuffixes $=a,b: if x.$ = y.$ : draw else: fill fi
+"       % This line will be indented because |{forsuffixes,if,else}| > |{else,fi}| (3 > 2)
+"     endfor
+
+function! s:Weight(line)
+  let [o, i] = [0, s:ValidMatchEnd(a:line, g:mp_open_tag, 0)]
+  while i > 0
+    let o += 1
+    let i = s:ValidMatchEnd(a:line, g:mp_open_tag, i)
   endwhile
-  if !tmp
-    call cursor(cl,cc)
+  let [c, i] = [0, matchend(a:line, '^\s*\<else\%[if]\>')] " Skip a leading else[if]
+  let i = s:ValidMatchEnd(a:line, g:mp_close_tag, i)
+  while i > 0
+    let c += 1
+    let i = s:ValidMatchEnd(a:line, g:mp_close_tag, i)
+  endwhile
+  return o - c
+endfunction
+
+" Similar to matchend(), but skips strings and comments.
+" line: a String
+function! s:ValidMatchEnd(line, pat, start)
+  let i = matchend(a:line, a:pat, a:start)
+  while i > 0 && s:CommentOrString(a:line, i)
+    let i = matchend(a:line, a:pat, i)
+  endwhile
+  return i
+endfunction
+
+" Like s:ValidMatchEnd(), but returns the end position of the last (i.e.,
+" rightmost) match.
+function! s:LastValidMatchEnd(line, pat, start)
+  let last_found = -1
+  let i = matchend(a:line, a:pat, a:start)
+  while i > 0
+    if !s:CommentOrString(a:line, i)
+      let last_found = i
+    endif
+    let i = matchend(a:line, a:pat, i)
+  endwhile
+  return last_found
+endfunction
+
+function! s:DecreaseIndentOnClosingTag(curr_indent)
+  let cur_text = getline(v:lnum)
+  if cur_text =~# '^\s*\%('.g:mp_close_tag.'\)'
+    return max([a:curr_indent - shiftwidth(), 0])
   endif
-  return tmp
+  return a:curr_indent
 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
+" Main function {{{
 "
+" Note: Every rule of indentation in MetaPost is very subjective. We might get
+" creative, but things get murky very soon (there are too many corner cases).
+" So, we provide a means for the user to decide what to do when this script
+" doesn't get it. We use a simple idea: use '%>', '%<' and '%=' to explicitly
+" control indentation. The '<' and '>' symbols may be repeated many times
+" (e.g., '%>>' will cause the next line to be indented twice).
+"
+" By using '%>...', '%<...' and '%=', the indentation the user wants is
+" preserved by commands like gg=G, even if it does not follow the rules of
+" this script.
+"
+" Example:
+"
+"    shiftwidth=4
+"    def foo =
+"        makepen(subpath(T-n,t) of r %>
+"            shifted .5down %>
+"                --subpath(t,T) of r shifted .5up -- cycle) %<<
+"        withcolor black
+"    enddef
+"
+" The default indentation of the previous example would be:
+"
+"    def foo =
+"        makepen(subpath(T-n,t) of r
+"        shifted .5down
+"        --subpath(t,T) of r shifted .5up -- cycle)
+"        withcolor black
+"    enddef
+"
+" Personally, I prefer the latter, but anyway...
+function! GetMetaPostIndentIntern()
+
+  " This is the reference line relative to which the current line is indented
+  " (but see below).
+  let lnum = s:PrevNonBlankNonComment(v:lnum)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  let prev_text = getline(lnum)
+
+  " User-defined overrides take precedence over anything else.
+  " See above for an example.
+  let j = match(prev_text, '%[<>=]')
+  if j > 0
+    let i = strlen(matchstr(prev_text, '%>\+', j)) - 1
+    if i > 0
+      return indent(lnum) + i * shiftwidth()
+    endif
+
+    let i = strlen(matchstr(prev_text, '%<\+', j)) - 1
+    if i > 0
+      return max([indent(lnum) - i * shiftwidth(), 0])
+    endif
+
+    if match(prev_text, '%=', j)
+      return indent(lnum)
+    endif
+  endif
+
+  " If the reference line ends with an open tag, indent.
+  "
+  " Example:
+  "
+  " if c:
+  "     0
+  " else:
+  "     1
+  " fi if c2: % Note that this line has weight equal to zero.
+  "     ...   % This line will be indented
+  if s:LastTagIsOpen(prev_text)
+    return s:DecreaseIndentOnClosingTag(indent(lnum) + shiftwidth())
+  endif
+
+  " Lines with a positive weight are unbalanced and should likely be indented.
+  "
+  " Example:
+  "
+  " def f = enddef for i = 1 upto 5: if x[i] > 0: 1 else: 2 fi
+  "     ... % This line will be indented (because of the unterminated `for`)
+  if s:Weight(prev_text) > 0
+    return s:DecreaseIndentOnClosingTag(indent(lnum) + shiftwidth())
+  endif
+
+  " Unterminated statements cause indentation to kick in.
+  "
+  " Example:
+  "
+  " draw unitsquare
+  "     withcolor black; % This line is indented because of `draw`.
+  " x := a + b + c
+  "     + d + e;         % This line is indented because of `:=`.
+  "
+  let i = s:LastValidMatchEnd(prev_text, g:mp_statement, 0)
+  if i >= 0 " Does the line contain a statement?
+    if s:ValidMatchEnd(prev_text, ';', i) < 0 " Is the statement unterminated?
+      return indent(lnum) + shiftwidth()
+    else
+      return s:DecreaseIndentOnClosingTag(indent(lnum))
+    endif
+  endif
+
+  " Deal with the special case of a statement spanning multiple lines. If the
+  " current reference line L ends with a semicolon, search backwards for
+  " another semicolon or a statement keyword. If the latter is found first,
+  " its line is used as the reference line for indenting the current line
+  " instead of L.
+  "
+  "  Example:
+  "
+  "  if cond:
+  "    draw if a: z0 else: z1 fi
+  "        shifted S
+  "        scaled T;      % L
+  "
+  "    for i = 1 upto 3:  % <-- Current line: this gets the same indent as `draw ...`
+  "
+  " NOTE: we get here if and only if L does not contain a statement (among
+  " those listed in g:mp_statement).
+  if s:ValidMatchEnd(prev_text, ';'.s:eol, 0) >= 0 " L ends with a semicolon
+    let stm_lnum = s:PrevNonBlankNonComment(lnum)
+    while stm_lnum > 0
+      let prev_text = getline(stm_lnum)
+      let sc_pos = s:LastValidMatchEnd(prev_text, ';', 0)
+      let stm_pos = s:ValidMatchEnd(prev_text, g:mp_statement, sc_pos)
+      if stm_pos > sc_pos
+        let lnum = stm_lnum
+        break
+      elseif sc_pos > stm_pos
+        break
+      endif
+      let stm_lnum = s:PrevNonBlankNonComment(stm_lnum)
+    endwhile
+  endif
+
+  return s:DecreaseIndentOnClosingTag(indent(lnum))
+endfunction
+" }}}
 
 let &cpo = s:keepcpo
 unlet s:keepcpo