changeset 27459:5825405e4e2c

Update runtime files Commit: https://github.com/vim/vim/commit/f10911e5db16f1fe6ab519c5d091ad0c1df0d063 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 29 22:20:48 2022 +0000 Update runtime files
author Bram Moolenaar <Bram@vim.org>
date Sat, 29 Jan 2022 23:30:04 +0100
parents 2a7fc102cb91
children b7ed275ef02f
files .github/CODEOWNERS runtime/autoload/dist/ft.vim runtime/autoload/freebasic.vim runtime/doc/builtin.txt runtime/doc/change.txt runtime/doc/eval.txt runtime/doc/if_perl.txt runtime/doc/index.txt runtime/doc/message.txt runtime/doc/options.txt runtime/doc/print.txt runtime/doc/tags runtime/doc/testing.txt runtime/doc/todo.txt runtime/doc/usr_41.txt runtime/doc/vim9.txt runtime/filetype.vim runtime/ftplugin/basic.vim runtime/ftplugin/freebasic.vim runtime/ftplugin/qb64.vim runtime/indent/basic.vim runtime/indent/freebasic.vim runtime/indent/qb64.vim runtime/pack/dist/opt/matchit/autoload/matchit.vim runtime/syntax/basic.vim runtime/syntax/qb64.vim runtime/syntax/strace.vim src/testdir/README.txt
diffstat 28 files changed, 1156 insertions(+), 251 deletions(-) [+]
line wrap: on
line diff
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -9,6 +9,7 @@
 # So if a pull request only touches javascript files, only these owners
 # will be requested to review.
 
+runtime/autoload/freebasic.vim		@dkearns
 runtime/autoload/getscript.vim		@cecamp
 runtime/autoload/netrw.vim		@cecamp
 runtime/autoload/netrwFileHandlers.vim	@cecamp
@@ -111,6 +112,7 @@ runtime/ftplugin/pbtxt.vim		@lakshayg
 runtime/ftplugin/pdf.vim		@tpope
 runtime/ftplugin/ps1.vim		@heaths
 runtime/ftplugin/ps1xml.vim		@heaths
+runtime/ftplugin/qb64.vim		@dkearns
 runtime/ftplugin/routeros.vim		@zainin
 runtime/ftplugin/ruby.vim		@tpope @dkearns
 runtime/ftplugin/sass.vim		@tpope
@@ -126,6 +128,7 @@ runtime/ftplugin/typescript.vim		@dkearn
 runtime/ftplugin/typescriptreact.vim	@dkearns
 runtime/ftplugin/xml.vim		@chrisbra
 runtime/ftplugin/zsh.vim		@chrisbra
+runtime/indent/basic.vim		@dkearns
 runtime/indent/bst.vim			@tpope
 runtime/indent/cdl.vim			@dkearns
 runtime/indent/clojure.vim		@axvr
@@ -140,6 +143,7 @@ runtime/indent/elm.vim			@andys8
 runtime/indent/eruby.vim		@tpope @dkearns
 runtime/indent/eterm.vim		@dkearns
 runtime/indent/framescript.vim		@dkearns
+runtime/indent/freebasic.vim		@dkearns
 runtime/indent/gitconfig.vim		@tpope
 runtime/indent/haml.vim			@tpope
 runtime/indent/idlang.vim		@dkearns
@@ -154,6 +158,7 @@ runtime/indent/occam.vim		@dkearns
 runtime/indent/postscr.vim		@dkearns
 runtime/indent/prolog.vim		@dkearns
 runtime/indent/ps1.vim			@heaths
+runtime/indent/qb64.vim			@dkearns
 runtime/indent/readline.vim		@dkearns
 runtime/indent/ruby.vim			@AndrewRadev @dkearns
 runtime/indent/sass.vim			@tpope
@@ -239,6 +244,7 @@ runtime/syntax/prolog.vim		@XVilka
 runtime/syntax/ps1.vim			@heaths
 runtime/syntax/ps1xml.vim		@heaths
 runtime/syntax/psl.vim			@danielkho
+runtime/syntax/qb64.vim			@dkearns
 runtime/syntax/rc.vim			@chrisbra
 runtime/syntax/routeros.vim		@zainin
 runtime/syntax/rpcgen.vim		@cecamp
--- a/runtime/autoload/dist/ft.vim
+++ b/runtime/autoload/dist/ft.vim
@@ -1,7 +1,7 @@
 " Vim functions for file type detection
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2022 Jan 11
+" Last Change:	2022 Jan 28
 
 " These functions are moved here from runtime/filetype.vim to make startup
 " faster.
new file mode 100644
--- /dev/null
+++ b/runtime/autoload/freebasic.vim
@@ -0,0 +1,41 @@
+" Vim filetype plugin file
+" Language:	FreeBASIC
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2021 Mar 16
+
+" Dialects can be one of fb, qb, fblite, or deprecated
+" Precedence is forcelang > #lang > lang
+function! freebasic#GetDialect() abort
+  if exists("g:freebasic_forcelang")
+    return g:freebasic_forcelang
+  endif
+
+  if exists("g:freebasic_lang")
+    let dialect = g:freebasic_lang
+  else
+    let dialect = "fb"
+  endif
+
+  " override with #lang directive or metacommand
+
+  let skip = "has('syntax_items') && synIDattr(synID(line('.'), col('.'), 1), 'name') =~ 'Comment$'"
+  let pat = '\c^\s*\%(#\s*lang\s\+\|''\s*$lang\s*:\s*\)"\([^"]*\)"'
+
+  let save_cursor = getcurpos()
+  call cursor(1, 1)
+  let lnum = search(pat, 'n', '', '', skip)
+  call setpos('.', save_cursor)
+
+  if lnum
+    let word = matchlist(getline(lnum), pat)[1]
+    if word =~? '\%(fb\|deprecated\|fblite\|qb\)'
+      let dialect = word
+    else
+      echomsg "freebasic#GetDialect: Invalid lang, found '" .. word .. "' at line " .. lnum .. " " .. getline(lnum)
+    endif
+  endif
+
+  return dialect
+endfunction
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*	For Vim version 8.2.  Last change: 2022 Jan 22
+*builtin.txt*	For Vim version 8.2.  Last change: 2022 Jan 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -2086,6 +2086,22 @@ exists({expr})	The result is a Number, w
 		For checking if a file exists use |filereadable()|.
 
 		The {expr} argument is a string, which contains one of these:
+			varname		internal variable (see
+			dict.key	|internal-variables|).  Also works
+			list[i]		for |curly-braces-names|, |Dictionary|
+			import.Func	entries, |List| items, imported
+					items,etc.
+					Does not work for local variables in a
+					compiled `:def` function.
+					Beware that evaluating an index may
+					cause an error message for an invalid
+					expression.  E.g.: >
+					   :let l = [1, 2, 3]
+					   :echo exists("l[5]")
+<					   0 >
+					   :echo exists("l[xx]")
+<					   E121: Undefined variable: xx
+					   0
 			&option-name	Vim option (only checks if it exists,
 					not if it really works)
 			+option-name	Vim option that works.
@@ -2100,21 +2116,6 @@ exists({expr})	The result is a Number, w
 			?funcname	built-in function that could be
 					implemented; to be used to check if
 					"funcname" is valid
-			varname		internal variable (see
-					|internal-variables|).  Also works
-					for |curly-braces-names|, |Dictionary|
-					entries, |List| items, etc.
-					Does not work for local variables in a
-					compiled `:def` function.
-					Beware that evaluating an index may
-					cause an error message for an invalid
-					expression.  E.g.: >
-					   :let l = [1, 2, 3]
-					   :echo exists("l[5]")
-<					   0 >
-					   :echo exists("l[xx]")
-<					   E121: Undefined variable: xx
-					   0
 			:cmdname	Ex command: built-in command, user
 					command or command modifier |:command|.
 					Returns:
@@ -2539,7 +2540,7 @@ flatten({list} [, {maxdepth}])					*flat
 		The {list} is changed in place, use |flattennew()| if you do
 		not want that.
 		In Vim9 script flatten() cannot be used, you must always use
-		|flattennew()|.
+		|flattennew()|. *E1158*
 								*E900*
 		{maxdepth} means how deep in nested lists changes are made.
 		{list} is not modified when {maxdepth} is 0.
@@ -6540,7 +6541,7 @@ reduce({object}, {func} [, {initial}])		
 		{func} is called for every item in {object}, which can be a
 		|String|, |List| or a |Blob|.  {func} is called with two
 		arguments: the result so far and current item.  After
-		processing all items the result is returned.
+		processing all items the result is returned. *E1132*
 
 		{initial} is the initial result.  When omitted, the first item
 		in {object} is used and {func} is first called for the second
@@ -7399,7 +7400,7 @@ setcellwidths({list})					*setcellwidths
 		   setcellwidths([[0xad, 0xad, 1],
 				\ [0x2194, 0x2199, 2]])
 
-<					*E1109* *E1110* *E1111* *E1112* *E1113*
+<				*E1109* *E1110* *E1111* *E1112* *E1113* *E1114*
 		The {list} argument is a list of lists with each three
 		numbers. These three numbers are [low, high, width].  "low"
 		and "high" can be the same, in which case this refers to one
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt*    For Vim version 8.2.  Last change: 2021 Dec 29
+*change.txt*    For Vim version 8.2.  Last change: 2022 Jan 28
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1176,10 +1176,13 @@ register.  With blockwise selection it a
 and whether the corners are on an existing character.  (Implementation detail:
 it actually works by first putting the register after the selection and then
 deleting the selection.)
-The previously selected text is put in the unnamed register.  If you want to
-put the same text into a Visual selection several times you need to use
+With 'p' the previously selected text is put in the unnamed register.  This is
+useful if you want to put that text somewhere else.  But you cannot repeat the
+same change.
+With 'P' the unnamed register is not changed, you can repeat the same change.
+But the deleted text cannot be used.  If you do need it you can use 'p' with
 another register.  E.g., yank the text to copy, Visually select the text to
-replace and use "0p .  You can repeat this as many times as you like, the
+replace and use "0p .  You can repeat this as many times as you like, and the
 unnamed register will be changed each time.
 
 When you use a blockwise Visual mode command and yank only a single line into
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*	For Vim version 8.2.  Last change: 2022 Jan 21
+*eval.txt*	For Vim version 8.2.  Last change: 2022 Jan 24
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -44,7 +44,8 @@ Profiling is documented at |profiling|.
 1. Variables						*variables*
 
 1.1 Variable types ~
-						*E712* *E896* *E897* *E899*
+					*E712* *E896* *E897* *E899* *E1098*
+					*E1107* *E1135* *E1138*
 There are ten types of variables:
 
 							*Number* *Integer*
@@ -180,7 +181,7 @@ You will not get an error if you try to 
 
 
 1.2 Function references ~
-						*Funcref* *E695* *E718*
+					*Funcref* *E695* *E718* *E1086*
 A Funcref variable is obtained with the |function()| function, the |funcref()|
 function or created with the lambda expression |expr-lambda|.  It can be used
 in an expression in the place of a function name, before the parenthesis
@@ -835,7 +836,7 @@ In legacy script it is possible to form 
 
 ==============================================================================
 2. Expression syntax					*expression-syntax*
-
+							*E1143*
 Expression syntax summary, from least to most significant:
 
 |expr1|	expr2
@@ -916,6 +917,9 @@ Example: >
 
 All expressions within one level are parsed from left to right.
 
+Expression nesting is limited to 1000 levels deep (300 when build with MSVC)
+to avoid running out of stack and crashing. *E1169*
+
 
 expr1				*expr1* *trinary* *falsy-operator* *??* *E109*
 -----
@@ -1339,7 +1343,7 @@ Note that the dot is also used for Strin
 always put spaces around the dot for String concatenation.
 
 
-expr9(expr1, ...)	|Funcref| function call
+expr9(expr1, ...)	|Funcref| function call  	*E1085*
 
 When expr9 is a |Funcref| type variable, invoke the function it refers to.
 
@@ -1577,7 +1581,7 @@ The first one probably doesn't echo anyt
 variable (if your shell supports it).
 
 
-internal variable				*expr-variable* *E1015*
+internal variable			*expr-variable* *E1015* *E1089*
 -----------------
 variable		internal variable
 See below |internal-variables|.
@@ -2709,7 +2713,7 @@ See |:verbose-cmd| for more information.
 			command, use line breaks instead of |:bar|: >
 				:exe "func Foo()\necho 'foo'\nendfunc"
 <
-				*:delf* *:delfunction* *E131* *E933*
+				*:delf* *:delfunction* *E131* *E933* *E1084*
 :delf[unction][!] {name}
 			Delete function {name}.
 			{name} can also be a |Dictionary| entry that is a
@@ -2726,8 +2730,11 @@ See |:verbose-cmd| for more information.
 			If "[expr]" is not given, the number 0 is returned.
 			When a function ends without an explicit ":return",
 			the number 0 is returned.
-			Note that there is no check for unreachable lines,
-			thus there is no warning if commands follow ":return".
+			In a :def function *E1095* is given if unreachable
+			code follows after the `:return`.
+			In legacy script there is no check for unreachable
+			lines, thus there is no warning if commands follow
+			`:return`.
 
 			If the ":return" is used after a |:try| but before the
 			matching |:finally| (if present), the commands
@@ -2746,7 +2753,7 @@ may optionally be following.  In the fun
 as "a:1", "a:2", etc.  "a:0" is set to the number of extra arguments (which
 can be 0).  "a:000" is set to a |List| that contains these arguments.  Note
 that "a:1" is the same as "a:000[0]".
-								*E742*
+							*E742* *E1090*
 The a: scope and the variables in it cannot be changed, they are fixed.
 However, if a composite type is used, such as |List| or |Dictionary| , you can
 change their contents.  Thus you can pass a |List| to a function and have the
@@ -3054,7 +3061,7 @@ declarations and assignments do not use 
 			from the {expr}.  If {var-name} didn't exist yet, it
 			is created.
 
-:let {var-name}[{idx}] = {expr1}			*E689*
+:let {var-name}[{idx}] = {expr1}			*E689* *E1141*
 			Set a list item to the result of the expression
 			{expr1}.  {var-name} must refer to a list and {idx}
 			must be a valid index in that list.  For nested list
@@ -3161,7 +3168,7 @@ declarations and assignments do not use 
 :let &g:{option-name} -= {expr1}
 			Like above, but only set the global value of an option
 			(if there is one).  Works like |:setglobal|.
-
+								*E1093*
 :let [{name1}, {name2}, ...] = {expr1}		*:let-unpack* *E687* *E688*
 			{expr1} must evaluate to a |List|.  The first item in
 			the list is assigned to {name1}, the second item to
@@ -3202,7 +3209,7 @@ declarations and assignments do not use 
 			|List| item.
 
 						*:let=<<* *:let-heredoc*
-						*E990* *E991* *E172* *E221*
+					*E990* *E991* *E172* *E221* *E1145*
 :let {var-name} =<< [trim] {endmarker}
 text...
 text...
@@ -3355,7 +3362,7 @@ text...
 				:lockvar v
 				:let v = 'asdf'	  " fails!
 				:unlet v	  " works
-<							*E741* *E940*
+<			*E741* *E940* *E1118* *E1119* *E1120* *E1121* *E1122*
 			If you try to change a locked variable you get an
 			error message: "E741: Value is locked: {name}".
 			If you try to lock or unlock a built-in variable you
@@ -3498,7 +3505,7 @@ text...
 			|Blob| does not affect the iteration.
 
 :for [{var1}, {var2}, ...] in {listlist}
-:endfo[r]
+:endfo[r]							*E1140*
 			Like ":for" above, but each item in {listlist} must be
 			a list, of which each item is assigned to {var1},
 			{var2}, etc.  Example: >
@@ -3601,7 +3608,7 @@ text...
 			|:break|, |:finish|, or |:return|, or by an error or
 			interrupt or exception (see |:throw|).
 
-							*:th* *:throw* *E608*
+						*:th* *:throw* *E608* *E1129*
 :th[row] {expr1}	The {expr1} is evaluated and thrown as an exception.
 			If the ":throw" is used after a |:try| but before the
 			first corresponding |:catch|, commands are skipped
--- a/runtime/doc/if_perl.txt
+++ b/runtime/doc/if_perl.txt
@@ -1,4 +1,4 @@
-*if_perl.txt*   For Vim version 8.2.  Last change: 2022 Jan 08
+*if_perl.txt*   For Vim version 8.2.  Last change: 2022 Jan 28
 
 
 		  VIM REFERENCE MANUAL    by Sven Verdoolaege
@@ -103,7 +103,7 @@ Here are some things you can try: >
   :perldo $_ = reverse($_);1
   :perl VIM::Msg("hello")
   :perl $line = $curbuf->Get(42)
-<
+<							*E299*
 Executing Perl commands in the |sandbox| is limited.  ":perldo" will not be
 possible at all.  ":perl" will be evaluated in the Safe environment, if
 possible.
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1,4 +1,4 @@
-*index.txt*     For Vim version 8.2.  Last change: 2021 Aug 31
+*index.txt*     For Vim version 8.2.  Last change: 2022 Jan 28
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -937,7 +937,9 @@ tag		command	      note action in Visual
 				   before the highlighted area
 |v_J|		J		2  join the highlighted lines
 |v_K|		K		   run 'keywordprg' on the highlighted area
-|v_O|		O		   Move horizontally to other corner of area.
+|v_O|		O		   move horizontally to other corner of area
+|v_P|		P		   replace highlighted area with register
+				   contents; unnamed register is unchanged
 		Q		   does not start Ex mode
 |v_R|		R		2  delete the highlighted lines and start
 				   insert
@@ -1000,6 +1002,8 @@ tag		command	      note action in Visual
 |v_i{|		i{		   same as iB
 |v_i}|		i}		   same as iB
 |v_o|		o		   move cursor to other corner of area
+|v_p|		p		   replace highlighted area with register
+				   contents; deleted text in unnamed register
 |v_r|		r		2  replace highlighted area with a character
 |v_s|		s		2  delete highlighted area and start insert
 |v_u|		u		2  make highlighted area lowercase
--- a/runtime/doc/message.txt
+++ b/runtime/doc/message.txt
@@ -1,4 +1,4 @@
-*message.txt*   For Vim version 8.2.  Last change: 2022 Jan 19
+*message.txt*   For Vim version 8.2.  Last change: 2022 Jan 26
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -82,7 +82,6 @@ LIST OF MESSAGES
   Add to read buffer ~
   makemap: Illegal mode ~
   Cannot create BalloonEval with both message and callback ~
-  Hangul automata ERROR ~
   block was not locked ~
   Didn't get block nr {N}? ~
   ml_upd_block0(): Didn't get block 0?? ~
@@ -92,12 +91,12 @@ LIST OF MESSAGES
   u_undo: line numbers wrong ~
   undo list corrupt ~
   undo line missing ~
-  ml_get: cannot find line {N} ~
-  cannot find line {N} ~
+  ml_get: cannot find line {N} in buffer {nr} {name} ~
   line number out of range: {N} past the end ~
   line count wrong in block {N} ~
-  Internal error ~
+  Internal error: lalloc(0, ) ~
   Internal error: {function} ~
+  Internal error in regexp ~
   fatal error in cs_manage_matches ~
   Invalid count for del_bytes(): {N} ~
 
@@ -728,6 +727,7 @@ specified.
 
 							*E488* 
   Trailing characters ~
+  Trailing characters: {text} ~
 
 An argument has been added to an Ex command that does not permit one.
 Or the argument has invalid characters and has not been recognized.
@@ -798,7 +798,7 @@ This is an (incomplete) overview of vari
 			*hit-enter* *press-enter* *hit-return*
 			*press-return* *hit-enter-prompt*
 
-  Press ENTER or type command to continue
+  Press ENTER or type command to continue ~
 
 This message is given when there is something on the screen for you to read,
 and the screen is about to be redrawn:
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 8.2.  Last change: 2022 Jan 22
+*options.txt*	For Vim version 8.2.  Last change: 2022 Jan 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1558,8 +1558,8 @@ A jump table for the options with a shor
 	preferred, because it is much faster.
 	'charconvert' is not used when reading stdin |--|, because there is no
 	file to convert from.  You will have to save the text in a file first.
-	The expression must return zero or an empty string for success,
-	non-zero for failure.
+	The expression must return zero, false or an empty string for success,
+	non-zero or true for failure.
 	The possible encoding names encountered are in 'encoding'.
 	Additionally, names given in 'fileencodings' and 'fileencoding' are
 	used.
@@ -1583,9 +1583,18 @@ A jump table for the options with a shor
 	Note that v:fname_in and v:fname_out will never be the same.
 	Note that v:charconvert_from and v:charconvert_to may be different
 	from 'encoding'.  Vim internally uses UTF-8 instead of UCS-2 or UCS-4.
+
 	Encryption is not done by Vim when using 'charconvert'.  If you want
 	to encrypt the file after conversion, 'charconvert' should take care
 	of this.
+
+	If the 'charconvert' expression starts with s: or |<SID>|, then it is
+	replaced with the script ID (|local-function|). Example: >
+		set charconvert=s:MyConvert()
+		set charconvert=<SID>SomeConvert()
+<	Otherwise the expression is evaluated in the context of the script
+	where the option was set, thus script-local items are available.
+
 	This option cannot be set from a |modeline| or in the |sandbox|, for
 	security reasons.
 
@@ -7777,10 +7786,11 @@ A jump table for the options with a shor
 'tabstop' 'ts'		number	(default 8)
 			local to buffer
 	Number of spaces that a <Tab> in the file counts for.  Also see
-	|:retab| command, and 'softtabstop' option.
+	the |:retab| command, and the 'softtabstop' option.
 
 	Note: Setting 'tabstop' to any other value than 8 can make your file
-	appear wrong in many places (e.g., when printing it).
+	appear wrong in many places, e.g., when printing it.
+	The value must be more than 0 and less than 10000.
 
 	There are four main ways to use tabs in Vim:
 	1. Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4
--- a/runtime/doc/print.txt
+++ b/runtime/doc/print.txt
@@ -1,4 +1,4 @@
-*print.txt*     For Vim version 8.2.  Last change: 2021 Oct 04
+*print.txt*     For Vim version 8.2.  Last change: 2022 Jan 23
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -178,7 +178,9 @@ If the expression starts with s: or |<SI
 script ID (|local-function|). Example: >
 		set printexpr=s:MyPrintFile()
 		set printexpr=<SID>SomePrintFile()
-<
+Otherwise, the expression is evaluated in the context of the script where the
+option was set, thus script-local items are available.
+
 This option cannot be set from a |modeline| or in the |sandbox|, for security
 reasons.
 
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -4033,25 +4033,77 @@ E1077	vim9.txt	/*E1077*
 E108	eval.txt	/*E108*
 E1081	eval.txt	/*E1081*
 E1083	editing.txt	/*E1083*
+E1084	eval.txt	/*E1084*
+E1085	eval.txt	/*E1085*
+E1086	eval.txt	/*E1086*
+E1087	vim9.txt	/*E1087*
+E1089	eval.txt	/*E1089*
 E109	eval.txt	/*E109*
+E1090	eval.txt	/*E1090*
 E1091	vim9.txt	/*E1091*
+E1093	eval.txt	/*E1093*
 E1094	vim9.txt	/*E1094*
+E1095	eval.txt	/*E1095*
+E1096	vim9.txt	/*E1096*
+E1097	vim9.txt	/*E1097*
+E1098	eval.txt	/*E1098*
+E1099	vim9.txt	/*E1099*
 E11	cmdline.txt	/*E11*
 E110	eval.txt	/*E110*
+E1100	vim9.txt	/*E1100*
+E1101	vim9.txt	/*E1101*
+E1102	vim9.txt	/*E1102*
+E1103	vim9.txt	/*E1103*
+E1104	vim9.txt	/*E1104*
+E1105	vim9.txt	/*E1105*
+E1106	vim9.txt	/*E1106*
+E1107	eval.txt	/*E1107*
+E1108	vim9.txt	/*E1108*
 E1109	builtin.txt	/*E1109*
 E111	eval.txt	/*E111*
 E1110	builtin.txt	/*E1110*
 E1111	builtin.txt	/*E1111*
 E1112	builtin.txt	/*E1112*
 E1113	builtin.txt	/*E1113*
+E1114	builtin.txt	/*E1114*
+E1115	testing.txt	/*E1115*
+E1116	testing.txt	/*E1116*
+E1117	vim9.txt	/*E1117*
+E1118	eval.txt	/*E1118*
+E1119	eval.txt	/*E1119*
 E112	eval.txt	/*E112*
+E1120	eval.txt	/*E1120*
+E1121	eval.txt	/*E1121*
+E1122	eval.txt	/*E1122*
+E1123	vim9.txt	/*E1123*
+E1124	vim9.txt	/*E1124*
+E1125	vim9.txt	/*E1125*
+E1126	vim9.txt	/*E1126*
+E1127	vim9.txt	/*E1127*
+E1128	vim9.txt	/*E1128*
+E1129	eval.txt	/*E1129*
 E113	eval.txt	/*E113*
+E1130	vim9.txt	/*E1130*
+E1131	vim9.txt	/*E1131*
+E1132	builtin.txt	/*E1132*
+E1133	vim9.txt	/*E1133*
+E1134	vim9.txt	/*E1134*
+E1135	eval.txt	/*E1135*
 E1136	map.txt	/*E1136*
 E1137	map.txt	/*E1137*
+E1138	eval.txt	/*E1138*
+E1139	vim9.txt	/*E1139*
 E114	eval.txt	/*E114*
+E1140	eval.txt	/*E1140*
+E1141	eval.txt	/*E1141*
+E1143	eval.txt	/*E1143*
+E1144	vim9.txt	/*E1144*
+E1145	eval.txt	/*E1145*
 E115	eval.txt	/*E115*
 E1155	autocmd.txt	/*E1155*
+E1158	builtin.txt	/*E1158*
 E116	eval.txt	/*E116*
+E1169	eval.txt	/*E1169*
 E117	eval.txt	/*E117*
 E118	eval.txt	/*E118*
 E1187	starting.txt	/*E1187*
@@ -4269,6 +4321,7 @@ E295	message.txt	/*E295*
 E296	message.txt	/*E296*
 E297	message.txt	/*E297*
 E298	message.txt	/*E298*
+E299	if_perl.txt	/*E299*
 E30	change.txt	/*E30*
 E300	message.txt	/*E300*
 E301	message.txt	/*E301*
@@ -7726,6 +7779,7 @@ interactive-functions	usr_41.txt	/*inter
 interfaces-5.2	version5.txt	/*interfaces-5.2*
 internal-variables	eval.txt	/*internal-variables*
 internal-wordlist	spell.txt	/*internal-wordlist*
+internal_get_nv_cmdchar()	builtin.txt	/*internal_get_nv_cmdchar()*
 internet	intro.txt	/*internet*
 interrupt()	builtin.txt	/*interrupt()*
 intro	intro.txt	/*intro*
@@ -9867,6 +9921,8 @@ test_garbagecollect_soon()	testing.txt	/
 test_getvalue()	testing.txt	/*test_getvalue()*
 test_gui_drop_files()	testing.txt	/*test_gui_drop_files()*
 test_gui_mouse_event()	testing.txt	/*test_gui_mouse_event()*
+test_gui_tabline_event()	testing.txt	/*test_gui_tabline_event()*
+test_gui_tabmenu_event()	testing.txt	/*test_gui_tabmenu_event()*
 test_ignore_error()	testing.txt	/*test_ignore_error()*
 test_null_blob()	testing.txt	/*test_null_blob()*
 test_null_channel()	testing.txt	/*test_null_channel()*
--- a/runtime/doc/testing.txt
+++ b/runtime/doc/testing.txt
@@ -1,4 +1,4 @@
-*testing.txt*	For Vim version 8.2.  Last change: 2022 Jan 20
+*testing.txt*	For Vim version 8.2.  Last change: 2022 Jan 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -390,12 +390,12 @@ assert_fails({cmd} [, {error} [, {msg} [
 <
 		If {msg} is empty then it is not used.  Do this to get the
 		default message when passing the {lnum} argument.
-
+							*E1115*
 		When {lnum} is present and not negative, and the {error}
 		argument is present and matches, then this is compared with
 		the line number at which the error was reported. That can be
 		the line number in a function or in a script.
-
+							*E1116*
 		When {context} is present it is used as a pattern and matched
 		against the context (script name or function name) where
 		{lnum} is located in.
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 8.2.  Last change: 2022 Jan 22
+*todo.txt*      For Vim version 8.2.  Last change: 2022 Jan 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -38,13 +38,22 @@ browser use: https://github.com/vim/vim/
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Also set the script context for other "expr" options, like for 'foldexpr'?
-    'printexpr'     eval_printexpr()
-    "expr:" part of 'spellsuggest   eval_spell_expr()
+Only find a global function from Vim9 script when using "g:" ?  #9637
+
+Disallow defining a script#Func() in Vim9 script.
+
+Cannot use command modifier for "import 'name.vim' as vim9"
+
+When making a copy of a list or dict, do not keep the type? #9644
+    With deepcopy() all, with copy() this still fails:
+    var l: list<list<number>> = [[1], [2]]
+    l->copy()[0][0] = 'x'
+
+Remove EBCDIC support?
 
 Once Vim9 is stable:
 - Add all the error numbers in a good place in documentation.
-    done until E1083
+    done until E1145
 - Check code coverage, add more tests if needed.
 - Use Vim9 for runtime files.
 
@@ -62,6 +71,8 @@ Further Vim9 improvements, possibly afte
   evaluation.
   Use the location where the option was set for deciding whether it's to be
   evaluated in Vim9 script context.
+- Implement "import lazy" - like autoload but with a relative or absolute
+  path. #9595
 - implement :type
 - implement :enum
 - implement :class and :interface: See |vim9-classes|
@@ -78,6 +89,7 @@ Further Vim9 improvements, possibly afte
 Update list of features to vote on:
 - multiple cursors
 - built-in LSP support
+- start first line halfway
 
 Popup windows:
 - Preview popup not properly updated when it overlaps with completion menu.
@@ -235,6 +247,8 @@ Memory leak in test_alot with pyeval() (
 Memory leak in test_alot with expand()
 Memory leaks in test_channel? (or is it because of fork())
 
+PR to support %e and %k in 'errorformat'. #9624
+
 Idea: when typing ":e /some/dir/" and "dir" does not exist, highlight in red.
 
 ":set &shellpipe" and ":set &shellredir" should use the logic from
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt*	For Vim version 8.2.  Last change: 2022 Jan 01
+*usr_41.txt*	For Vim version 8.2.  Last change: 2022 Jan 28
 
 		     VIM USER MANUAL - by Bram Moolenaar
 
@@ -2505,7 +2505,7 @@ When the user does ":setfiletype xyz" th
 should be undone.  Set the b:undo_ftplugin variable to the commands that will
 undo the settings in your filetype plugin.  Example: >
 
-	b:undo_ftplugin = "setlocal fo< com< tw< commentstring<"
+	let b:undo_ftplugin = "setlocal fo< com< tw< commentstring<"
 		\ .. "| unlet b:match_ignorecase b:match_words b:match_skip"
 
 Using ":setlocal" with "<" after the option name resets the option to its
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -1,4 +1,4 @@
-*vim9.txt*	For Vim version 8.2.  Last change: 2022 Jan 23
+*vim9.txt*	For Vim version 8.2.  Last change: 2022 Jan 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -82,7 +82,7 @@ script and `:def` functions; details are
 	     .. yourName
 	     .. ", how are you?"
 - White space is required in many places to improve readability.
-- Assign values without `:let`, declare variables with `:var`: >
+- Assign values without `:let` *E1126* , declare variables with `:var`: >
 	var count = 0
 	count += 3
 - Constants can be declared with `:final` and `:const`: >
@@ -139,7 +139,7 @@ arguments).
 
 
 Vim9 functions ~
-
+							*E1099*
 A function defined with `:def` is compiled.  Execution is many times faster,
 often 10 to 100 times.
 
@@ -183,11 +183,11 @@ You can call a legacy dict function thou
 	  var d = {func: Legacy, value: 'text'}
 	  d.func()
 	enddef
-
+<							*E1096*
 The argument types and return type need to be specified.  The "any" type can
 be used, type checking will then be done at runtime, like with legacy
 functions.
-
+							*E1106*
 Arguments are accessed by name, without "a:", just like any other language.
 There is no "a:" dictionary or "a:000" list.
 					*vim9-variable-arguments* *E1055*
@@ -238,9 +238,6 @@ When referring to a function and no "s:"
 search for the function:
 - in the function scope, in block scopes
 - in the script scope, possibly imported
-- in the list of global functions
-However, it is recommended to always use "g:" to refer to a global function
-for clarity.
 
 Since a script-local function reference can be used without "s:" the name must
 start with an upper case letter even when using the "s:" prefix.  In legacy
@@ -255,7 +252,7 @@ it is being compiled (to figure out the 
 The result is that functions and variables without a namespace can usually be
 found in the script, either defined there or imported.  Global functions and
 variables could be defined anywhere (good luck finding out where!).
-
+							*E1102*
 Global functions can still be defined and deleted at nearly any time.  In
 Vim9 script script-local functions are defined once when the script is sourced
 and cannot be deleted or replaced.
@@ -289,8 +286,8 @@ some point when loaded again.  E.g. when
 
 
 Variable declarations with :var, :final and :const ~
-					*vim9-declaration* *:var*
-					*E1017* *E1020* *E1054*
+				*vim9-declaration* *:var*
+				*E1017* *E1020* *E1054* *E1087* *E1108* *E1124*
 Local variables need to be declared with `:var`.  Local constants need to be
 declared with `:final` or `:const`.  We refer to both as "variables" in this
 section.
@@ -321,7 +318,7 @@ The declaration must be done earlier: >
 	   inner = 0
 	endif
 	echo inner
-<							*E1025*
+<							*E1025* *E1128*
 To intentionally hide a variable from code that follows, a block can be
 used: >
 	{
@@ -348,7 +345,7 @@ And with autocommands: >
 	   }
 
 Although using a :def function probably works better.
-						*E1022*
+				*E1022* *E1103* *E1130* *E1131* *E1133* *E1134*
 Declaring a variable with a type but without an initializer will initialize to
 false (for bool), empty (for string, list, dict, etc.) or zero (for number,
 any, etc.).  This matters especially when using the "any" type, the value will
@@ -440,7 +437,7 @@ Example: >
 	myList = [3, 4]		# Error!
 	myList[0] = 9		# Error!
 	myList->add(3)		# Error!
-<							*:final*
+<							*:final* *E1125*
 `:final` is used for making only the variable a constant, the value can be
 changed.  This is well known from Java.  Example: >
 	final myList = [1, 2]
@@ -600,7 +597,7 @@ Also when confused with the start of a c
 
 
 Automatic line continuation ~
-						*vim9-line-continuation*
+					*vim9-line-continuation* *E1097*
 In many cases it is obvious that an expression continues on the next line.  In
 those cases there is no need to prefix the line with a backslash (see
 |line-continuation|).  For example, when a list spans multiple lines: >
@@ -708,6 +705,7 @@ second line is seen as a separate comman
 Now "exit_cb: Func})" is actually a valid command: save any changes to the
 file "_cb: Func})" and exit.  To avoid this kind of mistake in Vim9 script
 there must be white space between most command names and the argument.
+*E1144*
 
 However, the argument of a command that is a command won't be recognized.  For
 example, after "windo echo expr" a line break inside "expr" will not be seen.
@@ -738,7 +736,7 @@ Notes:
 
 
 White space ~
-					*E1004* *E1068* *E1069* *E1074*
+				*E1004* *E1068* *E1069* *E1074* *E1127*
 Vim9 script enforces proper use of white space.  This is no longer allowed: >
 	var name=234	# Error!
 	var name= 234	# Error!
@@ -803,7 +801,7 @@ use another character, use a single or d
 	var dict = {'key with space': value}
 	var dict = {"key\twith\ttabs": value}
 	var dict = {'': value}  		# empty key
-
+<							*E1139*
 In case the key needs to be an expression, square brackets can be used, just
 like in JavaScript: >
 	var dict = {["key" .. nr]: value}
@@ -816,7 +814,7 @@ error.  A number can be given with and w
 
 
 No :xit, :t, :k, :append, :change or :insert ~
-
+							*E1100*
 These commands are too easily confused with local variable names.
 Instead of `:x` or `:xit` you can use `:exit`.
 Instead of `:t` you can use `:copy`.
@@ -1082,7 +1080,7 @@ 3. New style functions					*fast-functio
 			{return-type}.  When {return-type} is omitted or is
 			"void" the function is not expected to return
 			anything.
-							*E1077*	
+							*E1077* *E1123*
 			{arguments} is a sequence of zero or more argument
 			declarations.  There are three forms:
 				{name}: {type}
@@ -1100,7 +1098,7 @@ 3. New style functions					*fast-functio
 
 			It is possible to nest `:def` inside another `:def` or
 			`:function` up to about 50 levels deep.
-
+							*E1117*
 			[!] is used as with `:function`.  Note that
 			script-local functions cannot be deleted or redefined
 			later in Vim9 script.  They can only be removed by
@@ -1288,7 +1286,7 @@ expected to always be the same.  For exa
 At compile time Vim doesn't know the type of "g:two" and the expression type
 becomes list<any>.  An instruction is generated to check the list type before
 doing the assignment, which is a bit inefficient.
-							*type-casting*
+						*type-casting* *E1104*
 To avoid this, use a type cast: >
 	var l: list<number> = [1, <number>g:two]
 The compiled code will then only check that "g:two" is a number and give an
@@ -1333,6 +1331,14 @@ Results in:
 For script-local variables in Vim9 script the type is checked, also when the
 variable was declared in a legacy function.
 
+When a type has been declared this is attached to a list or string.  When
+later some expression attempts to change the type an error will be given: >
+	var ll: list<number> = [1, 2, 3]
+	ll->extend('x')  # Error, 'x' is not a number
+
+If the type is inferred then the type is allowed to change: >
+	[1, 2, 3]->extend('x')  # result: [1, 2, 3, 'x']
+
 
 Stricter type checking ~
 							*type-checking*
@@ -1347,7 +1353,7 @@ before, if the value used matches the ex
 an error, thus breaking backwards compatibility.  For example:
 - Using a number other than 0 or 1 where a boolean is expected.  *E1023*
 - Using a string value when setting a number option.
-- Using a number where a string is expected.   *E1024*
+- Using a number where a string is expected.   *E1024* *E1105*
 
 One consequence is that the item type of a list or dict given to |map()| must
 not change.  This will give an error in Vim9 script: >
@@ -1398,7 +1404,7 @@ global namespace.  If a file starts with
 	var myvar = 'yes'
 Then "myvar" will only exist in this file.  While without `vim9script` it would
 be available as `g:myvar` from any other script and function.
-
+							*E1101*
 The variables at the file level are very much like the script-local "s:"
 variables in legacy Vim script, but the "s:" is omitted.  And they cannot be
 deleted.
@@ -1466,11 +1472,11 @@ In case the name is long or ambiguous, a
 <							*E1060*
 Then you can use "that.EXPORTED_CONST", "that.someValue", etc.  You are free
 to choose the name "that".  Use something that will be recognized as referring
-to the imported script.  Avoid command names and builtin function names,
-because the name will shadow them.  If the name starts with a capital letter
-it can also shadow global user commands and functions.  Also, you cannot use
-the name for something else in the script, such as a function or variable
-name.
+to the imported script.  Avoid command names, command modifiers and builtin
+function names, because the name will shadow them.
+If the name starts with a capital letter it can also shadow global user
+commands and functions.  Also, you cannot use the name for something else in
+the script, such as a function or variable name.
 
 In case the dot in the name is undesired, a local reference can be made for a
 function: >
@@ -1747,6 +1753,9 @@ Specific items from TypeScript we avoid:
 - TypeScript has various "Readonly" types, which have limited usefulness,
   since a type cast can remove the immutable nature.  Vim locks the value,
   which is more flexible, but is only checked at runtime.
+- TypeScript has a complicated "import" statement that does not match how the
+  Vim import mechanism works.  A much simpler mechanism is used instead, which
+  matches that the imported script is only sourced once.
 
 
 Declarations ~
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2022 Jan 23
+" Last Change:	2022 Jan 29
 
 " Listen very carefully, I will say this only once
 if exists("did_load_filetypes")
--- a/runtime/ftplugin/basic.vim
+++ b/runtime/ftplugin/basic.vim
@@ -1,7 +1,7 @@
 " Vim filetype plugin file
-" Language:	BASIC
+" Language:	BASIC (QuickBASIC 4.5)
 " Maintainer:	Doug Kearns <dougkearns@gmail.com>
-" Last Change:	2015 Jan 10
+" Last Change:	2021 Mar 16
 
 if exists("b:did_ftplugin")
   finish
@@ -11,17 +11,46 @@ let b:did_ftplugin = 1
 let s:cpo_save = &cpo
 set cpo&vim
 
-setlocal comments=:REM,:'
+setlocal comments=:REM\ ,:Rem\ ,:rem\ ,:'
 setlocal commentstring='\ %s
 setlocal formatoptions-=t formatoptions+=croql
 
-if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
-  let b:browsefilter = "BASIC Source Files (*.bas)\t*.bas\n" .
-		     \ "All Files (*.*)\t*.*\n"
+" TODO: support exit ... as middle matches?
+if exists("loaded_matchit") && !exists("b:match_words")
+  let s:line_start	= '\%(^\s*\)\@<='
+  let s:not_end		= '\%(end\s\+\)\@<!'
+  let s:not_end_or_exit	= '\%(\%(end\|exit\)\s\+\)\@<!'
+
+  let b:match_ignorecase = 1
+  let b:match_words =
+		\     s:not_end_or_exit .. '\<def\s\+fn:\<end\s\+def\>,' ..
+		\     s:not_end_or_exit .. '\<function\>:\<end\s\+function\>,' ..
+		\     s:not_end_or_exit .. '\<sub\>:\<end\s\+sub\>,' ..
+		\     s:not_end .. '\<type\>:\<end\s\+type\>,' ..
+		\     s:not_end .. '\<select\>:\%(select\s\+\)\@<!\<case\%(\s\+\%(else\|is\)\)\=\>:\<end\s\+select\>,' ..
+		\     '\<do\>:\<loop\>,' ..
+		\     '\<for\>\%(\s\+\%(input\|output\|random\|append\|binary\)\)\@!:\<next\>,' ..
+		\     '\<while\>:\<wend\>,' ..
+		\     s:line_start .. 'if\%(.*\<then\s*\%($\|''\)\)\@=:\<\%(' .. s:line_start .. 'else\|elseif\)\>:\<end\s\+if\>,' ..
+		\     '\<lock\>:\<unlock\>'
+
+  let b:match_skip = 'synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string" || ' ..
+		\    'strpart(getline("."), 0, col(".") ) =~? "\\<exit\\s\\+"'
+
+  unlet s:line_start s:not_end s:not_end_or_exit
 endif
 
-let b:undo_ftplugin = "setl fo< com< cms< sua<" .
-		    \ " | unlet! b:browsefilter"
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+  let b:browsefilter = "BASIC Source Files (*.bas)\t*.bas\n" ..
+		\      "BASIC Include Files (*.bi, *.bm)\t*.bi;*.bm\n" ..
+		\      "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl fo< com< cms<" ..
+		\     " | unlet! b:match_ignorecase b:match_skip b:match_words" ..
+		\     " | unlet! b:browsefilter"
 
 let &cpo = s:cpo_save
 unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
--- a/runtime/ftplugin/freebasic.vim
+++ b/runtime/ftplugin/freebasic.vim
@@ -1,13 +1,65 @@
 " Vim filetype plugin file
-" Language:	FreeBasic
+" Language:	FreeBASIC
 " Maintainer:	Doug Kearns <dougkearns@gmail.com>
-" Last Change:	2015 Jan 10
+" Last Change:	2021 Mar 16
 
+" Setup {{{1
 if exists("b:did_ftplugin")
   finish
 endif
-let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
 
 runtime! ftplugin/basic.vim
 
-" vim: ts=8
+let s:dialect = freebasic#GetDialect()
+
+" Comments {{{1
+" add ''comments before 'comments
+let &l:comments = "sO:*\ -,mO:*\ \ ,exO:*/,s1:/',mb:',ex:'/,:''," .. &l:comments
+
+" Match words {{{1
+if exists("loaded_matchit")
+  let s:not_end = '\%(end\s\+\)\@<!'
+
+  let b:match_words ..= ','
+
+  if s:dialect == 'fb'
+    let b:match_words ..= s:not_end .. '\<constructor\>:\<end\s\+constructor\>,' ..
+		  \	  s:not_end .. '\<destructor\>:\<end\s\+destructor\>,' ..
+		  \	  s:not_end .. '\<property\>:\<end\s\+property\>,' ..
+		  \	  s:not_end .. '\<operator\>:\<end\s\+operator\>,' ..
+		  \	  s:not_end .. '\<extern\%(\s\+"\)\@=:\<end\s\+extern\>,'
+  endif
+
+  if s:dialect == 'fb' || s:dialect == 'deprecated'
+    let b:match_words ..= s:not_end .. '\<scope\>:\<end\s\+scope\>,'
+  endif
+
+  if s:dialect == 'qb'
+    let b:match_words ..= s:not_end .. '\<__asm\>:\<end\s\+__asm\>,' ..
+		  \	  s:not_end .. '\<__union\>:\<end\s\+__union\>,' ..
+		  \	  s:not_end .. '\<__with\>:\<end\s\+__with\>,'
+  else
+    let b:match_words ..= s:not_end .. '\<asm\>:\<end\s\+asm\>,' ..
+		  \	  s:not_end .. '\<namespace\>:\<end\s\+namespace\>,' ..
+		  \	  s:not_end .. '\<union\>:\<end\s\+union\>,' ..
+		  \	  s:not_end .. '\<with\>:\<end\s\+with\>,'
+  endif
+
+  let b:match_words ..= s:not_end .. '\<enum\>:\<end\s\+enum\>,' ..
+		  \	'^#\s*\%(if\|ifdef\|ifndef\)\>:^#\s*\%(else\|elseif\)\>:^#\s*endif\>,' ..
+		  \	'^#\s*macro\>:^#\s*endmacro\>'
+
+  " skip "function = <retval>"
+  let b:match_skip ..= '|| strpart(getline("."), col(".") - 1) =~? "^\\<function\\s\\+="'
+
+  unlet s:not_end
+endif
+
+" Cleanup {{{1
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
new file mode 100644
--- /dev/null
+++ b/runtime/ftplugin/qb64.vim
@@ -0,0 +1,26 @@
+" Vim filetype plugin file
+" Language:	QB64
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+runtime! ftplugin/basic.vim
+
+let s:not_end = '\%(end\s\+\)\@<!'
+
+let b:match_words ..= ',' ..
+		\     s:not_end .. '\<declare\>:\<end\s\+declare\>,' ..
+		\     '\<select\s\+everycase\>:\%(select\s\+\)\@<!\<case\%(\s\+\%(else\|is\)\)\=\>:\<end\s\+select\>,' ..
+		\     '$IF\>:$\%(ELSEIF\|ELSE\)\>:$END\s*IF\>'
+
+unlet s:not_end
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
new file mode 100644
--- /dev/null
+++ b/runtime/indent/basic.vim
@@ -0,0 +1,11 @@
+" Vim indent file
+" Language:	BASIC (QuickBASIC 4.5)
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2022 Jan 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/vb.vim
new file mode 100644
--- /dev/null
+++ b/runtime/indent/freebasic.vim
@@ -0,0 +1,11 @@
+" Vim indent file
+" Language:	FreeBASIC
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2022 Jan 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/vb.vim
new file mode 100644
--- /dev/null
+++ b/runtime/indent/qb64.vim
@@ -0,0 +1,11 @@
+" Vim indent file
+" Language:	QB64
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2022 Jan 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/vb.vim
--- a/runtime/pack/dist/opt/matchit/autoload/matchit.vim
+++ b/runtime/pack/dist/opt/matchit/autoload/matchit.vim
@@ -763,9 +763,9 @@ fun! s:ParseSkip(str)
       let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" ..
         \ strpart(skip,2) .. "'"
     elseif skip[0] == "r"
-      let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
+      let skip = "strpart(getline('.'),0,col('.'))=~'" .. strpart(skip,2) .. "'"
     elseif skip[0] == "R"
-      let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
+      let skip = "strpart(getline('.'),0,col('.'))!~'" .. strpart(skip,2) .. "'"
     endif
   endif
   return skip
--- a/runtime/syntax/basic.vim
+++ b/runtime/syntax/basic.vim
@@ -1,14 +1,15 @@
 " Vim syntax file
-" Language:		BASIC
+" Language:		BASIC (QuickBASIC 4.5)
 " Maintainer:		Doug Kearns <dougkearns@gmail.com>
 " Previous Maintainer:	Allan Kelly <allan@fruitloaf.co.uk>
 " Contributors:		Thilo Six
-" Last Change:		2015 Jan 10
+" Last Change:		2021 Aug 08
 
 " First version based on Micro$soft QBASIC circa 1989, as documented in
 " 'Learn BASIC Now' by Halvorson&Rygmyr. Microsoft Press 1989.
-" This syntax file not a complete implementation yet.  Send suggestions to the
-" maintainer.
+"
+" Second version attempts to match Microsoft QuickBASIC 4.5 while keeping FreeBASIC
+" (-lang qb) and QB64 (excluding extensions) in mind. -- DJK
 
 " Prelude {{{1
 if exists("b:current_syntax")
@@ -18,154 +19,357 @@ endif
 let s:cpo_save = &cpo
 set cpo&vim
 
+syn iskeyword @,48-57,.,!,#,%,&,$
+syn case      ignore
+
+" Whitespace Errors {{{1
+if exists("basic_space_errors")
+  if !exists("basic_no_trail_space_error")
+    syn match basicSpaceError display excludenl "\s\+$"
+  endif
+  if !exists("basic_no_tab_space_error")
+    syn match basicSpaceError display " \+\t"me=e-1
+  endif
+endif
+
+" Comment Errors {{{1
+if !exists("basic_no_comment_errors")
+  syn match basicCommentError "\<REM\>.*"
+endif
+
+" Not Top Cluster {{{1
+syn cluster basicNotTop contains=@basicLineIdentifier,basicDataString,basicDataSeparator,basicTodo
+
+" Statements {{{1
+
+syn cluster basicStatements contains=basicStatement,basicDataStatement,basicMetaRemStatement,basicPutStatement,basicRemStatement
+
+let s:statements =<< trim EOL " {{{2
+  beep
+  bload
+  bsave
+  call
+  calls
+  case
+  chain
+  chdir
+  circle
+  clear
+  close
+  cls
+  color
+  com
+  common
+  const
+  declare
+  def
+  def\s\+seg
+  defdbl
+  defint
+  deflng
+  defsng
+  defstr
+  dim
+  do
+  draw
+  elseif
+  end
+  end\s\+\%(def\|function\|if\|select\|sub\|type\)
+  environ
+  erase
+  error
+  exit\s\+\%(def\|do\|for\|function\|sub\)
+  field
+  files
+  for
+  function
+  get
+  gosub
+  goto
+  if
+  input
+  ioctl
+  key
+  kill
+  let
+  line
+  line\s\+input
+  locate
+  lock
+  loop
+  lprint
+  lset
+  mkdir
+  name
+  next
+  on
+  on\s\+error
+  on\s\+uevent
+  open
+  open\s\+com
+  option
+  out
+  paint
+  palette
+  palette\s\+using
+  pcopy
+  pen
+  pmap
+  poke
+  preset
+  print
+  pset
+  randomize
+  read
+  redim
+  reset
+  restore
+  resume
+  return
+  rmdir
+  rset
+  run
+  select\s\+case
+  shared
+  shell
+  sleep
+  sound
+  static
+  stop
+  strig
+  sub
+  swap
+  system
+  troff
+  tron
+  type
+  uevent
+  unlock
+  using
+  view
+  view\s\+print
+  wait
+  wend
+  while
+  width
+  window
+  write
+EOL
+" }}}
+
+for s in s:statements
+  exe 'syn match basicStatement "\<' .. s .. '\>" contained'
+endfor
+
+syn match basicStatement "\<\%(then\|else\)\>" nextgroup=@basicStatements skipwhite
+
+" DATA Statement
+syn match  basicDataSeparator "," contained
+syn region basicDataStatement matchgroup=basicStatement start="\<data\>" matchgroup=basicStatementSeparator end=":\|$" contained contains=basicDataSeparator,basicDataString,basicNumber,basicFloat,basicString
+
+if !exists("basic_no_data_fold")
+  syn region basicMultilineData start="^\s*\<data\>.*\n\%(^\s*\<data\>\)\@=" end="^\s*\<data\>.*\n\%(^\s*\<data\>\)\@!" contains=basicDataStatement transparent fold keepend
+endif
+
+" PUT File I/O and Graphics statements - needs special handling for graphics
+" action verbs
+syn match  basicPutAction "\<\%(pset\|preset\|and\|or\|xor\)\>" contained
+syn region basicPutStatement matchgroup=basicStatement start="\<put\>" matchgroup=basicStatementSeparator end=":\|$" contained contains=basicKeyword,basicPutAction,basicFilenumber
+
 " Keywords {{{1
-syn keyword basicStatement	BEEP beep Beep BLOAD bload Bload BSAVE bsave Bsave
-syn keyword basicStatement	CALL call Call ABSOLUTE absolute Absolute
-syn keyword basicStatement	CHAIN chain Chain CHDIR chdir Chdir
-syn keyword basicStatement	CIRCLE circle Circle CLEAR clear Clear
-syn keyword basicStatement	CLOSE close Close CLS cls Cls COLOR color Color
-syn keyword basicStatement	COM com Com COMMON common Common
-syn keyword basicStatement	CONST const Const DATA data Data
-syn keyword basicStatement	DECLARE declare Declare DEF def Def
-syn keyword basicStatement	DEFDBL defdbl Defdbl DEFINT defint Defint
-syn keyword basicStatement	DEFLNG deflng Deflng DEFSNG defsng Defsng
-syn keyword basicStatement	DEFSTR defstr Defstr DIM dim Dim
-syn keyword basicStatement	DO do Do LOOP loop Loop
-syn keyword basicStatement	DRAW draw Draw END end End
-syn keyword basicStatement	ENVIRON environ Environ ERASE erase Erase
-syn keyword basicStatement	ERROR error Error EXIT exit Exit
-syn keyword basicStatement	FIELD field Field FILES files Files
-syn keyword basicStatement	FOR for For NEXT next Next
-syn keyword basicStatement	FUNCTION function Function GET get Get
-syn keyword basicStatement	GOSUB gosub Gosub GOTO goto Goto
-syn keyword basicStatement	IF if If THEN then Then ELSE else Else
-syn keyword basicStatement	INPUT input Input INPUT# input# Input#
-syn keyword basicStatement	IOCTL ioctl Ioctl KEY key Key
-syn keyword basicStatement	KILL kill Kill LET let Let
-syn keyword basicStatement	LINE line Line LOCATE locate Locate
-syn keyword basicStatement	LOCK lock Lock UNLOCK unlock Unlock
-syn keyword basicStatement	LPRINT lprint Lprint USING using Using
-syn keyword basicStatement	LSET lset Lset MKDIR mkdir Mkdir
-syn keyword basicStatement	NAME name Name ON on On
-syn keyword basicStatement	ERROR error Error OPEN open Open
-syn keyword basicStatement	OPTION option Option BASE base Base
-syn keyword basicStatement	OUT out Out PAINT paint Paint
-syn keyword basicStatement	PALETTE palette Palette PCOPY pcopy Pcopy
-syn keyword basicStatement	PEN pen Pen PLAY play Play
-syn keyword basicStatement	PMAP pmap Pmap POKE poke Poke
-syn keyword basicStatement	PRESET preset Preset PRINT print Print
-syn keyword basicStatement	PRINT# print# Print# USING using Using
-syn keyword basicStatement	PSET pset Pset PUT put Put
-syn keyword basicStatement	RANDOMIZE randomize Randomize READ read Read
-syn keyword basicStatement	REDIM redim Redim RESET reset Reset
-syn keyword basicStatement	RESTORE restore Restore RESUME resume Resume
-syn keyword basicStatement	RETURN return Return RMDIR rmdir Rmdir
-syn keyword basicStatement	RSET rset Rset RUN run Run
-syn keyword basicStatement	SEEK seek Seek SELECT select Select
-syn keyword basicStatement	CASE case Case SHARED shared Shared
-syn keyword basicStatement	SHELL shell Shell SLEEP sleep Sleep
-syn keyword basicStatement	SOUND sound Sound STATIC static Static
-syn keyword basicStatement	STOP stop Stop STRIG strig Strig
-syn keyword basicStatement	SUB sub Sub SWAP swap Swap
-syn keyword basicStatement	SYSTEM system System TIMER timer Timer
-syn keyword basicStatement	TROFF troff Troff TRON tron Tron
-syn keyword basicStatement	TYPE type Type UNLOCK unlock Unlock
-syn keyword basicStatement	VIEW view View WAIT wait Wait
-syn keyword basicStatement	WHILE while While WEND wend Wend
-syn keyword basicStatement	WIDTH width Width WINDOW window Window
-syn keyword basicStatement	WRITE write Write DATE$ date$ Date$
-syn keyword basicStatement	MID$ mid$ Mid$ TIME$ time$ Time$
+let s:keywords =<< trim EOL " {{{2
+  absolute
+  access
+  alias
+  append
+  as
+  base
+  binary
+  byval
+  cdecl
+  com
+  def
+  do
+  for
+  function
+  gosub
+  goto
+  input
+  int86old
+  int86xold
+  interrupt
+  interruptx
+  is
+  key
+  len
+  list
+  local
+  lock
+  lprint
+  next
+  off
+  on
+  output
+  pen
+  play
+  random
+  read
+  resume
+  screen
+  seg
+  shared
+  signal
+  static
+  step
+  stop
+  strig
+  sub
+  timer
+  to
+  until
+  using
+  while
+  write
+EOL
+" }}}
 
-syn keyword basicFunction	ABS abs Abs ASC asc Asc
-syn keyword basicFunction	ATN atn Atn CDBL cdbl Cdbl
-syn keyword basicFunction	CINT cint Cint CLNG clng Clng
-syn keyword basicFunction	COS cos Cos CSNG csng Csng
-syn keyword basicFunction	CSRLIN csrlin Csrlin CVD cvd Cvd
-syn keyword basicFunction	CVDMBF cvdmbf Cvdmbf CVI cvi Cvi
-syn keyword basicFunction	CVL cvl Cvl CVS cvs Cvs
-syn keyword basicFunction	CVSMBF cvsmbf Cvsmbf EOF eof Eof
-syn keyword basicFunction	ERDEV erdev Erdev ERL erl Erl
-syn keyword basicFunction	ERR err Err EXP exp Exp
-syn keyword basicFunction	FILEATTR fileattr Fileattr FIX fix Fix
-syn keyword basicFunction	FRE fre Fre FREEFILE freefile Freefile
-syn keyword basicFunction	INP inp Inp INSTR instr Instr
-syn keyword basicFunction	INT int Int LBOUND lbound Lbound
-syn keyword basicFunction	LEN len Len LOC loc Loc
-syn keyword basicFunction	LOF lof Lof LOG log Log
-syn keyword basicFunction	LPOS lpos Lpos PEEK peek Peek
-syn keyword basicFunction	PEN pen Pen POINT point Point
-syn keyword basicFunction	POS pos Pos RND rnd Rnd
-syn keyword basicFunction	SADD sadd Sadd SCREEN screen Screen
-syn keyword basicFunction	SEEK seek Seek SETMEM setmem Setmem
-syn keyword basicFunction	SGN sgn Sgn SIN sin Sin
-syn keyword basicFunction	SPC spc Spc SQR sqr Sqr
-syn keyword basicFunction	STICK stick Stick STRIG strig Strig
-syn keyword basicFunction	TAB tab Tab TAN tan Tan
-syn keyword basicFunction	UBOUND ubound Ubound VAL val Val
-syn keyword basicFunction	VALPTR valptr Valptr VALSEG valseg Valseg
-syn keyword basicFunction	VARPTR varptr Varptr VARSEG varseg Varseg
-syn keyword basicFunction	CHR$ Chr$ chr$ COMMAND$ command$ Command$
-syn keyword basicFunction	DATE$ date$ Date$ ENVIRON$ environ$ Environ$
-syn keyword basicFunction	ERDEV$ erdev$ Erdev$ HEX$ hex$ Hex$
-syn keyword basicFunction	INKEY$ inkey$ Inkey$ INPUT$ input$ Input$
-syn keyword basicFunction	IOCTL$ ioctl$ Ioctl$ LCASES$ lcases$ Lcases$
-syn keyword basicFunction	LAFT$ laft$ Laft$ LTRIM$ ltrim$ Ltrim$
-syn keyword basicFunction	MID$ mid$ Mid$ MKDMBF$ mkdmbf$ Mkdmbf$
-syn keyword basicFunction	MKD$ mkd$ Mkd$ MKI$ mki$ Mki$
-syn keyword basicFunction	MKL$ mkl$ Mkl$ MKSMBF$ mksmbf$ Mksmbf$
-syn keyword basicFunction	MKS$ mks$ Mks$ OCT$ oct$ Oct$
-syn keyword basicFunction	RIGHT$ right$ Right$ RTRIM$ rtrim$ Rtrim$
-syn keyword basicFunction	SPACE$ space$ Space$ STR$ str$ Str$
-syn keyword basicFunction	STRING$ string$ String$ TIME$ time$ Time$
-syn keyword basicFunction	UCASE$ ucase$ Ucase$ VARPTR$ varptr$ Varptr$
+for k in s:keywords
+  exe 'syn match basicKeyword "\<' .. k .. '\>"'
+endfor
+
+" Functions {{{1
+syn keyword basicFunction abs asc atn cdbl chr$ cint clng command$ cos csng
+syn keyword basicFunction csrlin cvd cvdmbf cvi cvl cvs cvsmbf environ$ eof
+syn keyword basicFunction erdev erdev$ erl err exp fileattr fix fre freefile
+syn keyword basicFunction hex$ inkey$ inp input$ instr int ioctl$ left$ lbound
+syn keyword basicFunction lcase$ len loc lof log lpos ltrim$ mkd$ mkdmbf$ mki$
+syn keyword basicFunction mkl$ mks$ mksmbf$ oct$ peek pen point pos right$ rnd
+syn keyword basicFunction rtrim$ sadd setmem sgn sin space$ spc sqr stick str$
+syn keyword basicFunction strig string$ tab tan ubound ucase$ val valptr
+syn keyword basicFunction valseg varptr varptr$ varseg
+
+" Functions and statements (same name) {{{1
+syn match   basicStatement "\<\%(date\$\|mid\$\|play\|screen\|seek\|time\$\|timer\)\>" contained
+syn match   basicFunction  "\<\%(date\$\|mid\$\|play\|screen\|seek\|time\$\|timer\)\>"
+
+" Types {{{1
+syn keyword basicType integer long single double string any
+
+" Strings {{{1
+
+" Unquoted DATA strings - anything except [:,] and leading or trailing whitespace
+" Needs lower priority than numbers
+syn match basicDataString "[^[:space:],:]\+\%(\s\+[^[:space:],:]\+\)*" contained
+
+syn region basicString start=+"+ end=+"+ oneline
+
+" Booleans {{{1
+if exists("basic_booleans")
+  syn keyword basicBoolean true false
+endif
 
 " Numbers {{{1
-" Integer number, or floating point number without a dot.
-syn match  basicNumber		"\<\d\+\>"
-" Floating point number, with dot
-syn match  basicNumber		"\<\d\+\.\d*\>"
-" Floating point number, starting with a dot
-syn match  basicNumber		"\.\d\+\>"
+
+" Integers
+syn match basicNumber "-\=&o\=\o\+[%&]\=\>"
+syn match basicNumber "-\=&h\x\+[%&]\=\>"
+syn match basicNumber "-\=\<\d\+[%&]\=\>"
+
+" Floats
+syn match basicFloat "-\=\<\d\+\.\=\d*\%(\%([ed][+-]\=\d*\)\|[!#]\)\=\>"
+syn match basicFloat      "-\=\<\.\d\+\%(\%([ed][+-]\=\d*\)\|[!#]\)\=\>"
 
-" String and Character constants {{{1
-syn match   basicSpecial	"\\\d\d\d\|\\." contained
-syn region  basicString		start=+"+  skip=+\\\\\|\\"+  end=+"+	contains=basicSpecial
+" Statement anchors {{{1
+syn match basicLineStart	  "^" nextgroup=@basicStatements,@basicLineIdentifier skipwhite
+syn match basicStatementSeparator ":" nextgroup=@basicStatements		      skipwhite
+
+" Line numbers and labels {{{1
+
+" QuickBASIC limits these to 65,529 and 40 chars respectively
+syn match basicLineNumber "\d\+"		  nextgroup=@basicStatements skipwhite contained
+syn match basicLineLabel  "\a[[:alnum:]]*\ze\s*:" nextgroup=@basicStatements skipwhite contained
+
+syn cluster basicLineIdentifier contains=basicLineNumber,basicLineLabel
 
-" Line numbers {{{1
-syn region  basicLineNumber	start="^\d" end="\s"
+" Line Continuation {{{1
+syn match basicLineContinuation "\s*\zs_\ze\s*$"
+
+" Type suffixes {{{1
+if exists("basic_type_suffixes")
+  syn match basicTypeSuffix "\a[[:alnum:].]*\zs[$%&!#]"
+endif
+
+" File numbers {{{1
+syn match basicFilenumber "#\d\+"
+syn match basicFilenumber "#\a[[:alnum:].]*[%&!#]\="
 
-" Data-type suffixes {{{1
-syn match   basicTypeSpecifier	"[a-zA-Z0-9][$%&!#]"ms=s+1
-" Used with OPEN statement
-syn match   basicFilenumber  "#\d\+"
+" Operators {{{1
+if exists("basic_operators")
+  syn match basicArithmeticOperator "[-+*/\\^]"
+  syn match basicRelationalOperator "<>\|<=\|>=\|[><=]"
+endif
+syn match basicLogicalOperator	  "\<\%(not\|and\|or\|xor\|eqv\|imp\)\>"
+syn match basicArithmeticOperator "\<mod\>"
 
-" Mathematical operators {{{1
-" syn match   basicMathsOperator "[<>+\*^/\\=-]"
-syn match   basicMathsOperator	 "-\|=\|[:<>+\*^/\\]\|AND\|OR"
+" Metacommands {{{1
+" Note: No trailing word boundaries.  Text may be freely mixed however there
+" must be only leading whitespace prior to the first metacommand
+syn match basicMetacommand "$INCLUDE\s*:\s*'[^']\+'" contained containedin=@basicMetaComments
+syn match basicMetacommand "$\%(DYNAMIC\|STATIC\)"   contained containedin=@basicMetaComments
 
 " Comments {{{1
-syn keyword basicTodo		TODO FIXME XXX NOTE contained
-syn region  basicComment	start="^\s*\zsREM\>" start="\%(:\s*\)\@<=REM\>" end="$" contains=basicTodo
-syn region  basicComment	start="'"					end="$" contains=basicTodo
+syn keyword basicTodo TODO FIXME XXX NOTE contained
+
+syn region basicRemStatement matchgroup=basicStatement start="REM\>" end="$" contains=basicTodo,@Spell contained
+syn region basicComment				       start="'"     end="$" contains=basicTodo,@Spell
+
+if !exists("basic_no_comment_fold")
+  syn region basicMultilineComment start="^\s*'.*\n\%(\s*'\)\@=" end="^\s*'.*\n\%(\s*'\)\@!" contains=@basicComments transparent fold keepend
+endif
+
+" Metacommands
+syn region  basicMetaRemStatement matchgroup=basicStatement start="REM\>\s*\$\@=" end="$" contains=basicTodo contained
+syn region  basicMetaComment				    start="'\s*\$\@="	  end="$" contains=basicTodo
+
+syn cluster basicMetaComments contains=basicMetaComment,basicMetaRemStatement
+syn cluster basicComments     contains=basicComment,basicMetaComment
 
 "syn sync ccomment basicComment
 
 " Default Highlighting {{{1
-hi def link basicLabel		Label
-hi def link basicConditional	Conditional
-hi def link basicRepeat		Repeat
-hi def link basicLineNumber	Comment
-hi def link basicNumber		Number
-hi def link basicError		Error
-hi def link basicStatement	Statement
-hi def link basicString		String
-hi def link basicComment	Comment
-hi def link basicSpecial	Special
-hi def link basicTodo		Todo
-hi def link basicFunction	Identifier
-hi def link basicTypeSpecifier	Type
-hi def link basicFilenumber	basicTypeSpecifier
-"hi basicMathsOperator term=bold cterm=bold gui=bold
+hi def link basicArithmeticOperator basicOperator
+hi def link basicBoolean	    Boolean
+hi def link basicComment	    Comment
+hi def link basicCommentError	    Error
+hi def link basicDataString	    basicString
+hi def link basicFilenumber	    basicTypeSuffix " TODO: better group
+hi def link basicFloat		    Float
+hi def link basicFunction	    Identifier
+hi def link basicKeyword	    Keyword
+hi def link basicLineIdentifier	    LineNr
+hi def link basicLineContinuation   Special
+hi def link basicLineLabel	    basicLineIdentifier
+hi def link basicLineNumber	    basicLineIdentifier
+hi def link basicLogicalOperator    basicOperator
+hi def link basicMetacommand	    SpecialComment
+hi def link basicMetaComment	    Comment
+hi def link basicMetaRemStatement   Comment
+hi def link basicNumber		    Number
+hi def link basicOperator	    Operator
+hi def link basicPutAction	    Keyword
+hi def link basicRelationalOperator basicOperator
+hi def link basicRemStatement	    Comment
+hi def link basicSpaceError	    Error
+hi def link basicStatementSeparator Special
+hi def link basicStatement	    Statement
+hi def link basicString		    String
+hi def link basicTodo		    Todo
+hi def link basicType		    Type
+hi def link basicTypeSuffix	    Special
+if exists("basic_legacy_syntax_groups")
+  hi def link basicTypeSpecifier      Type
+  hi def link basicTypeSuffix	      basicTypeSpecifier
+endif
 
 " Postscript {{{1
 let b:current_syntax = "basic"
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/qb64.vim
@@ -0,0 +1,409 @@
+" Vim syntax file
+" Language:	QB64
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:	2022 Jan 21
+
+" Prelude {{{1
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" syn iskeyword set after sourcing of basic.vim
+
+syn case ignore
+
+let s:prefix = search('\c^\s*$NOPREFIX\>', 'n') ? '_\=' : '_'
+
+" Statements {{{1
+
+let s:statements =<< trim EOL " {{{2
+  acceptfiledrop
+  allowfullscreen
+  assert
+  console
+  consolecursor
+  consolefont
+  consoletitle
+  continue
+  copypalette
+  define
+  delay
+  depthbuffer
+  displayorder
+  dontblend
+  echo
+  exit\s\+\%(select\|case\)
+  finishdrop
+  freefont
+  freeimage
+  icon
+  keyclear
+  limit
+  maptriangle
+  memcopy
+  memfill
+  memfree
+  memput
+  mousehide
+  mousemove
+  mouseshow
+  printimage
+  printstring
+  putimage
+  screenclick
+  screenhide
+  screenmove
+  screenprint
+  screenshow
+  setalpha
+  sndbal
+  sndclose
+  sndlimit
+  sndloop
+  sndpause
+  sndplay
+  sndplaycopy
+  sndplayfile
+  sndraw
+  sndrawdone
+  sndsetpos
+  sndstop
+  sndvol
+  title
+EOL
+" }}}
+
+for s in s:statements
+  exe 'syn match qb64Statement "\<' .. s:prefix .. s .. '\>" contained contains=qb64Underscore'
+endfor
+
+" Functions {{{1
+
+let s:functions =<< trim EOL " {{{2
+  acos
+  acosh
+  alpha
+  alpha32
+  arccot
+  arccsc
+  arcsec
+  asin
+  asinh
+  atan2
+  atanh
+  axis
+  backgroundcolor
+  blue
+  blue32
+  button
+  buttonchange
+  ceil
+  cinp
+  commandcount
+  connected
+  connectionaddress
+  connectionaddress$
+  consoleinput
+  copyimage
+  cot
+  coth
+  cosh
+  csc
+  csch
+  cv
+  cwd$
+  d2g
+  d2r
+  defaultcolor
+  deflate$
+  desktopheight
+  desktopwidth
+  device$
+  deviceinput
+  devices
+  dir$
+  direxists
+  droppedfile
+  droppedfile$
+  errorline
+  errormessage$
+  exit
+  fileexists
+  fontheight
+  fontwidth
+  freetimer
+  g2d
+  g2r
+  green
+  green32
+  height
+  hypot
+  inclerrorfile$
+  inclerrorline
+  inflate$
+  instrrev
+  keyhit
+  keydown
+  lastaxis
+  lastbutton
+  lastwheel
+  loadfont
+  loadimage
+  mem
+  memelement
+  memexists
+  memimage
+  memnew
+  memsound
+  mk$
+  mousebutton
+  mouseinput
+  mousemovementx
+  mousemovementy
+  mousepipeopen
+  mousewheel
+  mousex
+  mousey
+  newimage
+  offset
+  openclient
+  os$
+  pi
+  pixelsize
+  printwidth
+  r2d
+  r2g
+  red
+  red32
+  readbit
+  resetbit
+  resizeheight
+  resizewidth
+  rgb
+  rgb32
+  rgba
+  rgba32
+  round
+  sec
+  sech
+  screenexists
+  screenimage
+  screenx
+  screeny
+  setbit
+  shellhide
+  shl
+  shr
+  sinh
+  sndcopy
+  sndgetpos
+  sndlen
+  sndopen
+  sndopenraw
+  sndpaused
+  sndplaying
+  sndrate
+  sndrawlen
+  startdir$
+  strcmp
+  stricmp
+  tanh
+  title$
+  togglebit
+  totaldroppedfiles
+  trim$
+  wheel
+  width
+  windowhandle
+  windowhasfocus
+EOL
+" }}}
+
+for f in s:functions
+  exe 'syn match qb64Function "\<' .. s:prefix .. f .. '\>" contains=qb64Underscore'
+endfor
+
+" Functions and statements (same name) {{{1
+
+let s:common =<< trim EOL " {{{2
+  autodisplay
+  blend
+  blink
+  capslock
+  clearcolor
+  clipboard$
+  clipboardimage
+  controlchr
+  dest
+  display
+  font
+  fullscreen
+  mapunicode
+  memget
+  numlock
+  palettecolor
+  printmode
+  resize
+  screenicon
+  scrolllock
+  source
+EOL
+" }}}
+
+for c in s:common
+  exe 'syn match qb64Statement "\<' .. s:prefix .. c .. '\>" contains=qb64Underscore contained'
+  exe 'syn match qb64Function  "\<' .. s:prefix .. c .. '\>" contains=qb64Underscore'
+endfor
+
+" Keywords {{{1
+
+" Non-prefixed keywords {{{2
+" TIMER FREE
+" _DEPTH_BUFFER LOCK
+syn keyword qb64Keyword free lock
+
+let s:keywords  =<< trim EOL " {{{2
+  all
+  anticlockwise
+  behind
+  clear
+  clip
+  console
+  dontwait
+  explicit
+  explicitarray
+  fillbackground
+  hardware
+  hardware1
+  hide
+  keepbackground
+  middle
+  none
+  off
+  only
+  onlybackground
+  ontop
+  openconnection
+  openhost
+  preserve
+  seamless
+  smooth
+  smoothshrunk
+  smoothstretched
+  software
+  squarepixels
+  stretch
+  toggle
+EOL
+" }}}
+
+for k in s:keywords
+  exe 'syn match qb64Keyword "\<' .. s:prefix .. k .. '\>" contains=qb64Underscore'
+endfor
+
+syn match qb64Underscore "\<_" contained conceal transparent
+
+" Source QuickBASIC syntax {{{1
+runtime! syntax/basic.vim
+
+" add after the BASIC syntax file is sourced so cluster already exists
+syn cluster basicStatements	add=qb64Statement,qb64Metacommand,qb64IfMetacommand
+syn cluster basicLineIdentifier add=qb64LineLabel
+syn cluster qb64NotTop		contains=@basicNotTop,qb64Metavariable
+
+syn iskeyword @,48-57,.,_,!,#,$,%,&,`
+
+" Unsupported QuickBASIC features {{{1
+" TODO: add linux only missing features
+syn keyword qb64Unsupported alias any byval calls cdecl erdev erdev$ fileattr
+syn keyword qb64Unsupported fre ioctl ioctl$ pen play setmem signal uevent
+syn keyword qb64Unsupported tron troff
+syn match   qb64Unsupported "\<declare\%(\s\+\%(sub\|function\)\>\)\@="
+syn match   qb64Unsupported "\<\%(date\|time\)$\ze\s*=" " statements only
+syn match   qb64Unsupported "\<def\zs\s\+FN"
+syn match   qb64Unsupported "\<\%(exit\|end\)\s\+def\>"
+syn match   qb64Unsupported "\<width\s\+lprint\>"
+
+" Types {{{1
+syn keyword qb64Type _BIT _BYTE _FLOAT _INTEGER64 _MEM _OFFSET _UNSIGNED
+
+" Type suffixes {{{1
+if exists("basic_type_suffixes")
+  " TODO: handle leading word boundary and __+ prefix
+  syn match qb64TypeSuffix "\%(\a[[:alnum:]._]*\)\@<=\~\=`\%(\d\+\)\="
+  syn match qb64TypeSuffix "\%(\a[[:alnum:]._]*\)\@<=\~\=\%(%\|%%\|&\|&&\|%&\)"
+  syn match qb64TypeSuffix "\%(\a[[:alnum:]._]*\)\@<=\%(!\|##\|#\)"
+  syn match qb64TypeSuffix "\%(\a[[:alnum:]._]*\)\@<=$\%(\d\+\)\="
+endif
+
+" Numbers {{{1
+
+" Integers
+syn match qb64Number "-\=&b[01]\+&\>\="
+
+syn match qb64Number "-\=\<[01]\~\=`\>"
+syn match qb64Number "-\=\<\d\+`\d\+\>"
+
+syn match qb64Number "-\=\<\d\+\%(%%\|&&\|%&\)\>"
+syn match qb64Number  "\<\d\+\~\%(%%\|&&\|%&\)\>"
+
+syn match qb64Number "-\=\<&b[01]\+\%(%%\|&&\|%&\)\>"
+syn match qb64Number  "\<&b[01]\+\~\%(%%\|&&\|%&\)\>"
+
+syn match qb64Number "-\=\<&o\=\o\+\%(%%\|&&\|%&\)\>"
+syn match qb64Number  "\<&o\=\o\+\~\%(%%\|&&\|%&\)\>"
+
+syn match qb64Number "-\=\<&h\x\+\%(%%\|&&\|%&\)\>"
+syn match qb64Number  "\<&h\x\+\~\%(%%\|&&\|%&\)\>"
+
+" Floats
+syn match qb64Float "-\=\<\d\+\.\=\d*##\>"
+syn match qb64Float "-\=\<\.\d\+##\>"
+
+" Line numbers and labels {{{1
+syn match qb64LineLabel  "\%(_\{2,}\)\=\a[[:alnum:]._]*[[:alnum:]]\ze\s*:" nextgroup=@basicStatements skipwhite contained
+
+" Metacommands {{{1
+syn match qb64Metacommand contained "$NOPREFIX\>"
+syn match qb64Metacommand contained "$ASSERTS\%(:CONSOLE\)\=\>"
+syn match qb64Metacommand contained "$CHECKING:\%(ON\|OFF\)\>"
+syn match qb64Metacommand contained "$COLOR:\%(0\|32\)\>"
+syn match qb64Metacommand contained "$CONSOLE\%(:ONLY\)\=\>"
+syn match qb64Metacommand contained "$EXEICON\s*:\s*'[^']\+'"
+syn match qb64Metacommand contained "$ERROR\>"
+syn match qb64Metacommand contained "$LET\>"
+syn match qb64Metacommand contained "$RESIZE:\%(ON\|OFF\|STRETCH\|SMOOTH\)\>"
+syn match qb64Metacommand contained "$SCREEN\%(HIDE\|SHOW\)\>"
+syn match qb64Metacommand contained "$VERSIONINFO\s*:.*"
+syn match qb64Metacommand contained "$VIRTUALKEYBOARD:\%(ON\|OFF\)\>"
+
+syn region qb64IfMetacommand contained matchgroup=qb64Metacommand start="$\%(IF\|ELSEIF\)\>" end="\<THEN\>" oneline transparent contains=qb64Metavariable
+syn match  qb64Metacommand contained "$\%(ELSE\|END\s*IF\)\>"
+
+syn keyword qb64Metavariable contained defined undefined
+syn keyword qb64Metavariable contained windows win linux mac maxosx
+syn keyword qb64Metavariable contained 32bit 64bit version
+
+" Default Highlighting {{{1
+hi def link qb64Float	      basicFloat
+hi def link qb64Function      Function
+hi def link qb64Keyword       Keyword
+hi def link qb64LineLabel     basicLineLabel
+hi def link qb64Metacommand   PreProc
+hi def link qb64Metavariable  Identifier
+hi def link qb64Number	      basicNumber
+hi def link qb64Statement     Statement
+hi def link qb64TypeSuffix    basicTypeSuffix
+hi def link qb64Type	      Type
+hi def link qb64Unsupported   Error
+
+" Postscript {{{1
+let b:current_syntax = "qb64"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
--- a/runtime/syntax/strace.vim
+++ b/runtime/syntax/strace.vim
@@ -1,8 +1,7 @@
 " Vim syntax file
-" This is a GENERATED FILE. Please always refer to source file at the URI below.
 " Language: strace output
 " Maintainer: David Necas (Yeti) <yeti@physics.muni.cz>
-" Last Change: 2015-01-16
+" Last Change: 2022 Jan 29
 
 " Setup
 " quit when a syntax file was already loaded
--- a/src/testdir/README.txt
+++ b/src/testdir/README.txt
@@ -55,7 +55,7 @@ OLD STYLE TESTS:
 There are a few tests that are used when Vim was built without the +eval
 feature.  These cannot use the "assert" functions, therefore they consist of a
 .in file that contains Normal mode commands between STARTTEST and ENDTEST.
-They modify the file and the result gets writtein in the test.out file.  This
+They modify the file and the result gets written in the test.out file.  This
 is then compared with the .ok file.  If they are equal the test passed.  If
 they differ the test failed.