patch 8.2.1826: Vim9: cannot use a {} block at script level

Problem:    Vim9: cannot use a {} block at script level.
Solution:   Recognize a {} block.
diff --git a/src/errors.h b/src/errors.h
index cddd691..c2dc633 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -278,4 +278,6 @@
 	INIT(= N_("E1126: Cannot use :let in Vim9 script"));
 EXTERN char e_missing_name_after_dot[]
 	INIT(= N_("E1127: Missing name after dot"));
+EXTERN char e_endblock_without_block[]
+	INIT(= N_("E1128: } without {"));
 #endif
diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h
index 0f9eb39..2e59d2c 100644
--- a/src/ex_cmdidxs.h
+++ b/src/ex_cmdidxs.h
@@ -69,4 +69,4 @@
   /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
 };
 
-static const int command_count = 571;
+static const int command_count = 573;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 0c83f52..0b52c11 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1812,6 +1812,12 @@
 EXCMD(CMD_at,		"@",		ex_at,
 	EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
 	ADDR_LINES),
+EXCMD(CMD_block,	"{{{{{{{{",	ex_block,  // not found normally
+	0,
+	ADDR_NONE),
+EXCMD(CMD_endblock,	"}",		ex_endblock,
+	EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
+	ADDR_NONE),
 EXCMD(CMD_tilde,	"~",		ex_substitute,
 	EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
 	ADDR_LINES),
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 310934e..4a71989 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3222,7 +3222,7 @@
 		*p == '('
 		    || (p == eap->cmd
 			? (
-			    // "{..." is an dict expression.
+			    // "{..." is a dict expression or block start.
 			    *eap->cmd == '{'
 			    // "'string'->func()" is an expression.
 			 || *eap->cmd == '\''
@@ -3234,6 +3234,12 @@
 			    // "varname->func()" is an expression.
 			: (*p == '-' && p[1] == '>')))
 	    {
+		if (*eap->cmd == '{' && ends_excmd(*skipwhite(eap->cmd + 1)))
+		{
+		    // "{" by itself is the start of a block.
+		    eap->cmdidx = CMD_block;
+		    return eap->cmd + 1;
+		}
 		eap->cmdidx = CMD_eval;
 		return eap->cmd;
 	    }
@@ -3355,7 +3361,7 @@
 	}
 
 	// check for non-alpha command
-	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
+	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL)
 	    ++p;
 	len = (int)(p - eap->cmd);
 	if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
diff --git a/src/ex_eval.c b/src/ex_eval.c
index d205caf..57c6178 100644
--- a/src/ex_eval.c
+++ b/src/ex_eval.c
@@ -1002,7 +1002,7 @@
     did_endif = TRUE;
     if (cstack->cs_idx < 0
 	    || (cstack->cs_flags[cstack->cs_idx]
-					   & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+				& (CSF_WHILE | CSF_FOR | CSF_TRY | CSF_BLOCK)))
 	eap->errmsg = _(e_endif_without_if);
     else
     {
@@ -1043,7 +1043,7 @@
 
     if (cstack->cs_idx < 0
 	    || (cstack->cs_flags[cstack->cs_idx]
-					   & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+				& (CSF_WHILE | CSF_FOR | CSF_TRY | CSF_BLOCK)))
     {
 	if (eap->cmdidx == CMD_else)
 	{
@@ -1375,6 +1375,37 @@
     }
 }
 
+/*
+ * "{" start of a block in Vim9 script
+ */
+    void
+ex_block(exarg_T *eap)
+{
+    cstack_T	*cstack = eap->cstack;
+
+    if (cstack->cs_idx == CSTACK_LEN - 1)
+	eap->errmsg = _("E579: block nesting too deep");
+    else
+    {
+	enter_block(cstack);
+	cstack->cs_flags[cstack->cs_idx] = CSF_BLOCK | CSF_ACTIVE | CSF_TRUE;
+    }
+}
+
+/*
+ * "}" end of a block in Vim9 script
+ */
+    void
+ex_endblock(exarg_T *eap)
+{
+    cstack_T	*cstack = eap->cstack;
+
+    if (cstack->cs_idx < 0
+	    || (cstack->cs_flags[cstack->cs_idx] & CSF_BLOCK) == 0)
+	eap->errmsg = _(e_endblock_without_block);
+    else
+	leave_block(cstack);
+}
 
 /*
  * ":throw expr"
diff --git a/src/proto/ex_eval.pro b/src/proto/ex_eval.pro
index 929f479..f186161 100644
--- a/src/proto/ex_eval.pro
+++ b/src/proto/ex_eval.pro
@@ -20,6 +20,8 @@
 void ex_continue(exarg_T *eap);
 void ex_break(exarg_T *eap);
 void ex_endwhile(exarg_T *eap);
+void ex_block(exarg_T *eap);
+void ex_endblock(exarg_T *eap);
 void ex_throw(exarg_T *eap);
 void do_throw(cstack_T *cstack);
 void ex_try(exarg_T *eap);
diff --git a/src/structs.h b/src/structs.h
index 094b736..103c70c 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -907,6 +907,7 @@
 # define CSF_ELSE	0x0004	// ":else" has been passed
 # define CSF_WHILE	0x0008	// is a ":while"
 # define CSF_FOR	0x0010	// is a ":for"
+# define CSF_BLOCK	0x0020	// is a "{" block
 
 # define CSF_TRY	0x0100	// is a ":try"
 # define CSF_FINALLY	0x0200	// ":finally" has been passed
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 466b2d0..1edc773 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2733,6 +2733,27 @@
       echo one
   END
   CheckScriptFailure(lines, 'E121:', 6)
+
+  lines =<< trim END
+      vim9script
+      {
+        var one = 'one'
+        assert_equal('one', one)
+      }
+      assert_false(exists('one'))
+      assert_false(exists('s:one'))
+  END
+  CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      {
+        var one = 'one'
+        echo one
+      }
+      echo one
+  END
+  CheckScriptFailure(lines, 'E121:', 6)
 enddef
 
 " Keep this last, it messes up highlighting.
diff --git a/src/version.c b/src/version.c
index 789e104..6ff2aa0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1826,
+/**/
     1825,
 /**/
     1824,