diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index d1b8f4eb47..fdc3d279c9 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -1223,6 +1223,38 @@ class TestCmdParser(TestCase): self.assertEqual(cmdparser.try_num_differentiators("look me-3"), (3, "look me")) self.assertEqual(cmdparser.try_num_differentiators("look me-567"), (567, "look me")) + def test_num_differentiators_hyphenated_names(self): + """Test that hyphenated object names like 't-shirt-1' are parsed correctly. + + This tests the default SEARCH_MULTIMATCH_REGEX which uses the format 'name-number'. + Objects with hyphens in their names (e.g., 't-shirt') should be correctly parsed + when disambiguated (e.g., 't-shirt-1' should return (1, 't-shirt')). + + See: https://github.com/evennia/evennia/issues/3691 + """ + # Simple name without hyphen - should work + self.assertEqual(cmdparser.try_num_differentiators("ball-1"), (1, "ball")) + self.assertEqual(cmdparser.try_num_differentiators("ball-23"), (23, "ball")) + + # Hyphenated name - this is the bug case + self.assertEqual(cmdparser.try_num_differentiators("t-shirt-1"), (1, "t-shirt")) + self.assertEqual(cmdparser.try_num_differentiators("t-shirt-2"), (2, "t-shirt")) + + # Multiple hyphens in name + self.assertEqual( + cmdparser.try_num_differentiators("some-long-name-3"), (3, "some-long-name") + ) + + # No number suffix - should return (None, None) + self.assertEqual(cmdparser.try_num_differentiators("t-shirt"), (None, None)) + self.assertEqual(cmdparser.try_num_differentiators("ball"), (None, None)) + + # With trailing args (space after the number) + self.assertEqual(cmdparser.try_num_differentiators("t-shirt-1 arg"), (1, "t-shirt arg")) + self.assertEqual( + cmdparser.try_num_differentiators("ball-2 some args"), (2, "ball some args") + ) + @override_settings( SEARCH_MULTIMATCH_REGEX=r"(?P[0-9]+)-(?P.*)", CMD_IGNORE_PREFIXES="@&/+" ) diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 16e15c1649..835462c1ca 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -357,16 +357,16 @@ WEBCLIENT_OPTIONS = { # The command parser module to use. See the default module for which # functions it must implement COMMAND_PARSER = "evennia.commands.cmdparser.cmdparser" -# On a multi-match when search objects or commands, the user has the +# On a multi-match when searching objects or commands, the user has the # ability to search again with an index marker that differentiates -# the results. If multiple "box" objects -# are found, they can by default be separated as 1-box, 2-box. Below you -# can change the regular expression used. The regex must have one -# have two capturing groups (?P...) and (?P...) - the default -# parser expects this. It should also involve a number starting from 1. -# When changing this you must also update SEARCH_MULTIMATCH_TEMPLATE +# the results. If multiple "box" objects are found, they can by default +# be separated as box-1, box-2. Below you can change the regular expression +# used. The regex must have two capturing groups (?P...) and +# (?P...) - the default parser expects this. It may also have an +# optional (?P...) group. It should also involve a number starting +# from 1. When changing this you must also update SEARCH_MULTIMATCH_TEMPLATE # to properly describe the syntax. -SEARCH_MULTIMATCH_REGEX = r"(?P[^-]*)-(?P[0-9]+)(?P.*)" +SEARCH_MULTIMATCH_REGEX = r"^(?P.*?)-(?P[0-9]+)(?P(?:\s.*)?)$" # To display multimatch errors in various listings we must display # the syntax in a way that matches what SEARCH_MULTIMATCH_REGEX understand. # The template will be populated with data and expects the following markup: