Start update help command further
This commit is contained in:
parent
e301a1410f
commit
062aba2926
1 changed files with 292 additions and 198 deletions
|
|
@ -103,17 +103,137 @@ def help_search_with_index(query, candidate_entries, suggestion_maxnum=5):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_entry_for_subcategories(entry):
|
||||||
|
"""
|
||||||
|
Parse a command docstring for special sub-category blocks:
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entry (str): A help entry to parse
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: The dict is a mapping that splits the entry into subcategories. This
|
||||||
|
will always hold a key `None` for the main help entry and
|
||||||
|
zero or more keys holding the subcategories. Each is itself
|
||||||
|
a dict with a key `None` for the main text of that subcategory
|
||||||
|
followed by any sub-sub-categories down to a max-depth of 5.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
::
|
||||||
|
|
||||||
|
'''
|
||||||
|
Main topic text
|
||||||
|
|
||||||
|
# HELP-SUBCATEGORIES
|
||||||
|
|
||||||
|
## foo
|
||||||
|
|
||||||
|
A subcategory of the main entry, accessible as `help topic foo`
|
||||||
|
(or using /, like `help topic/foo`)
|
||||||
|
|
||||||
|
## bar
|
||||||
|
|
||||||
|
Another subcategory, accessed as `help topic bar`
|
||||||
|
(or `help topic/bar`)
|
||||||
|
|
||||||
|
### moo
|
||||||
|
|
||||||
|
A subcategory of bar, accessed as `help bar moo`
|
||||||
|
(or `help bar/moo`)
|
||||||
|
|
||||||
|
#### dum
|
||||||
|
|
||||||
|
A subcategory of moo, accessed `help bar moo dum`
|
||||||
|
(or `help bar/moo/dum`)
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
This will result in this returned entry structure:
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
None: "Main topic text":
|
||||||
|
"foo": {
|
||||||
|
None: "main topic/foo text"
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
None: "Main topic/bar text",
|
||||||
|
"moo": {
|
||||||
|
None: "topic/bar/moo text"
|
||||||
|
"dum": {
|
||||||
|
None: "topic/bar/moo/dum text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Apart from making
|
||||||
|
sub-categories at the bottom of the entry.
|
||||||
|
|
||||||
|
This will be applied both to command docstrings and database-based help
|
||||||
|
entries.
|
||||||
|
|
||||||
|
"""
|
||||||
|
topic, *subtopics = _RE_HELP_SUBTOPICS_START.split(entry, maxsplit=1)
|
||||||
|
structure = {None: topic.strip()}
|
||||||
|
subtopics_index = []
|
||||||
|
|
||||||
|
if subtopics:
|
||||||
|
subctopics = subtopics[0]
|
||||||
|
else:
|
||||||
|
return structure
|
||||||
|
|
||||||
|
keypath = []
|
||||||
|
current_nesting = 0
|
||||||
|
subtopic = None
|
||||||
|
|
||||||
|
for part in _RE_HELP_SUBTOPIC_SPLIT.split(subtopics):
|
||||||
|
subtopic_match = _RE_HELP_SUBTOPIC_PARSE.match(part)
|
||||||
|
if subtopic_match:
|
||||||
|
# a new sub(-sub..) category starts.
|
||||||
|
mdict = subtopic_match.groupdict()
|
||||||
|
subtopic = mdict['name'].strip()
|
||||||
|
subtopic_index.append(subtopic)
|
||||||
|
new_nesting = len(mdict['nesting']) - 1
|
||||||
|
nestdiff = new_nesting - current_nesting
|
||||||
|
if nestdiff < 0:
|
||||||
|
# jumping back up in nesting
|
||||||
|
for _ in range(abs(nestdiff) + 1):
|
||||||
|
try:
|
||||||
|
keypath.pop()
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
keypath.append(subtopic)
|
||||||
|
current_nesting = new_nesting
|
||||||
|
else:
|
||||||
|
# an entry belonging to a subtopic - find the nested location
|
||||||
|
dct = structure
|
||||||
|
if not keypath and subtopic is not None:
|
||||||
|
structure[subtopic] = part.strip()
|
||||||
|
else:
|
||||||
|
for key in keypath:
|
||||||
|
if key in dct:
|
||||||
|
dct = dct[key]
|
||||||
|
else:
|
||||||
|
dct[key] = {
|
||||||
|
None: part.strip()
|
||||||
|
}
|
||||||
|
return structure, subtopic_index
|
||||||
|
|
||||||
|
|
||||||
class CmdHelp(COMMAND_DEFAULT_CLASS):
|
class CmdHelp(COMMAND_DEFAULT_CLASS):
|
||||||
"""
|
"""
|
||||||
View help or a list of topics
|
View help or a list of topics
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
help <topic or command>
|
help
|
||||||
help list
|
help <topic, command or category>
|
||||||
help all
|
help <topic> / <subtopic>
|
||||||
|
help <topic> / <subtopic> / <subsubtopic> ...
|
||||||
|
|
||||||
|
Use the help command alone to see an index of all help topics, organized by
|
||||||
|
category. Some long topics may offer additional sub-topics.
|
||||||
|
|
||||||
This will search for help on commands and other
|
|
||||||
topics related to the game.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = "help"
|
key = "help"
|
||||||
|
|
@ -136,6 +256,9 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
||||||
# number of suggestions (set to 0 to remove suggestions from help)
|
# number of suggestions (set to 0 to remove suggestions from help)
|
||||||
suggestion_maxnum = 5
|
suggestion_maxnum = 5
|
||||||
|
|
||||||
|
# separator between subtopics:
|
||||||
|
subtopic_separator_char = r"/"
|
||||||
|
|
||||||
def msg_help(self, text):
|
def msg_help(self, text):
|
||||||
"""
|
"""
|
||||||
messages text to the caller, adding an extra oob argument to indicate
|
messages text to the caller, adding an extra oob argument to indicate
|
||||||
|
|
@ -160,165 +283,74 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
||||||
self.msg(text=(text, {"type": "help"}))
|
self.msg(text=(text, {"type": "help"}))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_entry_for_subcategories(entry):
|
def format_help_entry(topic="", help_text="", aliases=None, suggested=None,
|
||||||
"""
|
subtopics=None):
|
||||||
Parse a command docstring for special sub-category blocks:
|
|
||||||
|
|
||||||
Args:
|
|
||||||
entry (str): A help entry to parse
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: A mapping that splits the entry into subcategories. This
|
|
||||||
will always hold a key `None` for the main help entry and
|
|
||||||
zero or more keys holding the subcategories. Each is itself
|
|
||||||
a dict with a key `None` for the main text of that subcategory
|
|
||||||
followed by any sub-sub-categories down to a max-depth of 5.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
::
|
|
||||||
|
|
||||||
'''
|
|
||||||
Main topic text
|
|
||||||
|
|
||||||
# help-subcategories
|
|
||||||
|
|
||||||
## foo
|
|
||||||
|
|
||||||
A subcategory of the main entry, accessible as `help topic foo`
|
|
||||||
(or using /, like `help topic/foo`)
|
|
||||||
|
|
||||||
## bar
|
|
||||||
|
|
||||||
Another subcategory, accessed as `help topic bar`
|
|
||||||
(or `help topic/bar`)
|
|
||||||
|
|
||||||
### moo
|
|
||||||
|
|
||||||
A subcategory of bar, accessed as `help bar moo`
|
|
||||||
(or `help bar/moo`)
|
|
||||||
|
|
||||||
#### dum
|
|
||||||
|
|
||||||
A subcategory of moo, accessed `help bar moo dum`
|
|
||||||
(or `help bar/moo/dum`)
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
This will result in this returned entry structure:
|
|
||||||
::
|
|
||||||
|
|
||||||
{
|
|
||||||
None: "Main topic text":
|
|
||||||
"foo": {
|
|
||||||
None: "main topic/foo text"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
None: "Main topic/bar text",
|
|
||||||
"moo": {
|
|
||||||
None: "topic/bar/moo text"
|
|
||||||
"dum": {
|
|
||||||
None: "topic/bar/moo/dum text"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Apart from making
|
|
||||||
sub-categories at the bottom of the entry.
|
|
||||||
|
|
||||||
This will be applied both to command docstrings and database-based help
|
|
||||||
entries.
|
|
||||||
|
|
||||||
"""
|
|
||||||
topic, *subcategories = _RE_HELP_SUBTOPICS_START.split(entry, maxsplit=1)
|
|
||||||
structure = {None: topic.strip()}
|
|
||||||
|
|
||||||
if subcategories:
|
|
||||||
subcategories = subcategories[0]
|
|
||||||
else:
|
|
||||||
return structure
|
|
||||||
|
|
||||||
keypath = []
|
|
||||||
current_nesting = 0
|
|
||||||
subtopic = None
|
|
||||||
|
|
||||||
for part in _RE_HELP_SUBTOPIC_SPLIT.split(subcategories):
|
|
||||||
subtopic_match = _RE_HELP_SUBTOPIC_PARSE.match(part)
|
|
||||||
if subtopic_match:
|
|
||||||
# a new sub(-sub..) category starts.
|
|
||||||
mdict = subtopic_match.groupdict()
|
|
||||||
subtopic = mdict['name'].strip()
|
|
||||||
new_nesting = len(mdict['nesting']) - 1
|
|
||||||
nestdiff = new_nesting - current_nesting
|
|
||||||
if nestdiff < 0:
|
|
||||||
# jumping back up in nesting
|
|
||||||
for _ in range(abs(nestdiff) + 1):
|
|
||||||
try:
|
|
||||||
keypath.pop()
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
keypath.append(subtopic)
|
|
||||||
current_nesting = new_nesting
|
|
||||||
else:
|
|
||||||
# an entry belonging to a subtopic - find the nested location
|
|
||||||
dct = structure
|
|
||||||
if not keypath and subtopic is not None:
|
|
||||||
structure[subtopic] = part.strip()
|
|
||||||
else:
|
|
||||||
for key in keypath:
|
|
||||||
if key in dct:
|
|
||||||
dct = dct[key]
|
|
||||||
else:
|
|
||||||
dct[key] = {
|
|
||||||
None: part.strip()
|
|
||||||
}
|
|
||||||
return structure
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def format_help_entry(title, help_text, aliases=None, suggested=None):
|
|
||||||
"""
|
"""
|
||||||
This visually formats the help entry.
|
This visually formats the help entry.
|
||||||
This method can be overriden to customize the way a help
|
This method can be overriden to customize the way a help
|
||||||
entry is displayed.
|
entry is displayed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
title (str): the title of the help entry.
|
title (str): The title of the help entry.
|
||||||
help_text (str): the text of the help entry.
|
help_text (str): Text of the help entry.
|
||||||
aliases (list of str or None): the list of aliases.
|
aliases (list): List of help-aliases (displayed in header).
|
||||||
suggested (list of str or None): suggested reading.
|
suggested (list): Strings suggested reading (based on title).
|
||||||
|
subtopics (list): A list of strings - the subcategories to this entry.
|
||||||
|
|
||||||
Returns the formatted string, ready to be sent.
|
Returns the formatted string, ready to be sent.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
start = f"{_SEP}\n"
|
start = f"{_SEP}\n"
|
||||||
title = f"|CHelp for |w{title}|n" if title else ""
|
title = f"|CHelp for |w{topic}|n" if topic else ""
|
||||||
aliases = (
|
aliases = (
|
||||||
" |C(aliases: {}|C)|n".format("|C,|n ".join(f"|w{ali}|n" for ali in aliases))
|
" |C(aliases: {}|C)|n".format("|C,|n ".join(f"|w{ali}|n" for ali in aliases))
|
||||||
if aliases else "")
|
if aliases else ""
|
||||||
|
)
|
||||||
help_text = (
|
help_text = (
|
||||||
f"\n{dedent(help_text.rstrip())}"if help_text else "")
|
f"\n{dedent(help_text.rstrip())}" if help_text else ""
|
||||||
|
)
|
||||||
|
subtopics = (
|
||||||
|
"\nSubtopics (read with |whelp {} / subtopic): {}".format(
|
||||||
|
topic, "|C,|n ".join(f"|w{subtop}|n" for subtop in subtopics)
|
||||||
|
if subtopics else ""
|
||||||
|
)
|
||||||
|
)
|
||||||
suggested = (
|
suggested = (
|
||||||
"\n\n|CSuggested:|n {}".format(
|
"\n\n|CSuggested:|n {}".format(
|
||||||
fill("|C,|n ".join(f"|w{sug}|n" for sug in suggested)))
|
fill("|C,|n ".join(f"|w{sug}|n" for sug in suggested))
|
||||||
if suggested else "")
|
)
|
||||||
|
if suggested else ""
|
||||||
|
)
|
||||||
end = f"\n{_SEP}"
|
end = f"\n{_SEP}"
|
||||||
|
|
||||||
return "".join((start, title, aliases, help_text, suggested, end))
|
return "".join((start, title, aliases, help_text, subtopics, suggested, end))
|
||||||
|
|
||||||
def format_help_list(self, hdict_cmds, hdict_db):
|
def format_help_index(self, cmd_help_dict=None, db_help_dict=None):
|
||||||
"""
|
"""
|
||||||
Output a category-ordered list. The input are the
|
Output a category-ordered g for displaying the main help, grouped by
|
||||||
|
category.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmd_help_dict (dict): A dict `{"category": [topic, topic, ...]}` for
|
||||||
|
command-based help.
|
||||||
|
db_help_dict (dict): A dict `{"category": [topic, topic], ...]}` for
|
||||||
|
database-based help.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The help index organized into a grid.
|
||||||
|
|
||||||
|
The input are the
|
||||||
pre-loaded help files for commands and database-helpfiles
|
pre-loaded help files for commands and database-helpfiles
|
||||||
respectively. You can override this method to return a
|
respectively. You can override this method to return a
|
||||||
custom display of the list of commands and topics.
|
custom display of the list of commands and topics.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
category_clr = "|w"
|
category_clr = "|w"
|
||||||
topic_clr = "|G"
|
topic_clr = "|G"
|
||||||
width = self.client_width()
|
width = self.client_width()
|
||||||
grid = []
|
grid = []
|
||||||
verbatim_elements = []
|
verbatim_elements = []
|
||||||
for category in sorted(set(list(hdict_cmds.keys()) + list(hdict_db.keys()))):
|
for category in sorted(set(list(cmd_help_dict.keys()) + list(db_help_dict.keys()))):
|
||||||
|
|
||||||
category_str = f"-- {category.title()} "
|
category_str = f"-- {category.title()} "
|
||||||
grid.append(
|
grid.append(
|
||||||
|
|
@ -328,7 +360,7 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
||||||
)
|
)
|
||||||
verbatim_elements.append(len(grid) - 1)
|
verbatim_elements.append(len(grid) - 1)
|
||||||
|
|
||||||
entries = sorted(set(hdict_cmds.get(category, []) + hdict_db.get(category, [])))
|
entries = sorted(set(cmd_help_dict.get(category, []) + db_help_dict.get(category, [])))
|
||||||
grid.extend(entries)
|
grid.extend(entries)
|
||||||
|
|
||||||
gridrows = format_grid(grid, width, sep=" ", verbatim_elements=verbatim_elements)
|
gridrows = format_grid(grid, width, sep=" ", verbatim_elements=verbatim_elements)
|
||||||
|
|
@ -379,111 +411,173 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
||||||
def parse(self):
|
def parse(self):
|
||||||
"""
|
"""
|
||||||
input is a string containing the command or topic to match.
|
input is a string containing the command or topic to match.
|
||||||
"""
|
|
||||||
self.original_args = self.args.strip()
|
|
||||||
self.args = self.args.strip().lower()
|
|
||||||
|
|
||||||
|
The allowed syntax is
|
||||||
|
::
|
||||||
|
|
||||||
|
help <topic>[/<subtopic>[/<subtopic>[/...]]]
|
||||||
|
|
||||||
|
The database/command query is always for `<topic>`, and any subtopics
|
||||||
|
is then parsed from there. If a `<topic>` has spaces in it, it is
|
||||||
|
always matched before assuming the space begins a subtopic.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# parse the query
|
||||||
|
|
||||||
|
if self.args:
|
||||||
|
self.subtopics = [part.strip().lower()
|
||||||
|
for part in self.args.split(self.subtopic_separator_char)]
|
||||||
|
self.topic = self.subtopics.pop(0)
|
||||||
|
else:
|
||||||
|
self.topic = ""
|
||||||
|
self.subtopics = []
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"""
|
"""
|
||||||
Run the dynamic help entry creator.
|
Run the dynamic help entry creator.
|
||||||
"""
|
"""
|
||||||
query, cmdset = self.args, self.cmdset
|
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
query, subtopics, cmdset = self.topic, self.subtopics, self.cmdset
|
||||||
suggestion_cutoff = self.suggestion_cutoff
|
suggestion_cutoff = self.suggestion_cutoff
|
||||||
suggestion_maxnum = self.suggestion_maxnum
|
suggestion_maxnum = self.suggestion_maxnum
|
||||||
|
|
||||||
if not query:
|
|
||||||
query = "all"
|
|
||||||
|
|
||||||
# removing doublets in cmdset, caused by cmdhandler
|
# removing doublets in cmdset, caused by cmdhandler
|
||||||
# having to allow doublet commands to manage exits etc.
|
# having to allow doublet commands to manage exits etc.
|
||||||
cmdset.make_unique(caller)
|
cmdset.make_unique(caller)
|
||||||
|
|
||||||
# retrieve all available commands and database topics
|
# retrieve all available commands and database topics
|
||||||
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
|
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
|
||||||
all_topics = [
|
all_db_topics = [
|
||||||
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
|
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
|
||||||
]
|
]
|
||||||
all_categories = list(
|
all_categories = list(set(
|
||||||
set(
|
[HelpCategory(cmd.help_category) for cmd in all_cmds]
|
||||||
[HelpCategory(cmd.help_category) for cmd in all_cmds]
|
+ [HelpCategory(topic.help_category) for topic in all_db_topics]
|
||||||
+ [HelpCategory(topic.help_category) for topic in all_topics]
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if query in ("list", "all"):
|
if not query:
|
||||||
# we want to list all available help entries, grouped by category
|
# list all available help entries, grouped by category. We want to
|
||||||
hdict_cmd = defaultdict(list)
|
# build dictionaries {category: [topic, topic, ...], ...}
|
||||||
hdict_topic = defaultdict(list)
|
cmd_help_dict = defaultdict(list)
|
||||||
# create the dictionaries {category:[topic, topic ...]} required by format_help_list
|
db_help_dict = defaultdict(list)
|
||||||
|
|
||||||
# Filter commands that should be reached by the help
|
# Filter commands that should be reached by the help
|
||||||
# system, but not be displayed in the table, or be displayed differently.
|
# system, but not be displayed in the table, or be displayed differently.
|
||||||
for cmd in all_cmds:
|
for cmd in all_cmds:
|
||||||
if self.should_list_cmd(cmd, caller):
|
if self.should_list_cmd(cmd, caller):
|
||||||
key = (cmd.auto_help_display_key
|
key = (cmd.auto_help_display_key
|
||||||
if hasattr(cmd, "auto_help_display_key") else cmd.key)
|
if hasattr(cmd, "auto_help_display_key") else cmd.key)
|
||||||
hdict_cmd[cmd.help_category].append(key)
|
cmd_help_dict[cmd.help_category].append(key)
|
||||||
[hdict_topic[topic.help_category].append(topic.key) for topic in all_topics]
|
|
||||||
# report back
|
for db_topic in all_db_topics:
|
||||||
self.msg_help(self.format_help_list(hdict_cmd, hdict_topic))
|
db_help_dict[db_topic.help_category].append(db_topic.key)
|
||||||
|
|
||||||
|
output = self.format_help_index(cmd_help_dict, db_help_dict)
|
||||||
|
self.msg_help(output)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Try to access a particular help entry or category
|
# We have a query - try to find a specific topic/category using the
|
||||||
|
# Lunr search engine
|
||||||
|
|
||||||
|
# all available options
|
||||||
entries = [cmd for cmd in all_cmds if cmd] + list(HelpEntry.objects.all()) + all_categories
|
entries = [cmd for cmd in all_cmds if cmd] + list(HelpEntry.objects.all()) + all_categories
|
||||||
|
match, suggestions = None, None
|
||||||
|
|
||||||
for match_query in [f"{query}~1", f"{query}*"]:
|
for match_query in [f"{query}~1", f"{query}*"]:
|
||||||
# We first do an exact word-match followed by a start-by query
|
# We first do an exact word-match followed by a start-by query
|
||||||
|
# the return of this will either be a HelpCategory, a Command or a HelpEntry.
|
||||||
matches, suggestions = help_search_with_index(
|
matches, suggestions = help_search_with_index(
|
||||||
match_query, entries, suggestion_maxnum=self.suggestion_maxnum
|
match_query, entries, suggestion_maxnum=self.suggestion_maxnum
|
||||||
)
|
)
|
||||||
|
|
||||||
if matches:
|
if matches:
|
||||||
match = matches[0]
|
match = matches[0]
|
||||||
if isinstance(match, HelpCategory):
|
break
|
||||||
formatted = self.format_help_list(
|
|
||||||
{
|
if not match:
|
||||||
match.key: [
|
# no exact matches found. Just give suggestions.
|
||||||
cmd.key
|
output = self.format_help_entry(
|
||||||
for cmd in all_cmds
|
topic="",
|
||||||
if match.key.lower() == cmd.help_category
|
help_text=f"No help entry found for '{query}'",
|
||||||
]
|
suggested=suggestions
|
||||||
},
|
)
|
||||||
{
|
self.msg_help(output)
|
||||||
match.key: [
|
return
|
||||||
topic.key
|
|
||||||
for topic in all_topics
|
if isinstance(match, HelpCategory):
|
||||||
if match.key.lower() == topic.help_category
|
# no subtopics for categories - these are just lists of topics
|
||||||
]
|
output = self.format_help_index(
|
||||||
},
|
{
|
||||||
)
|
match.key: [
|
||||||
elif inherits_from(match, "evennia.commands.command.Command"):
|
cmd.key
|
||||||
formatted = self.format_help_entry(
|
for cmd in all_cmds
|
||||||
match.key,
|
if match.key.lower() == cmd.help_category
|
||||||
match.get_help(caller, cmdset),
|
]
|
||||||
aliases=match.aliases,
|
},
|
||||||
suggested=suggestions[1:],
|
{
|
||||||
)
|
match.key: [
|
||||||
|
topic.key
|
||||||
|
for topic in all_topics
|
||||||
|
if match.key.lower() == topic.help_category
|
||||||
|
]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.msg_help(output)
|
||||||
|
return
|
||||||
|
|
||||||
|
if inherits_from(match, "evennia.commands.command.Command"):
|
||||||
|
# a command match
|
||||||
|
topic = match.key
|
||||||
|
help_text = match.get_help(caller, cmdset)
|
||||||
|
aliases = match.aliases,
|
||||||
|
suggested=suggestions[1:]
|
||||||
|
else:
|
||||||
|
# a database match
|
||||||
|
topic = match.key
|
||||||
|
help_text = match.entrytext
|
||||||
|
aliases = match.aliases.all()
|
||||||
|
suggested = suggestions[1:]
|
||||||
|
|
||||||
|
# parse for subtopics. The subtopic_map is a dict with the current topic/subtopic
|
||||||
|
# text is stored under a `None` key and all other keys are subtopic titles pointing
|
||||||
|
# to nested dicts.
|
||||||
|
|
||||||
|
subtopic_map = parse_entry_for_subcategories(help_text)
|
||||||
|
help_text = subtopic_map[None]
|
||||||
|
subtopic_index = [subtopic for subtopic in subtopic_map if subtopic is not None]
|
||||||
|
|
||||||
|
if subtopics:
|
||||||
|
# if we asked for subtopics, parse the found topic_text to see if any match.
|
||||||
|
# the subtopics is a list describing the path through the subtopic_map.
|
||||||
|
for subtopic_query in subtopics:
|
||||||
|
subtopic_query_lower = subtopic_query.lower()
|
||||||
|
checked_topic = topic + f" / {subtopic_query.lower().capitalize()}"
|
||||||
|
subtopic_index = [subtopic for subtopic in subtopic_map if subtopic is not None]
|
||||||
|
if subtopic_query_lower() in subtopic_index:
|
||||||
|
# keep stepping down into the tree
|
||||||
|
subtopic_map = subtopic_map.pop(subtopic_query)
|
||||||
|
topic = checked_topic
|
||||||
else:
|
else:
|
||||||
formatted = self.format_help_entry(
|
output = self.format_help_entry(
|
||||||
match.key,
|
topic=topic,
|
||||||
match.entrytext,
|
help_text=f"No help entry found for '{checked_topic}'",
|
||||||
aliases=match.aliases.all(),
|
subtopics=subtopic_index
|
||||||
suggested=suggestions[1:],
|
|
||||||
)
|
)
|
||||||
|
self.msg_help(output)
|
||||||
|
return
|
||||||
|
# we reached the bottom of the topic tree
|
||||||
|
help_text = subtopic_map[None]
|
||||||
|
|
||||||
self.msg_help(formatted)
|
output = self.format_help_entry(
|
||||||
return
|
topic=topic,
|
||||||
|
help_text=help_text,
|
||||||
# no exact matches found. Just give suggestions.
|
aliases=aliases if not subtopics else None,
|
||||||
self.msg(
|
subtopics=subtopic_index
|
||||||
self.format_help_entry(
|
|
||||||
"", f"No help entry found for '{query}'", None, suggested=suggestions
|
|
||||||
),
|
|
||||||
options={"type": "help"},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.msg_help(output)
|
||||||
|
|
||||||
|
|
||||||
def _loadhelp(caller):
|
def _loadhelp(caller):
|
||||||
entry = caller.db._editing_help
|
entry = caller.db._editing_help
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue