Add prefix-ignorer. This will identify allow users to target a command using both cmd, @cmd, +cmd etc. If there are two different commands @cmd and cmd, entering @cmd will still explicitly target the former. Single-character commands consisting of only an ignore-character will not be ignored. Configure and turn off using settings.CMD_PREFIX_IGNORE.
This commit is contained in:
parent
1b3fb8fca9
commit
596efe4c72
2 changed files with 58 additions and 24 deletions
|
|
@ -12,6 +12,7 @@ from django.conf import settings
|
||||||
from evennia.utils.logger import log_trace
|
from evennia.utils.logger import log_trace
|
||||||
|
|
||||||
_MULTIMATCH_REGEX = re.compile(settings.SEARCH_MULTIMATCH_REGEX, re.I + re.U)
|
_MULTIMATCH_REGEX = re.compile(settings.SEARCH_MULTIMATCH_REGEX, re.I + re.U)
|
||||||
|
_CMD_IGNORE_PREFIXES = settings.CMD_IGNORE_PREFIXES
|
||||||
|
|
||||||
def cmdparser(raw_string, cmdset, caller, match_index=None):
|
def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -69,23 +70,29 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||||
args = string[cmdlen:]
|
args = string[cmdlen:]
|
||||||
return (cmdname, args, cmdobj, cmdlen, mratio)
|
return (cmdname, args, cmdobj, cmdlen, mratio)
|
||||||
|
|
||||||
if not raw_string:
|
def build_matches(raw_string, include_prefixes=False):
|
||||||
return []
|
|
||||||
|
|
||||||
matches = []
|
|
||||||
|
|
||||||
# match everything that begins with a matching cmdname.
|
|
||||||
l_raw_string = raw_string.lower()
|
l_raw_string = raw_string.lower()
|
||||||
for cmd in cmdset:
|
matches = []
|
||||||
try:
|
try:
|
||||||
|
if include_prefixes:
|
||||||
|
for cmd in cmdset:
|
||||||
matches.extend([create_match(cmdname, raw_string, cmd)
|
matches.extend([create_match(cmdname, raw_string, cmd)
|
||||||
for cmdname in [cmd.key] + cmd.aliases
|
for cmdname in [cmd.key] + cmd.aliases
|
||||||
if cmdname and l_raw_string.startswith(cmdname.lower())
|
if cmdname and l_raw_string.startswith(cmdname.lower())
|
||||||
and (not cmd.arg_regex or
|
and (not cmd.arg_regex or
|
||||||
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
||||||
|
else:
|
||||||
|
for cmd in cmdset:
|
||||||
|
for cmdname in [cmd.key] + cmd.aliases:
|
||||||
|
cmdname = cmdname.lstrip(_CMD_IGNORE_PREFIXES) if len(cmdname) > 1 else cmdname
|
||||||
|
if cmdname and l_raw_string.startswith(cmdname.lower()) and \
|
||||||
|
(not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname):])):
|
||||||
|
matches.append(create_match(cmdname, raw_string, cmd))
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
log_trace("cmdhandler error. raw_input:%s" % raw_string)
|
||||||
|
return matches
|
||||||
|
|
||||||
|
def try_num_prefixes(raw_string):
|
||||||
if not matches:
|
if not matches:
|
||||||
# no matches found
|
# no matches found
|
||||||
num_ref_match = _MULTIMATCH_REGEX.match(raw_string)
|
num_ref_match = _MULTIMATCH_REGEX.match(raw_string)
|
||||||
|
|
@ -94,12 +101,33 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||||
# with a #num-command style syntax. We expect the regex to
|
# with a #num-command style syntax. We expect the regex to
|
||||||
# contain the groups "number" and "name".
|
# contain the groups "number" and "name".
|
||||||
mindex, new_raw_string = num_ref_match.group("number"), num_ref_match.group("name")
|
mindex, new_raw_string = num_ref_match.group("number"), num_ref_match.group("name")
|
||||||
return cmdparser(new_raw_string, cmdset,
|
return mindex, new_raw_string
|
||||||
caller, match_index=int(mindex))
|
return None, None
|
||||||
|
|
||||||
|
if not raw_string:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# find mathces
|
||||||
|
matches = build_matches(raw_string, include_prefixes=True)
|
||||||
|
if not matches:
|
||||||
|
# try to match a number 1-cmdname, 2-cmdname etc
|
||||||
|
mindex, new_raw_string = try_num_prefixes(raw_string)
|
||||||
|
if mindex is not None:
|
||||||
|
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex))
|
||||||
|
elif _CMD_IGNORE_PREFIXES:
|
||||||
|
# still no match. Try to strip prefixes
|
||||||
|
raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
|
||||||
|
matches = build_matches(raw_string, include_prefixes=False)
|
||||||
|
if not matches:
|
||||||
|
# try to match a number 1-cmdname, 2-cmdname etc
|
||||||
|
mindex, new_raw_string = try_num_prefixes(raw_string)
|
||||||
|
if mindex is not None:
|
||||||
|
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex))
|
||||||
|
|
||||||
# only select command matches we are actually allowed to call.
|
# only select command matches we are actually allowed to call.
|
||||||
matches = [match for match in matches if match[2].access(caller, 'cmd')]
|
matches = [match for match in matches if match[2].access(caller, 'cmd')]
|
||||||
|
|
||||||
|
# try to bring the number of matches down to 1
|
||||||
if len(matches) > 1:
|
if len(matches) > 1:
|
||||||
# See if it helps to analyze the match with preserved case but only if
|
# See if it helps to analyze the match with preserved case but only if
|
||||||
# it leaves at least one match.
|
# it leaves at least one match.
|
||||||
|
|
@ -129,4 +157,3 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||||
|
|
||||||
# no matter what we have at this point, we have to return it.
|
# no matter what we have at this point, we have to return it.
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,13 @@ SEARCH_MULTIMATCH_TEMPLATE = " {number}-{name}{aliases}{info}\n"
|
||||||
# both for command- and object-searches. This allows full control
|
# both for command- and object-searches. This allows full control
|
||||||
# over the error output (it uses SEARCH_MULTIMATCH_TEMPLATE by default).
|
# over the error output (it uses SEARCH_MULTIMATCH_TEMPLATE by default).
|
||||||
SEARCH_AT_RESULT = "evennia.utils.utils.at_search_result"
|
SEARCH_AT_RESULT = "evennia.utils.utils.at_search_result"
|
||||||
|
# Single characters to ignore at the beginning of a command. When set, e.g.
|
||||||
|
# cmd, @cmd and +cmd will all find a command "cmd" or one named "@cmd". If
|
||||||
|
# you have defined two different commands cmd and @cmd you can still enter
|
||||||
|
# @cmd to exactly target the second one. Single-character commands consisting
|
||||||
|
# of only a prefix character will not be stripped. Set to the empty
|
||||||
|
# string ("") to turn off prefix ignore.
|
||||||
|
CMD_IGNORE_PREFIXES = "@&/+"
|
||||||
# The module holding text strings for the connection screen.
|
# The module holding text strings for the connection screen.
|
||||||
# This module should contain one or more variables
|
# This module should contain one or more variables
|
||||||
# with strings defining the look of the screen.
|
# with strings defining the look of the screen.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue