Update runtime files.
diff --git a/runtime/ftplugin/gprof.vim b/runtime/ftplugin/gprof.vim
index 750751c..d4547ae 100644
--- a/runtime/ftplugin/gprof.vim
+++ b/runtime/ftplugin/gprof.vim
@@ -1,6 +1,6 @@
 " Language:    gprof
 " Maintainer:  Dominique Pelle <dominique.pelle@gmail.com>
-" Last Change: 2013 Jun 09
+" Last Change: 2021 Apr 08
 
 " When cursor is on one line of the gprof call graph,
 " calling this function jumps to this function in the call graph.
@@ -16,7 +16,7 @@
     norm! $y%
     call search('^' . escape(@", '[]'), 'sw')
     norm! zz
-  elseif l:line =~ '^\(\s\+[0-9\.]\+\)\{3}\s\+'
+  elseif l:line =~ '^\(\s*[0-9\.]\+\)\{3}\s\+'
     " We're in line in the flat profile.
     norm! 55|eby$
     call search('^\[\d\+\].*\d\s\+' .  escape(@", '[]*.') . '\>', 'sW')
diff --git a/runtime/ftplugin/m3build.vim b/runtime/ftplugin/m3build.vim
new file mode 100644
index 0000000..9e1e169
--- /dev/null
+++ b/runtime/ftplugin/m3build.vim
@@ -0,0 +1,24 @@
+" Vim filetype plugin file
+" Language:	Modula-3 Makefile
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2021 April 15
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+runtime! ftplugin/m3quake.vim
+
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+  let b:browsefilter = "Modula-3 Makefile (m3makefile m3overrides)\tm3makefile;m3overrides\n" ..
+	\	       "All Files (*.*)\t*.*\n"
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet:
diff --git a/runtime/ftplugin/m3quake.vim b/runtime/ftplugin/m3quake.vim
new file mode 100644
index 0000000..627aabd
--- /dev/null
+++ b/runtime/ftplugin/m3quake.vim
@@ -0,0 +1,33 @@
+" Vim filetype plugin file
+" Language:	Modula-3 Quake
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2021 April 15
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal comments=s1:/*,mb:*,ex:*/,:%
+setlocal commentstring=%\ %s
+setlocal formatoptions-=t formatoptions+=croql
+
+if exists("loaded_matchit") && !exists("b:match_words")
+  let b:match_words = '\<\%(proc\|if\|foreach\)\>:\<else\>:\<end\>'
+endif
+
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+  let b:browsefilter = "Modula-3 Quake Source Files (*.quake)\t*.quake\n" ..
+	\	       "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl fo< com< cms< " ..
+      \		      "| unlet! b:browsefilter b:match_words"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet:
diff --git a/runtime/ftplugin/modula2.vim b/runtime/ftplugin/modula2.vim
new file mode 100644
index 0000000..1d0e81e
--- /dev/null
+++ b/runtime/ftplugin/modula2.vim
@@ -0,0 +1,39 @@
+" Vim filetype plugin file
+" Language:	Modula-2
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2021 Apr 08
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal comments=s0:(*,mb:\ ,ex:*)
+setlocal commentstring=(*%s*)
+setlocal formatoptions-=t formatoptions+=croql
+
+if exists("loaded_matchit") && !exists("b:match_words")
+  " The second branch of the middle pattern is intended to match CASE labels
+  let b:match_words = '\<REPEAT\>:\<UNTIL\>,' ..
+		    \ '\<\%(BEGIN\|CASE\|FOR\|IF\|LOOP\|WHILE\|WITH\)\>' ..
+		    \	':' ..
+		    \	'\<\%(ELSIF\|ELSE\)\>\|\%(^\s*\)\@<=\w\+\%(\s*\,\s*\w\+\)\=\s*\:=\@!' ..
+		    \	':' ..
+		    \ '\<END\>'
+endif
+
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+  let b:browsefilter = "Modula-2 Source Files (*.def *.mod)\t*.def;*.mod\n" ..
+		     \ "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl com< cms< fo< " ..
+		    \ "| unlet! b:browsefilter b:match_words"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet:
diff --git a/runtime/ftplugin/modula3.vim b/runtime/ftplugin/modula3.vim
new file mode 100644
index 0000000..fc9eb57
--- /dev/null
+++ b/runtime/ftplugin/modula3.vim
@@ -0,0 +1,38 @@
+" Vim filetype plugin file
+" Language:	Modula-3
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2021 Apr 08
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal comments=s0:(*,mb:\ ,ex:*)
+setlocal commentstring=(*%s*)
+setlocal formatoptions-=t formatoptions+=croql
+
+if exists("loaded_matchit") && !exists("b:match_words")
+  let b:match_words = '\<REPEAT\>:\<UNTIL\>,' ..
+		    \ '\<\%(BEGIN\|CASE\|FOR\|IF\|LOCK\|LOOP\|TRY\|TYPECASE\|WHILE\|WITH\)\>' ..
+		    \	':' ..
+		    \	'\<\%(ELSIF\|ELSE\|EXCEPT\|FINALLY\)\>\|\%(^\s*\)\@<=\S.*=>' ..
+		    \	':' ..
+		    \ '\<END\>'
+endif
+
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+  let b:browsefilter = "Modula-3 Source Files (*.m3)\t*.m3\n" ..
+		     \ "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl com< cms< fo< " ..
+		    \ "| unlet! b:browsefilter b:match_words"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet:
diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim
index 746e80b..98c94cc 100644
--- a/runtime/ftplugin/vim.vim
+++ b/runtime/ftplugin/vim.vim
@@ -1,7 +1,7 @@
 " Vim filetype plugin
 " Language:	Vim
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2021 Feb 20
+" Last Change:	2021 Apr 11
 
 " Only do this when not done yet for this buffer
 if exists("b:did_ftplugin")
@@ -94,11 +94,11 @@
   "   func name
   " require a parenthesis following, then there can be an "endfunc".
   let b:match_words =
-	\ '\<\%(fu\%[nction]\|def\)!\=\s\+\S\+(:\<retu\%[rn]\>:\<\%(endf\%[unction]\|enddef\)\>,' .
- 	\ '\<\(wh\%[ile]\|for\)\>:\<brea\%[k]\>:\<con\%[tinue]\>:\<end\(w\%[hile]\|fo\%[r]\)\>,' .
-	\ '\<if\>:\<el\%[seif]\>:\<en\%[dif]\>,' .
+	\ '\<\%(fu\%[nction]\|def\)!\=\s\+\S\+(:\%(\%(^\||\)\s*\)\@<=\<retu\%[rn]\>:\%(\%(^\||\)\s*\)\@<=\<\%(endf\%[unction]\|enddef\)\>,' .
+ 	\ '\<\(wh\%[ile]\|for\)\>:\%(\%(^\||\)\s*\)\@<=\<brea\%[k]\>:\%(\%(^\||\)\s*\)\@<=\<con\%[tinue]\>:\%(\%(^\||\)\s*\)\@<=\<end\(w\%[hile]\|fo\%[r]\)\>,' .
+	\ '\<if\>:\%(\%(^\||\)\s*\)\@<=\<el\%[seif]\>:\%(\%(^\||\)\s*\)\@<=\<en\%[dif]\>,' .
 	\ '{:},' .
-	\ '\<try\>:\<cat\%[ch]\>:\<fina\%[lly]\>:\<endt\%[ry]\>,' .
+	\ '\<try\>:\%(\%(^\||\)\s*\)\@<=\<cat\%[ch]\>:\%(\%(^\||\)\s*\)\@<=\<fina\%[lly]\>:\%(\%(^\||\)\s*\)\@<=\<endt\%[ry]\>,' .
 	\ '\<aug\%[roup]\s\+\%(END\>\)\@!\S:\<aug\%[roup]\s\+END\>,'
   " Ignore syntax region commands and settings, any 'en*' would clobber
   " if-endif.