Merge pull request #242 from Kalmarv/pr/help-v2

Console: "help perf" lists the perf commands
This commit is contained in:
zeex64 authored and GitHub committed 2026-10-15 14:15:45 -05:00
commit e88853add8
2 files changed
+33 -11

No files matched your search

+20 -1
View File
@@ -139,6 +139,23 @@ template <class Context> class Registry {
const auto it = lookup_.find(lower(name));
return it == lookup_.end() ? nullptr : &entries_[it->second];
}
// The other entries whose name or an alias goes on from a name by more words:
// `perf hud` and `perf status` under `perf`.
std::vector<const Entry *> under(std::string_view name) const {
const auto prefix = std::string(name) + ' ';
const auto *self = find(name); // (`log` is also `log status`)
std::vector<const Entry *> result;
for (const auto &entry : entries_) {
if (&entry == self)
continue;
bool below = ascii_case_insensitive_starts_with(entry.name, prefix);
for (const auto &alias : entry.aliases)
below = below || ascii_case_insensitive_starts_with(alias, prefix);
if (below)
result.push_back(&entry);
}
return result;
}
static std::string usage(const Entry &entry) {
std::string result = entry.name;
for (const auto &arg : entry.arguments) {
@@ -259,7 +276,9 @@ template <class Context> class Registry {
values.push_back(std::move(*value));
}
if (index != args.size()) {
output("error: Too many arguments. Usage: " + usage(*entry));
// `perf hdu`: neither an argument of perf nor a command under it.
output("error: Too many arguments. Usage: " + usage(*entry) +
(under(entry->name).empty() ? "" : ". Use help " + entry->name + " for the commands under it."));
return false;
}
if (!entry->run) {
+13 -10
View File
@@ -44,24 +44,23 @@ void register_console_commands(Commands &registry) {
if (args.empty()) {
out("Enter a variable by itself to read it, or follow it with a value: "
"noclip 1, nobail 0, flyspeed 60.");
out("Use commands [prefix] to list entries, help <command> for details, "
"and Tab to complete names and "
"arguments.");
out("Use commands [prefix] to list entries, help <command> for details and the commands under it "
"(help perf, help mp, help trainer), and Tab to complete names and arguments.");
out("Groups: Movement, Gameplay, World, Graphics, Progression, Objects, "
"Engine, Console.");
return;
}
const auto &name = std::get<std::string>(args[0]);
const auto *entry = registry.find(name);
const auto below = registry.under(entry ? entry->name : name);
const auto list_below = [&below, &out] {
for (const auto *item : below)
out(Commands::usage(*item) + (item->description.empty() ? "" : " - " + item->description));
};
if (!entry) {
bool found = false;
for (const auto &item : registry.entries())
if (ascii_case_insensitive_starts_with(item.name, name + " ")) {
out(Commands::usage(item) + (item.description.empty() ? "" : " - " + item.description));
found = true;
}
if (!found)
if (below.empty())
out("error: Unknown help topic.");
list_below();
return;
}
out(Commands::usage(*entry));
@@ -83,6 +82,10 @@ void register_console_commands(Commands &registry) {
}
if (entry->reset)
out("Restore: reset " + entry->name);
// `perf` is a command of its own and the first word of `perf hud`, `perf status` and the rest.
if (!below.empty())
out(entry->name + " commands:");
list_below();
};
registry.add(std::move(help));
auto list = action("commands", "List commands and variables, optionally filtered by prefix", Group::console,