patch 9.2.0541: Vim9: endclass/endenum/endinterface can give errors
Commit:
https://github.com/vim/vim/commit/207039097a214fb64fce18f5675152ae45a1e37c
Author: Peter Kenny <[email protected]>
Date: Tue May 26 19:02:20 2026 +0000
patch 9.2.0541: Vim9: endclass/endenum/endinterface can give errors
Problem: Vim9: ":endclass", ":endenum" and ":endinterface" can give a
"command cannot be shortened" error, because the full-name
check compares against the line start instead of the command
word.
Solution: Skip a leading colon and white space before checking the end
command name, update tests (Peter Kenny).
related: #20032
related: #20191
closes: #20253
Signed-off-by: Peter Kenny <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 35b87b208..e49e5a8dc 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -1,4 +1,4 @@
-" Test Vim9 classes
+" Tests for Vim9 script classes
import './util/vim9.vim' as v9
@@ -50,6 +50,14 @@ def Test_class_basic()
END
v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
+ # "endclass" cannot be shortened (variant incl. whitespace and colon)
+ lines =<< trim END
+ vim9script
+ class Something
+ : endcla
+ END
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcla', 3)
+
# Additional words after "endclass"
lines =<< trim END
vim9script
@@ -11869,4 +11877,19 @@ func Test_class_member_lambda()
call v9.CheckSourceSuccess(lines)
endfunc
+" Test for colon and whitespace before class, endclass, static, and abstract
+def Test_colon_whitespace()
+ var lines =<< trim END
+ : vim9script
+ : class C
+ # TODO: Fix :public - gives E1065
+ # : public var p = true
+ : static var s = true
+ : endclass
+ : abstract class A
+ : endclass
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_enum.vim b/src/testdir/test_vim9_enum.vim
index be4c8f6d5..4e05c8668 100644
--- a/src/testdir/test_vim9_enum.vim
+++ b/src/testdir/test_vim9_enum.vim
@@ -1,8 +1,8 @@
-" Test Vim9 enums
+" Tests for Vim9 script enums
import './util/vim9.vim' as v9
-" Test for parsing an enum definition
+" Test for parsing an enum definition {{{1
def Test_enum_parse()
# enum supported only in a Vim9 script
var lines =<< trim END
@@ -11,6 +11,14 @@ def Test_enum_parse()
END
v9.CheckSourceFailure(lines, 'E1414: Enum can only be defined in Vim9
script', 1)
+ # ":enum" and ":endenum"
+ lines =<< trim END
+ vim9script
+ :enum Foo
+ :endenum
+ END
+ v9.CheckSourceSuccess(lines)
+
# First character in an enum name should be capitalized.
lines =<< trim END
vim9script
@@ -46,10 +54,10 @@ def Test_enum_parse()
# The complete "enum" should be specified.
lines =<< trim END
vim9script
- enu Something
+ enu Nah
endenum
END
- v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enu', 2)
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enu Nah',
2)
# The complete "endenum" should be specified.
lines =<< trim END
@@ -59,6 +67,14 @@ def Test_enum_parse()
END
v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enden', 3)
+ # "endenum" cannot be shortened (variant incl. whitespace and colon)
+ lines =<< trim END
+ vim9script
+ enum NoAbbrev
+ : endenu
+ END
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endenu', 3)
+
# Only the complete word "endenum" should be recognized
lines =<< trim END
vim9script
@@ -271,6 +287,16 @@ def Test_enum_parse()
END
v9.CheckSourceFailure(lines, 'E1418: Invalid enum value declaration: $%@', 4)
+ # Additional command after "enumvalue"
+ lines =<< trim END
+ vim9script
+ enum NoAdditionalCmd
+ One, | var y = 10
+ Two
+ endenum
+ END
+ v9.CheckSourceFailure(lines, "E1418: Invalid enum value declaration: | var y
= 10", 3)
+
# Duplicate enum value
lines =<< trim END
vim9script
@@ -352,6 +378,7 @@ def Test_enum_parse()
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: n:
number = 10', 3)
enddef
+" Test for basic enum declaration and errors {{{1
def Test_basic_enum()
# Declare a simple enum
var lines =<< trim END
@@ -493,7 +520,7 @@ def Test_basic_enum()
v9.CheckSourceFailure(lines, 'E1421: Enum "Fruit" cannot be used as a
value', 6)
enddef
-" Test for type() and typename() of an enum
+" Test for type() and typename() of an enum {{{1
def Test_enum_type()
var lines =<< trim END
vim9script
@@ -525,7 +552,7 @@ def Test_enum_type()
v9.CheckSourceSuccess(lines)
enddef
-" Try modifying an enum or an enum item
+" Test for trying to modify an enum or an enum item {{{1
def Test_enum_modify()
# Try assigning an unsupported value to an enum
var lines =<< trim END
@@ -652,7 +679,7 @@ def Test_enum_modify()
v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be
modified', 1)
enddef
-" Test for using enum in an expression
+" Test for using enum in an expression {{{1
def Test_enum_expr()
var lines =<< trim END
vim9script
@@ -691,7 +718,7 @@ def Test_enum_expr()
v9.CheckSourceFailure(lines, 'E1425: Using an Enum "Color" as a String', 5)
enddef
-" Using an enum in a lambda function
+" Test for using an enum in a lambda function {{{1
def Test_enum_lambda()
var lines =<< trim END
vim9script
@@ -708,7 +735,7 @@ def Test_enum_lambda()
v9.CheckSourceSuccess(lines)
enddef
-" Comparison using enums
+" Test for comparison using enums {{{1
def Test_enum_compare()
var lines =<< trim END
vim9script
@@ -761,7 +788,7 @@ def Test_enum_compare()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using an enum as a default argument to a function
+" Test for using an enum as a default argument to a function {{{1
def Test_enum_default_arg()
var lines =<< trim END
vim9script
@@ -777,7 +804,7 @@ def Test_enum_default_arg()
v9.CheckSourceSuccess(lines)
enddef
-" Test for enum garbage collection
+" Test for enum garbage collection {{{1
func Test_enum_garbagecollect()
let lines =<< trim END
vim9script
@@ -826,7 +853,7 @@ func Test_enum_garbagecollect()
call v9.CheckSourceSuccess(lines)
endfunc
-" Test for the enum values class variable
+" Test for the enum values class variable {{{1
def Test_enum_values()
var lines =<< trim END
vim9script
@@ -912,7 +939,7 @@ def Test_enum_values()
v9.CheckSourceSuccess(lines)
enddef
-" Test comments in enums
+" Test for using comments in enums {{{1
def Test_enum_comments()
var lines =<< trim END
vim9script
@@ -951,7 +978,7 @@ def Test_enum_comments()
v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 4)
enddef
-" Test trailing whitespace after enum values
+" Test for trailing whitespace after enum values {{{1
def Test_enum_whitespace()
var lines =<< trim END
vim9script
@@ -966,7 +993,7 @@ def Test_enum_whitespace()
lines =<< trim END
vim9script
enum Car
- Honda(),
+ Honda(),
Ford()
endenum
defcompile
@@ -974,7 +1001,7 @@ def Test_enum_whitespace()
v9.CheckSourceSuccess(lines)
enddef
-" Test string() with enums
+" Test for using string() with enums {{{1
def Test_enum_string()
var lines =<< trim END
vim9script
@@ -1004,7 +1031,7 @@ def Test_enum_string()
v9.CheckSourceSuccess(lines)
enddef
-" Test for importing an enum
+" Test for importing an enum {{{1
def Test_enum_import()
var lines =<< trim END
vim9script
@@ -1040,7 +1067,7 @@ def Test_enum_import()
v9.CheckScriptSuccess(lines)
enddef
-" Test for using test_refcount() with enum
+" Test for using test_refcount() with enum {{{1
def Test_enum_refcount()
var lines =<< trim END
vim9script
@@ -1099,7 +1126,7 @@ def Test_enum_refcount()
v9.CheckSourceSuccess(lines)
enddef
-" Test for defining an enum with additional object variables and methods
+" Test for defining an enum with additional object variables and methods {{{1
def Test_enum_enhanced()
var lines =<< trim END
vim9script
@@ -1140,7 +1167,7 @@ def Test_enum_enhanced()
v9.CheckSourceSuccess(lines)
enddef
-" Test for the enum value 'name' variable
+" Test for the enum value 'name' variable {{{1
def Test_enum_name()
# Check the names of enum values
var lines =<< trim END
@@ -1221,7 +1248,7 @@ def Test_enum_name()
v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: name', 4)
enddef
-" Test for the enum value 'ordinal' variable
+" Test for the enum value 'ordinal' variable {{{1
def Test_enum_ordinal()
# Check the ordinal values of enum items
var lines =<< trim END
@@ -1302,7 +1329,7 @@ def Test_enum_ordinal()
v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: ordinal', 4)
enddef
-" Test for trying to create a new enum object using the constructor
+" Test for trying to create a new enum object using the constructor {{{1
def Test_enum_invoke_constructor()
var lines =<< trim END
vim9script
@@ -1360,7 +1387,7 @@ def Test_enum_invoke_constructor()
v9.CheckSourceFailureList(lines, ['E1100:', 'E1100:'], 1)
enddef
-" Test for checking "this" in an enum constructor
+" Test for checking "this" in an enum constructor {{{1
def Test_enum_this_in_constructor()
var lines =<< trim END
vim9script
@@ -1378,7 +1405,7 @@ def Test_enum_this_in_constructor()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using member variables in an enum object
+" Test for using member variables in an enum object {{{1
def Test_enum_object_variable()
var lines =<< trim END
vim9script
@@ -1483,7 +1510,7 @@ def Test_enum_object_variable()
v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new',
8)
enddef
-" Test for using a custom constructor with an enum
+" Test for using a custom constructor with an enum {{{1
def Test_enum_custom_constructor()
# space before "("
var lines =<< trim END
@@ -1556,7 +1583,7 @@ def Test_enum_custom_constructor()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using class variables in an enum class
+" Test for using class variables in an enum class {{{1
def Test_enum_class_variable()
var lines =<< trim END
vim9script
@@ -1571,7 +1598,7 @@ def Test_enum_class_variable()
v9.CheckSourceSuccess(lines)
enddef
-" Test for converting a string to an enum value
+" Test for converting a string to an enum value {{{1
def Test_enum_eval()
var lines =<< trim END
vim9script
@@ -1588,7 +1615,7 @@ def Test_enum_eval()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using "values" in an enum class variable
+" Test for using "values" in an enum class variable {{{1
def Test_use_enum_values_in_class_variable()
var lines =<< trim END
vim9script
@@ -1601,7 +1628,7 @@ def Test_use_enum_values_in_class_variable()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using lambda block in enums
+" Test for using lambda block in enums {{{1
def Test_lambda_block_in_enum()
# This used to crash Vim
var lines =<< trim END
@@ -1632,7 +1659,7 @@ def Test_lambda_block_in_enum()
v9.CheckScriptSuccess(lines)
enddef
-" Echo an enum
+" Test for echoing an enum {{{1
def Test_enum_echo()
var lines =<< trim END
vim9script
@@ -1647,8 +1674,8 @@ def Test_enum_echo()
v9.CheckScriptSuccess(lines)
enddef
-" Test for garbage collecting an enum with a complex member variables.
-func Test_class_selfref_gc()
+" Test for garbage collecting an enum with a complex member variables {{{1
+func Test_enum_selfref_gc()
let lines =<< trim END
vim9script
enum Foo
@@ -1664,7 +1691,7 @@ func Test_class_selfref_gc()
call v9.CheckSourceSuccess(lines)
endfunc
-" Test for defining an enum in a function
+" Test for defining an enum in a function {{{1
def Test_enum_defined_in_function()
var lines =<< trim END
vim9script
@@ -1678,5 +1705,5 @@ def Test_enum_defined_in_function()
END
v9.CheckScriptFailure(lines, 'E1435: Enum can only be used in a script', 2)
enddef
-
+" }}}
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_interface.vim
b/src/testdir/test_vim9_interface.vim
index 742b871f1..6377eb38e 100644
--- a/src/testdir/test_vim9_interface.vim
+++ b/src/testdir/test_vim9_interface.vim
@@ -1,8 +1,8 @@
-" Tests for Vim9 interface
+" Tests for Vim9 script interfaces
import './util/vim9.vim' as v9
-" Tests for basic interface declaration and errors
+" Test for basic interface declaration and errors {{{1
def Test_interface_basics()
var lines =<< trim END
vim9script
@@ -13,6 +13,14 @@ def Test_interface_basics()
END
v9.CheckSourceSuccess(lines)
+ # ":interface" and ":endinterface"
+ lines =<< trim END
+ vim9script
+ :interface I
+ :endinterface
+ END
+ v9.CheckSourceSuccess(lines)
+
lines =<< trim END
interface SomethingWrong
static var count = 7
@@ -78,6 +86,14 @@ def Test_interface_basics()
END
v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endin', 3)
+ # "endinterface" cannot be shortened (variant incl. whitespace and colon)
+ lines =<< trim END
+ vim9script
+ interface Short
+ : endint
+ END
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endint', 3)
+
# Additional commands after "interface name"
lines =<< trim END
vim9script
@@ -86,6 +102,14 @@ def Test_interface_basics()
END
v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
+ # Additional command after "endinterface"
+ lines =<< trim END
+ vim9script
+ interface NoTrailingCmd
+ endinterface | echo 'no'
+ END
+ v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'no'", 3)
+
lines =<< trim END
vim9script
export interface EnterExit
@@ -124,6 +148,7 @@ def Test_interface_basics()
v9.CheckScriptSuccess(lines)
enddef
+" Test for mismatched end command for class and interface {{{1
def Test_class_interface_wrong_end()
var lines =<< trim END
vim9script
@@ -142,7 +167,7 @@ def Test_class_interface_wrong_end()
v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected
endinterface', 4)
enddef
-" Test for using string() with an interface
+" Test for using string() with an interface {{{1
def Test_interface_to_string()
var lines =<< trim END
vim9script
@@ -154,6 +179,7 @@ def Test_interface_to_string()
v9.CheckSourceSuccess(lines)
enddef
+" Test for a class implementing an interface {{{1
def Test_class_implements_interface()
var lines =<< trim END
vim9script
@@ -281,13 +307,21 @@ def Test_class_implements_interface()
END
v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
- # Trailing characters after a class name
+ # Trailing characters after an interface name
lines =<< trim END
vim9script
- class A bbb
- endclass
+ interface I nah
+ endinterface
END
- v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
+ v9.CheckSourceFailure(lines, 'E488: Trailing characters: nah', 2)
+
+ # Additional words after "endinterface"
+ lines =<< trim END
+ vim9script
+ interface NoTrailingChars
+ endinterface nah
+ END
+ v9.CheckSourceFailure(lines, "E488: Trailing characters: nah", 3)
# using "implements" with a non-existing class
lines =<< trim END
@@ -519,6 +553,7 @@ def Test_class_implements_interface()
v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
enddef
+" Test for calling a method via an interface-typed variable {{{1
def Test_call_interface_method()
var lines =<< trim END
vim9script
@@ -639,7 +674,7 @@ def Test_call_interface_method()
v9.CheckSourceSuccess(lines)
enddef
-" Test for implementing an imported interface
+" Test for implementing an imported interface {{{1
def Test_implement_imported_interface()
var lines =<< trim END
vim9script
@@ -671,7 +706,7 @@ def Test_implement_imported_interface()
v9.CheckScriptSuccess(lines)
enddef
-" Test for changing the member access of an interface in a implementation class
+" Test for changing the member access of an interface in a implementation
class {{{1
def Test_change_interface_member_access()
var lines =<< trim END
vim9script
@@ -696,7 +731,7 @@ def Test_change_interface_member_access()
v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of
interface "A" is different', 7)
enddef
-" Test for using a interface method using a child object
+" Test for using a interface method using a child object {{{1
def Test_interface_method_from_child()
var lines =<< trim END
vim9script
@@ -732,8 +767,8 @@ def Test_interface_method_from_child()
v9.CheckSourceSuccess(lines)
enddef
-" Test for using an interface method using a child object when it is overridden
-" by the child class.
+" Test for using an interface method using a child object when ... {{{1
+" it is overridden by the child class.
def Test_interface_overridden_method_from_child()
var lines =<< trim END
vim9script
@@ -772,7 +807,7 @@ def Test_interface_overridden_method_from_child()
v9.CheckSourceSuccess(lines)
enddef
-" Test for interface inheritance
+" Test for interface inheritance {{{1
def Test_interface_inheritance()
var lines =<< trim END
vim9script
@@ -880,8 +915,8 @@ def Test_interface_inheritance()
v9.CheckSourceSuccess(lines)
enddef
-" A interface cannot have a static variable or a static method or a protected
-" variable or a protected method or a public variable
+" Test for an interface cannot have a static variable/method ... {{{1
+" a protected variable/method, or a public variable
def Test_interface_with_unsupported_members()
var lines =<< trim END
vim9script
@@ -956,7 +991,7 @@ def Test_interface_with_unsupported_members()
v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an
interface', 3)
enddef
-" Test for extending an interface
+" Test for extending an interface {{{1
def Test_extend_interface()
var lines =<< trim END
vim9script
@@ -1079,8 +1114,8 @@ def Test_extend_interface()
v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch,
expected number but got string', 11)
enddef
-" Test for a child class implementing an interface when some of the methods are
-" defined in the parent class.
+" Test for a child class implementing an interface when some ... {{{1
+" of the methods are defined in the parent class
def Test_child_class_implements_interface()
var lines =<< trim END
vim9script
@@ -1263,7 +1298,7 @@ def Test_child_class_implements_interface()
v9.CheckSourceFailure(lines, 'E1382: Variable "var3": type mismatch,
expected list<dict<number>> but got list<dict<string>>', 22)
enddef
-" Test for extending an interface with duplicate variables and methods
+" Test for extending an interface with duplicate variables and methods {{{1
def Test_interface_extends_with_dup_members()
var lines =<< trim END
vim9script
@@ -1304,8 +1339,8 @@ def Test_interface_extends_with_dup_members()
v9.CheckSourceSuccess(lines)
enddef
-" Test for implementing an interface with different ordering for the interface
-" member variables.
+" Test for implementing an interface with different ordering for {{{1
+" the interface member variables
def Test_implement_interface_with_different_variable_order()
var lines =<< trim END
vim9script
@@ -1329,7 +1364,7 @@ def
Test_implement_interface_with_different_variable_order()
v9.CheckSourceSuccess(lines)
enddef
-" Test for inheriting interfaces from an imported super class
+" Test for inheriting interfaces from an imported super class {{{1
def Test_interface_inheritance_with_imported_super()
var lines =<< trim END
vim9script
@@ -1367,7 +1402,7 @@ def Test_interface_inheritance_with_imported_super()
v9.CheckSourceSuccess(lines)
enddef
-" Test for defining an interface in a function
+" Test for defining an interface in a function {{{1
def Test_interface_defined_in_function()
var lines =<< trim END
vim9script
@@ -1381,8 +1416,8 @@ def Test_interface_defined_in_function()
v9.CheckScriptFailure(lines, 'E1436: Interface can only be used in a
script', 2)
enddef
-" Test for using "any" type for a variable in a sub-class while it has a
-" concrete type in the interface
+" Test for using "any" type for a variable in a sub-class while ... {{{1
+" it has a concrete type in the interface
def Test_implements_using_var_type_any()
var lines =<< trim END
vim9script
@@ -1411,7 +1446,7 @@ def Test_implements_using_var_type_any()
v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected
list<dict<string>> but got dict<number>', 1)
enddef
-" Test interface garbage collection
+" Test interface garbage collection {{{1
func Test_interface_garbagecollect()
let lines =<< trim END
vim9script
@@ -1455,5 +1490,5 @@ func Test_interface_garbagecollect()
END
call v9.CheckSourceSuccess(lines)
endfunc
-
+" }}}
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index bee5c589c..6b9c13f39 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 541,
/**/
540,
/**/
diff --git a/src/vim9class.c b/src/vim9class.c
index bc10ce8b0..908fb95a3 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -2230,10 +2230,14 @@ early_ret:
fullen = 12;
}
+ // skip ':' and blanks
+ for (; VIM_ISWHITE(*p) || *p == ':'; ++p)
+ ;
+ char_u *cmd_start = p;
if (checkforcmd(&p, end_name, shortlen))
{
- if (STRNCMP(line, end_name, fullen) != 0)
- semsg(_(e_command_cannot_be_shortened_str), line);
+ if (STRNCMP(cmd_start, end_name, fullen) != 0)
+ semsg(_(e_command_cannot_be_shortened_str), cmd_start);
else if (*p == '|' || !ends_excmd2(line, p))
semsg(_(e_trailing_characters_str), p);
else
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1wRxF3-007xL9-6x%40256bit.org.