diff --git a/src/mudlib/commands/help.py b/src/mudlib/commands/help.py index 84e46bb..e75c323 100644 --- a/src/mudlib/commands/help.py +++ b/src/mudlib/commands/help.py @@ -19,10 +19,33 @@ async def _show_command_detail(player: Player, command_name: str) -> None: """ from mudlib.combat.commands import combat_moves - # Look up the command in registry + # Look up the command in registry - exact match first defn = _registry.get(command_name) - # If not in registry, check if it's a combat move name (like "punch left") + # If not found, try prefix matching + if defn is None: + prefix_matches = [key for key in _registry if key.startswith(command_name)] + + # Deduplicate by CommandDefinition identity + unique_defns = {} + for key in prefix_matches: + defn_obj = _registry[key] + unique_defns[id(defn_obj)] = defn_obj + + if len(unique_defns) == 1: + # Unique match via prefix + defn = next(iter(unique_defns.values())) + elif len(unique_defns) > 1: + # Multiple matches - show disambiguation + names = sorted([d.name for d in unique_defns.values()]) + if len(names) == 2: + msg = f"{names[0]} or {names[1]}?\r\n" + else: + msg = f"{', '.join(names[:-1])}, or {names[-1]}?\r\n" + await player.send(msg) + return + + # If still not in registry, check if it's a combat move name (like "punch left") if defn is None: move = combat_moves.get(command_name) if move is not None: diff --git a/tests/test_combat_moves.py b/tests/test_combat_moves.py index 1f433b9..6ef88a8 100644 --- a/tests/test_combat_moves.py +++ b/tests/test_combat_moves.py @@ -476,9 +476,3 @@ def test_load_content_combat_directory(): assert "sweep" in moves assert "duck" in moves assert "jump" in moves - - # Verify aliases - assert "pl" in moves - assert moves["pl"] is moves["punch left"] - assert "pr" in moves - assert moves["pr"] is moves["punch right"] diff --git a/tests/test_commands_list.py b/tests/test_commands_list.py index 502e299..3eadfbf 100644 --- a/tests/test_commands_list.py +++ b/tests/test_commands_list.py @@ -229,7 +229,7 @@ async def test_commands_detail_unknown_command(player): @pytest.mark.asyncio async def test_commands_detail_via_prefix(player, combat_moves): """Test commands detail view via prefix matching.""" - await commands.dispatch(player, "commands rh") + await commands.dispatch(player, "commands ro") output = "".join([call[0][0] for call in player.writer.write.call_args_list]) # Should show the full command details via prefix match