diff options
Diffstat (limited to 'src/command/cmd_defs.c')
-rw-r--r-- | src/command/cmd_defs.c | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index d5eba7c8..9c320a4f 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -113,12 +113,12 @@ static gboolean _cmd_has_tag(Command *pcmd, const char *const tag); static struct cmd_t command_defs[] = { { "/help", - parse_args, 0, 2, NULL, + parse_args_with_freetext, 0, 2, NULL, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_help) CMD_NOTAGS CMD_SYN( - "/help [<area>|<command>]") + "/help [<area>|<command>|search] [<search_term>]") CMD_DESC( "Help on using Profanity. Passing no arguments list help areas. " "For command help, optional arguments are shown using square brackets, " @@ -127,8 +127,10 @@ static struct cmd_t command_defs[] = "e.g. val1|val2|val3.") CMD_ARGS( { "<area>", "Summary help for commands in a certain area of functionality." }, - { "<command>", "Full help for a specific command, for example '/help connect'." }) + { "<command>", "Full help for a specific command, for example '/help connect'." }, + { "search <search_term>", "Search commands for search_term." }) CMD_EXAMPLES( + "/help search presence show", "/help commands", "/help presence", "/help who") @@ -2264,9 +2266,75 @@ static struct cmd_t command_defs[] = CMD_EXAMPLES( "/export /path/to/output.csv", "/export ~/contacts.csv") - }, + } }; +static GHashTable *search_index; + +char* +_cmd_index(Command *cmd) { + GString *index_source = g_string_new(""); + index_source = g_string_append(index_source, cmd->cmd); + index_source = g_string_append(index_source, " "); + index_source = g_string_append(index_source, cmd->help.desc); + index_source = g_string_append(index_source, " "); + + int len = g_strv_length(cmd->help.tags); + int i = 0; + for (i = 0; i < len; i++) { + index_source = g_string_append(index_source, cmd->help.tags[i]); + index_source = g_string_append(index_source, " "); + } + len = g_strv_length(cmd->help.synopsis); + for (i = 0; i < len; i++) { + index_source = g_string_append(index_source, cmd->help.synopsis[i]); + index_source = g_string_append(index_source, " "); + } + for (i = 0; cmd->help.args[i][0] != NULL; i++) { + index_source = g_string_append(index_source, cmd->help.args[i][0]); + index_source = g_string_append(index_source, " "); + index_source = g_string_append(index_source, cmd->help.args[i][1]); + index_source = g_string_append(index_source, " "); + } + + gchar **tokens = g_str_tokenize_and_fold(index_source->str, NULL, NULL); + + GString *index = g_string_new(""); + i = 0; + for (i = 0; i < g_strv_length(tokens); i++) { + index = g_string_append(index, tokens[i]); + index = g_string_append(index, " "); + } + + char *res = index->str; + g_string_free(index, FALSE); + + return res; +} + +GList* +cmd_search_index(char *term) +{ + GList *results = NULL; + + gchar **processed_terms = g_str_tokenize_and_fold(term, NULL, NULL); + int terms_len = g_strv_length(processed_terms); + + int i = 0; + for (i = 0; i < terms_len; i++) { + GList *index_keys = g_hash_table_get_keys(search_index); + GList *curr = index_keys; + while (curr) { + char *index_entry = g_hash_table_lookup(search_index, curr->data); + if (g_str_match_string(processed_terms[i], index_entry, FALSE)) { + results = g_list_append(results, curr->data); + } + curr = g_list_next(curr); + } + } + + return results; +} /* * Initialise command autocompleter and history @@ -2278,6 +2346,8 @@ cmd_init(void) cmd_ac_init(); + search_index = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); + // load command defs into hash table commands = g_hash_table_new(g_str_hash, g_str_equal); unsigned int i; @@ -2287,6 +2357,9 @@ cmd_init(void) // add to hash g_hash_table_insert(commands, pcmd->cmd, pcmd); + // add to search index + g_hash_table_insert(search_index, strdup(pcmd->cmd), strdup(_cmd_index(pcmd))); + // add to commands and help autocompleters cmd_ac_add_cmd(pcmd); } |