From c8567cd793792493c7f8956ea59a97ff44f716e3 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 25 Jun 2013 00:49:29 +0100 Subject: [PATCH] Restructured help --- src/command/command.c | 304 ++++++++++++++++++++++-------------------- src/command/command.h | 4 +- src/ui/console.c | 87 ++---------- 3 files changed, 169 insertions(+), 226 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index cd2ce744..f83952fc 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -55,18 +55,17 @@ * max_args - Maximum number of arguments * help - A help struct containing usage info etc */ -struct cmd_t { - const gchar *cmd; +typedef struct cmd_t { + gchar *cmd; gboolean (*func)(gchar **args, struct cmd_help_t help); gchar** (*parser)(const char * const inp, int min, int max); int min_args; int max_args; - struct cmd_help_t help; -}; + CommandHelp help; +} Command; typedef char*(*autocompleter)(char*, int*); -static struct cmd_t * _cmd_get_command(const char * const command); static void _update_presence(const resource_presence_t presence, const char * const show, gchar **args); static gboolean _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help, @@ -143,13 +142,12 @@ static gboolean _cmd_who(gchar **args, struct cmd_help_t help); static gboolean _cmd_wins(gchar **args, struct cmd_help_t help); static gboolean _cmd_xa(gchar **args, struct cmd_help_t help); +static GHashTable *commands = NULL; + /* - * The commands are broken down into three groups: - * Main commands - * Commands to change preferences - * Commands to change users status + * Command list */ -static struct cmd_t main_commands[] = +static struct cmd_t command_defs[] = { { "/help", _cmd_help, parse_args, 0, 1, @@ -471,7 +469,7 @@ static struct cmd_t main_commands[] = { "/close", _cmd_close, parse_args, 0, 1, - { "/close [win|read|all]", "Close a window window.", + { "/close [win|read|all]", "Close windows.", { "/close [win|read|all]", "---------------------", "Passing no argument will close the current window.", @@ -496,11 +494,8 @@ static struct cmd_t main_commands[] = { "/quit", "-----", "Logout of any current session, and quit Profanity.", - NULL } } } -}; + NULL } } }, -static struct cmd_t setting_commands[] = -{ { "/beep", _cmd_beep, parse_args, 1, 1, { "/beep on|off", "Terminal beep on new messages.", @@ -783,11 +778,8 @@ static struct cmd_t setting_commands[] = "Show status updates from contacts, such as online/offline/away etc.", "When disabled, status updates are not displayed.", "The default is 'on'.", - NULL } } } -}; + NULL } } }, -static struct cmd_t presence_commands[] = -{ { "/away", _cmd_away, parse_args_with_freetext, 0, 1, { "/away [msg]", "Set status to away.", @@ -872,7 +864,32 @@ cmd_init(void) log_info("Initialising commands"); commands_ac = autocomplete_new(); - who_ac = autocomplete_new(); + + help_ac = autocomplete_new(); + autocomplete_add(help_ac, strdup("commands")); + autocomplete_add(help_ac, strdup("basic")); + autocomplete_add(help_ac, strdup("chatting")); + autocomplete_add(help_ac, strdup("groupchat")); + autocomplete_add(help_ac, strdup("presence")); + autocomplete_add(help_ac, strdup("roster")); + autocomplete_add(help_ac, strdup("service")); + autocomplete_add(help_ac, strdup("settings")); + autocomplete_add(help_ac, strdup("other")); + autocomplete_add(help_ac, strdup("navigation")); + + // load command defs into hash table + commands = g_hash_table_new(g_str_hash, g_str_equal); + unsigned int i; + for (i = 0; i < ARRAY_SIZE(command_defs); i++) { + Command *pcmd = command_defs+i; + + // add to hash + g_hash_table_insert(commands, pcmd->cmd, pcmd); + + // add to commands and help autocompleters + autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd)); + autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1)); + } prefs_ac = autocomplete_new(); autocomplete_add(prefs_ac, strdup("ui")); @@ -882,13 +899,6 @@ cmd_init(void) autocomplete_add(prefs_ac, strdup("conn")); autocomplete_add(prefs_ac, strdup("presence")); - help_ac = autocomplete_new(); - autocomplete_add(help_ac, strdup("list")); - autocomplete_add(help_ac, strdup("basic")); - autocomplete_add(help_ac, strdup("presence")); - autocomplete_add(help_ac, strdup("settings")); - autocomplete_add(help_ac, strdup("navigation")); - notify_ac = autocomplete_new(); autocomplete_add(notify_ac, strdup("message")); autocomplete_add(notify_ac, strdup("typing")); @@ -958,26 +968,12 @@ cmd_init(void) theme_load_ac = NULL; - unsigned int i; - for (i = 0; i < ARRAY_SIZE(main_commands); i++) { - struct cmd_t *pcmd = main_commands+i; - autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd)); - autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1)); - } - - for (i = 0; i < ARRAY_SIZE(setting_commands); i++) { - struct cmd_t *pcmd = setting_commands+i; - autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd)); - autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1)); - } - - for (i = 0; i < ARRAY_SIZE(presence_commands); i++) { - struct cmd_t *pcmd = presence_commands+i; - autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd)); - autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1)); - autocomplete_add(who_ac, (gchar *)strdup(pcmd->cmd+1)); - } - + who_ac = autocomplete_new(); + autocomplete_add(who_ac, strdup("chat")); + autocomplete_add(who_ac, strdup("online")); + autocomplete_add(who_ac, strdup("away")); + autocomplete_add(who_ac, strdup("xa")); + autocomplete_add(who_ac, strdup("dnd")); autocomplete_add(who_ac, strdup("offline")); autocomplete_add(who_ac, strdup("available")); autocomplete_add(who_ac, strdup("unavailable")); @@ -1079,51 +1075,12 @@ cmd_reset_autocomplete() autocomplete_reset(group_ac); } -GSList * -cmd_get_basic_help(void) -{ - GSList *result = NULL; - - unsigned int i; - for (i = 0; i < ARRAY_SIZE(main_commands); i++) { - result = g_slist_append(result, &((main_commands+i)->help)); - } - - return result; -} - -GSList * -cmd_get_settings_help(void) -{ - GSList *result = NULL; - - unsigned int i; - for (i = 0; i < ARRAY_SIZE(setting_commands); i++) { - result = g_slist_append(result, &((setting_commands+i)->help)); - } - - return result; -} - -GSList * -cmd_get_presence_help(void) -{ - GSList *result = NULL; - - unsigned int i; - for (i = 0; i < ARRAY_SIZE(presence_commands); i++) { - result = g_slist_append(result, &((presence_commands+i)->help)); - } - - return result; -} - // Command execution gboolean cmd_execute(const char * const command, const char * const inp) { - struct cmd_t *cmd = _cmd_get_command(command); + Command *cmd = g_hash_table_lookup(commands, command); if (cmd != NULL) { gchar **args = cmd->parser(inp, cmd->min_args, cmd->max_args); @@ -1674,48 +1631,129 @@ _cmd_wins(gchar **args, struct cmd_help_t help) return TRUE; } +static +gint _compare_commands(Command *a, Command *b) +{ + const char * utf8_str_a = a->cmd; + const char * utf8_str_b = b->cmd; + + gchar *key_a = g_utf8_collate_key(utf8_str_a, -1); + gchar *key_b = g_utf8_collate_key(utf8_str_b, -1); + + gint result = g_strcmp0(key_a, key_b); + + g_free(key_a); + g_free(key_b); + + return result; +} + +static void +_cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size) +{ + cons_show(""); + cons_show("%s", heading); + cons_show(""); + + GList *ordered_commands = NULL; + int i; + for (i = 0; i < filter_size; i++) { + Command *cmd = g_hash_table_lookup(commands, cmd_filter[i]); + ordered_commands = g_list_insert_sorted(ordered_commands, cmd, (GCompareFunc)_compare_commands); + } + + GList *curr = ordered_commands; + while (curr != NULL) { + Command *cmd = curr->data; + cons_show("%-12s: %s", cmd->cmd, cmd->help.short_help); + curr = g_list_next(curr); + } + g_list_free(ordered_commands); + g_list_free(curr); + + cons_show(""); + cons_show("Use /help [command] without the leading slash, for help on a specific command"); + cons_show(""); +} + static gboolean _cmd_help(gchar **args, struct cmd_help_t help) { int num_args = g_strv_length(args); if (num_args == 0) { cons_help(); - } else if (strcmp(args[0], "list") == 0) { + } else if (strcmp(args[0], "commands") == 0) { cons_show(""); - cons_show("Basic commands:"); - cons_show_time(); - unsigned int i; - for (i = 0; i < ARRAY_SIZE(main_commands); i++) { - cons_show_word( (main_commands+i)->cmd ); - if (i < ARRAY_SIZE(main_commands) - 1) { - cons_show_word(", "); - } + cons_show("All commands"); + cons_show(""); + + GList *ordered_commands = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, commands); + while (g_hash_table_iter_next(&iter, &key, &value)) { + ordered_commands = g_list_insert_sorted(ordered_commands, value, (GCompareFunc)_compare_commands); } - cons_show_word("\n"); - cons_show("Presence commands:"); - cons_show_time(); - for (i = 0; i < ARRAY_SIZE(presence_commands); i++) { - cons_show_word( (presence_commands+i)->cmd ); - if (i < ARRAY_SIZE(presence_commands) - 1) { - cons_show_word(", "); - } + + GList *curr = ordered_commands; + while (curr != NULL) { + Command *cmd = curr->data; + cons_show("%-12s: %s", cmd->cmd, cmd->help.short_help); + curr = g_list_next(curr); } - cons_show_word("\n"); - cons_show("Settings commands:"); - cons_show_time(); - for (i = 0; i < ARRAY_SIZE(setting_commands); i++) { - cons_show_word( (setting_commands+i)->cmd ); - if (i < ARRAY_SIZE(setting_commands) - 1) { - cons_show_word(", "); - } - } - cons_show_word("\n"); + g_list_free(ordered_commands); + g_list_free(curr); + + cons_show(""); + cons_show("Use /help [command] without the leading slash, for help on a specific command"); + cons_show(""); + } else if (strcmp(args[0], "basic") == 0) { - cons_basic_help(); + gchar *filter[] = { "/about", "/clear", "/close", "/connect", + "/disconnect", "/help", "/msg", "/join", "/quit", "/vercheck", + "/wins" }; + _cmd_show_filtered_help("Basic commands", filter, ARRAY_SIZE(filter)); + + } else if (strcmp(args[0], "chatting") == 0) { + gchar *filter[] = { "/chlog", "/duck", "/gone", "/history", + "/info", "/intype", "/msg", "/notify", "/outtype", "/status", + "/close", "/clear", "/tiny" }; + _cmd_show_filtered_help("Chat commands", filter, ARRAY_SIZE(filter)); + + } else if (strcmp(args[0], "groupchat") == 0) { + gchar *filter[] = { "/close", "/clear", "/decline", "/grlog", + "/invite", "/invites", "/join", "/leave", "/notify", "/msg", + "/rooms", "/tiny", "/who", "/nick" }; + _cmd_show_filtered_help("Groupchat commands", filter, ARRAY_SIZE(filter)); + } else if (strcmp(args[0], "presence") == 0) { - cons_presence_help(); + gchar *filter[] = { "/autoaway", "/away", "/chat", "/dnd", + "/online", "/priority", "/account", "/status", "/statuses", "/who", + "/xa" }; + _cmd_show_filtered_help("Presence commands", filter, ARRAY_SIZE(filter)); + + } else if (strcmp(args[0], "roster") == 0) { + gchar *filter[] = { "/group", "/roster", "/sub", "/who" }; + _cmd_show_filtered_help("Roster commands", filter, ARRAY_SIZE(filter)); + + } else if (strcmp(args[0], "service") == 0) { + gchar *filter[] = { "/caps", "/disco", "/info", "/software", "/rooms" }; + _cmd_show_filtered_help("Service discovery commands", filter, ARRAY_SIZE(filter)); + } else if (strcmp(args[0], "settings") == 0) { - cons_settings_help(); + gchar *filter[] = { "/account", "/autoaway", "/autoping", "/beep", + "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", + "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority", + "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme", + "/titlebar", "/vercheck" }; + _cmd_show_filtered_help("Settings commands", filter, ARRAY_SIZE(filter)); + + } else if (strcmp(args[0], "other") == 0) { + gchar *filter[] = { "/duck", "/vercheck" }; + _cmd_show_filtered_help("Other commands", filter, ARRAY_SIZE(filter)); + } else if (strcmp(args[0], "navigation") == 0) { cons_navigation_help(); } else { @@ -1724,7 +1762,7 @@ _cmd_help(gchar **args, struct cmd_help_t help) sprintf(cmd_with_slash, "/%s", cmd); const gchar **help_text = NULL; - struct cmd_t *command = _cmd_get_command(cmd_with_slash); + Command *command = g_hash_table_lookup(commands, cmd_with_slash); if (command != NULL) { help_text = command->help.long_help; @@ -3446,36 +3484,6 @@ _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help, return TRUE; } -// helper to get command by string - -static struct cmd_t * -_cmd_get_command(const char * const command) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(main_commands); i++) { - struct cmd_t *pcmd = main_commands+i; - if (strcmp(pcmd->cmd, command) == 0) { - return pcmd; - } - } - - for (i = 0; i < ARRAY_SIZE(setting_commands); i++) { - struct cmd_t *pcmd = setting_commands+i; - if (strcmp(pcmd->cmd, command) == 0) { - return pcmd; - } - } - - for (i = 0; i < ARRAY_SIZE(presence_commands); i++) { - struct cmd_t *pcmd = presence_commands+i; - if (strcmp(pcmd->cmd, command) == 0) { - return pcmd; - } - } - - return NULL; -} - static char * _sub_autocomplete(char *input, int *size) { diff --git a/src/command/command.h b/src/command/command.h index 00c18a9c..c20413c8 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -26,11 +26,11 @@ #include // Command help strings -struct cmd_help_t { +typedef struct cmd_help_t { const gchar *usage; const gchar *short_help; const gchar *long_help[50]; -}; +} CommandHelp; void cmd_init(void); void cmd_close(void); diff --git a/src/ui/console.c b/src/ui/console.c index 992ac9b5..84ef2488 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -43,7 +43,6 @@ static ProfWin* console; static void _cons_splash_logo(void); -static void _cons_show_basic_help(void); ProfWin * cons_create(void) @@ -1155,10 +1154,15 @@ cons_help(void) cons_show(""); cons_show("Choose a help option:"); cons_show(""); - cons_show("/help list - List all commands."); - cons_show("/help basic - Summary of basic usage commands."); - cons_show("/help presence - Summary of online status change commands."); - cons_show("/help settings - Summary of commands for changing Profanity settings."); + cons_show("/help commands - List all commands."); + cons_show("/help basic - List basic commands for getting started."); + cons_show("/help chatting - List chat commands."); + cons_show("/help groupchat - List groupchat commands."); + cons_show("/help presence - List commands to change presence."); + cons_show("/help roster - List commands for manipulating your roster."); + cons_show("/help service - List service discovery commands"); + cons_show("/help settings - List commands for changing settings."); + cons_show("/help other - Other commands."); cons_show("/help navigation - How to navigate around Profanity."); cons_show("/help [command] - Detailed help on a specific command."); cons_show(""); @@ -1167,57 +1171,6 @@ cons_help(void) cons_alert(); } -void -cons_basic_help(void) -{ - cons_show(""); - cons_show("Basic Commands:"); - _cons_show_basic_help(); - - ui_console_dirty(); - cons_alert(); -} - -void -cons_settings_help(void) -{ - cons_show(""); - cons_show("Settings:"); - cons_show(""); - - GSList *settings_helpers = cmd_get_settings_help(); - while (settings_helpers != NULL) { - struct cmd_help_t *help = (struct cmd_help_t *)settings_helpers->data; - cons_show("%-27s: %s", help->usage, help->short_help); - settings_helpers = g_slist_next(settings_helpers); - } - - cons_show(""); - - ui_console_dirty(); - cons_alert(); -} - -void -cons_presence_help(void) -{ - cons_show(""); - cons_show("Presence changes:"); - cons_show(""); - - GSList *presence_helpers = cmd_get_presence_help(); - while (presence_helpers != NULL) { - struct cmd_help_t *help = (struct cmd_help_t *)presence_helpers->data; - cons_show("%-25s: %s", help->usage, help->short_help); - presence_helpers = g_slist_next(presence_helpers); - } - - cons_show(""); - - ui_console_dirty(); - cons_alert(); -} - void cons_navigation_help(void) { @@ -1230,8 +1183,9 @@ cons_navigation_help(void) cons_show("F2..F10 : Chat windows."); cons_show("UP, DOWN : Navigate input history."); cons_show("LEFT, RIGHT, HOME, END : Edit current input."); + cons_show("CTRL-LEFT, CTRL-RIGHT : Jump word in input."); cons_show("ESC : Clear current input."); - cons_show("TAB : Autocomplete command/recipient/login."); + cons_show("TAB : Autocomplete."); cons_show("PAGE UP, PAGE DOWN : Page the main window."); cons_show(""); @@ -1411,22 +1365,3 @@ _cons_splash_logo(void) wprintw(console->win, "Version %s\n", PACKAGE_VERSION); } } - -static void -_cons_show_basic_help(void) -{ - cons_show(""); - - GSList *basic_helpers = cmd_get_basic_help(); - while (basic_helpers != NULL) { - struct cmd_help_t *help = (struct cmd_help_t *)basic_helpers->data; - cons_show("%-30s: %s", help->usage, help->short_help); - basic_helpers = g_slist_next(basic_helpers); - } - - cons_show(""); - ui_console_dirty(); - cons_alert(); -} - -