1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Restructured help

This commit is contained in:
James Booth 2013-06-25 00:49:29 +01:00
parent b48ef9d5e0
commit c8567cd793
3 changed files with 169 additions and 226 deletions

View File

@ -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);
}
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("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(", ");
}
}
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)
{

View File

@ -26,11 +26,11 @@
#include <glib.h>
// 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);

View File

@ -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();
}