From de65a162dc402df0e052c9a6e79a533a00036902 Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Mon, 6 May 2019 19:00:13 +0000 Subject: [PATCH] Implicitly support abbreviating commands Match entered commands against initial substrings of a sorted list of command keywords, effectively supporting abbreviated commands. Also test it works. --- mudpy/command.py | 5 +---- mudpy/misc.py | 29 +++++++++++++++++++++-------- mudpy/tests/selftest.py | 7 +++++++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/mudpy/command.py b/mudpy/command.py index 1138aa8..95fb793 100644 --- a/mudpy/command.py +++ b/mudpy/command.py @@ -148,10 +148,7 @@ def help(actor, parameters): if parameters and actor.owner: # is the command word one for which we have data? - if parameters in actor.universe.groups["command"]: - command = actor.universe.groups["command"][parameters] - else: - command = None + command = mudpy.misc.find_command(parameters) # only for allowed commands if actor.can_run(command): diff --git a/mudpy/misc.py b/mudpy/misc.py index 50a9456..501d5b4 100644 --- a/mudpy/misc.py +++ b/mudpy/misc.py @@ -1474,6 +1474,25 @@ def check_for_connection(listening_socket): return user +def find_command(command_name): + """Try to find a command by name or abbreviation.""" + + # lowercase the command + command_name = command_name.lower() + + command = None + if command_name in universe.groups["command"]: + # the command matches a command word for which we have data + command = universe.groups["command"][command_name] + else: + for candidate in sorted(universe.groups["command"]): + if candidate.startswith(command_name): + # the command matches the start of a command word + command = universe.groups["command"][candidate] + break + return command + + def get_menu(state, error=None, choices=None): """Show the correct menu text to a user.""" @@ -1864,14 +1883,8 @@ def handler_active(user): else: command_name, parameters = first_word(input_data) - # lowercase the command - command_name = command_name.lower() - - # the command matches a command word for which we have data - if command_name in universe.groups["command"]: - command = universe.groups["command"][command_name] - else: - command = None + # expand to an actual command + command = find_command(command_name) # if it's allowed, do it if actor.can_run(command): diff --git a/mudpy/tests/selftest.py b/mudpy/tests/selftest.py index b73c13e..520f2fd 100644 --- a/mudpy/tests/selftest.py +++ b/mudpy/tests/selftest.py @@ -215,6 +215,12 @@ test_admin_help = ( (2, "This will save all active accounts", ""), ) +test_abbrev = ( + (0, "> ", "help mov"), + (0, r"Move in a specific direction\.", "mov north"), + (0, r"You exit to the north\.", ""), +) + test_reload = ( (2, "> ", "reload"), (2, r"Reloading all code modules, configs and data\." @@ -334,6 +340,7 @@ dialogue = ( (test_telnet_unknown_option, "log unknown telnet option"), (test_admin_restriction, "restricted admin commands"), (test_admin_help, "admin help"), + (test_abbrev, "command abbreviation"), (test_reload, "reload"), (test_set_facet, "set facet"), (test_set_refused, "refuse altering read-only element"), -- 2.11.0