diff
minitox.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 3 deletions(-)
diff --git a/minitox.c b/minitox.c
index ab6a77f..3139d86 100644
--- a/minitox.c
+++ b/minitox.c
@@ -102,6 +102,14 @@ struct Command {
CommandHandler *handler;
};
+struct CommandHelp {
+ const char *name;
+ const char *section;
+ const char *usage;
+ const char *summary;
+ const char *example;
+};
+
struct GroupUserData {
uint32_t friend_num;
uint8_t *cookie;
@@ -1322,6 +1330,45 @@ void command_settitle(int narg, char **args) {
#define COMMAND_ARGS_REST 10
#define COMMAND_LENGTH (sizeof(commands)/sizeof(struct Command))
+static const char *help_sections[] = {
+ "General",
+ "Profile",
+ "Contacts",
+ "Chat",
+ "Requests",
+ "Groups",
+};
+
+static const struct CommandHelp command_help_info[] = {
+ {"guide", "General", "", "Print the quick start notes.", "/guide"},
+ {"help", "General", "[command]", "Show all commands or help for one.", "/help add"},
+ {"save", "General", "", "Save state to disk now.", "/save"},
+ {"info", "Profile", "[contact_index]", "Show your info or one contact.", "/info 3"},
+ {"setname", "Profile", "<name>", "Change your display name.", "/setname alice"},
+ {"setstmsg", "Profile", "<status_message>", "Change your status message.", "/setstmsg coding"},
+ {"contacts", "Contacts", "", "List friends and groups with indexes.", "/contacts"},
+ {"add", "Contacts", "<toxid> <msg>", "Send a friend request.", "/add <toxid> hi"},
+ {"del", "Contacts", "<contact_index>", "Remove a friend or group.", "/del 4"},
+ {"go", "Chat", "[contact_index]", "Enter chat mode or go back to command mode.", "/go 2"},
+ {"history", "Chat", "[n]", "Show recent lines from this chat.", "/history 30"},
+ {"accept", "Requests", "[request_index]", "List requests or accept one.", "/accept 1"},
+ {"deny", "Requests", "[request_index]", "List requests or deny one.", "/deny 1"},
+ {"invite", "Groups", "<friend_contact_index> [group_contact_index]", "Invite a friend to a group.", "/invite 2"},
+ {"settitle", "Groups", "<group_contact_index> <title>", "Rename a group.", "/settitle 5 friday plan"},
+};
+
+#define HELP_SECTION_COUNT (sizeof(help_sections) / sizeof(help_sections[0]))
+#define HELP_INFO_COUNT (sizeof(command_help_info) / sizeof(command_help_info[0]))
+
+static const struct CommandHelp *find_command_help(const char *name) {
+ for (size_t i = 0; i < HELP_INFO_COUNT; i++) {
+ if (strcmp(command_help_info[i].name, name) == 0) {
+ return &command_help_info[i];
+ }
+ }
+ return NULL;
+}
+
struct Command commands[] = {
{
"guide",
@@ -1332,7 +1379,7 @@ struct Command commands[] = {
{
"help",
"- print this message.",
- 0,
+ 0 + COMMAND_ARGS_REST,
command_help,
},
{
@@ -1416,8 +1463,32 @@ struct Command commands[] = {
};
void command_help(int narg, char **args){
- for (int i=1;i<COMMAND_LENGTH;i++) {
- printf("%-16s%s\n", commands[i].name, commands[i].desc);
+ if (narg > 0) {
+ const char *name = args[0];
+ if (name[0] == '/') name++;
+
+ const struct CommandHelp *h = find_command_help(name);
+ if (!h) {
+ WARN("Unknown command: %s", args[0]);
+ return;
+ }
+
+ PRINT("command: /%s", h->name);
+ PRINT("usage: /%s%s%s", h->name, h->usage[0] ? " " : "", h->usage);
+ PRINT("about: %s", h->summary);
+ PRINT("example: %s", h->example);
+ return;
+ }
+
+ PRINT("commands (`/help <command>` for details):");
+ for (size_t s = 0; s < HELP_SECTION_COUNT; s++) {
+ PRINT("");
+ PRINT("%s", help_sections[s]);
+ for (size_t i = 0; i < HELP_INFO_COUNT; i++) {
+ const struct CommandHelp *h = &command_help_info[i];
+ if (strcmp(h->section, help_sections[s]) != 0) continue;
+ PRINT(" /%-10s %-30s %s", h->name, h->usage, h->summary);
+ }
}
}