Moved autcomplete code to command.c

This commit is contained in:
James Booth
2012-10-28 01:08:04 +01:00
parent adf1a6ae4a
commit 34392622ea
4 changed files with 110 additions and 75 deletions

View File

@@ -38,16 +38,20 @@
#include "tinyurl.h" #include "tinyurl.h"
#include "ui.h" #include "ui.h"
typedef char*(*autocomplete_func)(char *);
/* /*
* Command structure * Command structure
* *
* cmd - The command string including leading '/' * cmd - The command string including leading '/'
* func - The function to execute for the command * func - The function to execute for the command
* complete_func - Function to autcomplete parameters
* help - A help struct containing usage info etc * help - A help struct containing usage info etc
*/ */
struct cmd_t { struct cmd_t {
const gchar *cmd; const gchar *cmd;
gboolean (*func)(const char * const inp, struct cmd_help_t help); gboolean (*func)(const char * const inp, struct cmd_help_t help);
autocomplete_func complete_func;
struct cmd_help_t help; struct cmd_help_t help;
}; };
@@ -57,6 +61,9 @@ static void _update_presence(const jabber_presence_t presence,
static gboolean _cmd_set_boolean_preference(const char * const inp, static gboolean _cmd_set_boolean_preference(const char * const inp,
struct cmd_help_t help, const char * const cmd_str, const char * const display, struct cmd_help_t help, const char * const cmd_str, const char * const display,
void (*set_func)(gboolean)); void (*set_func)(gboolean));
static char *_cmd_help_complete(char *inp);
static void _parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func);
// command prototypes // command prototypes
static gboolean _cmd_quit(const char * const inp, struct cmd_help_t help); static gboolean _cmd_quit(const char * const inp, struct cmd_help_t help);
@@ -93,6 +100,7 @@ static struct cmd_t main_commands[] =
{ {
{ "/help", { "/help",
_cmd_help, _cmd_help,
_cmd_help_complete,
{ "/help [area|command]", "Show help summary, or help on a specific area or command", { "/help [area|command]", "Show help summary, or help on a specific area or command",
{ "/help [area|command]", { "/help [area|command]",
"--------------------", "--------------------",
@@ -106,6 +114,7 @@ static struct cmd_t main_commands[] =
{ "/about", { "/about",
_cmd_about, _cmd_about,
NULL,
{ "/about", "About Profanity", { "/about", "About Profanity",
{ "/about", { "/about",
"------", "------",
@@ -114,6 +123,7 @@ static struct cmd_t main_commands[] =
{ "/connect", { "/connect",
_cmd_connect, _cmd_connect,
prefs_find_login,
{ "/connect user@host", "Login to jabber.", { "/connect user@host", "Login to jabber.",
{ "/connect user@host", { "/connect user@host",
"------------------", "------------------",
@@ -126,6 +136,7 @@ static struct cmd_t main_commands[] =
{ "/disconnect", { "/disconnect",
_cmd_disconnect, _cmd_disconnect,
NULL,
{ "/disconnect", "Logout of current jabber session.", { "/disconnect", "Logout of current jabber session.",
{ "/disconnect", { "/disconnect",
"------------------", "------------------",
@@ -135,6 +146,7 @@ static struct cmd_t main_commands[] =
{ "/prefs", { "/prefs",
_cmd_prefs, _cmd_prefs,
NULL,
{ "/prefs", "Show current preferences.", { "/prefs", "Show current preferences.",
{ "/prefs", { "/prefs",
"------", "------",
@@ -149,6 +161,7 @@ static struct cmd_t main_commands[] =
{ "/msg", { "/msg",
_cmd_msg, _cmd_msg,
contact_list_find_contact,
{ "/msg user@host mesg", "Send mesg to user.", { "/msg user@host mesg", "Send mesg to user.",
{ "/msg user@host mesg", { "/msg user@host mesg",
"-------------------", "-------------------",
@@ -164,6 +177,7 @@ static struct cmd_t main_commands[] =
{ "/tiny", { "/tiny",
_cmd_tiny, _cmd_tiny,
NULL,
{ "/tiny url", "Send url as tinyurl in current chat.", { "/tiny url", "Send url as tinyurl in current chat.",
{ "/tiny url", { "/tiny url",
"---------", "---------",
@@ -176,6 +190,7 @@ static struct cmd_t main_commands[] =
{ "/who", { "/who",
_cmd_who, _cmd_who,
NULL,
{ "/who [status]", "Show contacts with chosen status.", { "/who [status]", "Show contacts with chosen status.",
{ "/who [status]", { "/who [status]",
"-------------", "-------------",
@@ -186,6 +201,7 @@ static struct cmd_t main_commands[] =
{ "/close", { "/close",
_cmd_close, _cmd_close,
NULL,
{ "/close", "Close current chat window.", { "/close", "Close current chat window.",
{ "/close", { "/close",
"------", "------",
@@ -195,6 +211,7 @@ static struct cmd_t main_commands[] =
{ "/quit", { "/quit",
_cmd_quit, _cmd_quit,
NULL,
{ "/quit", "Quit Profanity.", { "/quit", "Quit Profanity.",
{ "/quit", { "/quit",
"-----", "-----",
@@ -206,6 +223,7 @@ static struct cmd_t setting_commands[] =
{ {
{ "/beep", { "/beep",
_cmd_set_beep, _cmd_set_beep,
prefs_autocomplete_boolean_choice,
{ "/beep on|off", "Terminal beep on new messages.", { "/beep on|off", "Terminal beep on new messages.",
{ "/beep on|off", { "/beep on|off",
"------------", "------------",
@@ -220,6 +238,7 @@ static struct cmd_t setting_commands[] =
{ "/notify", { "/notify",
_cmd_set_notify, _cmd_set_notify,
NULL,
{ "/notify type value", "Control various desktop noficiations.", { "/notify type value", "Control various desktop noficiations.",
{ "/notify type value", { "/notify type value",
"------------------", "------------------",
@@ -245,6 +264,7 @@ static struct cmd_t setting_commands[] =
{ "/flash", { "/flash",
_cmd_set_flash, _cmd_set_flash,
prefs_autocomplete_boolean_choice,
{ "/flash on|off", "Terminal flash on new messages.", { "/flash on|off", "Terminal flash on new messages.",
{ "/flash on|off", { "/flash on|off",
"-------------", "-------------",
@@ -259,6 +279,7 @@ static struct cmd_t setting_commands[] =
{ "/intype", { "/intype",
_cmd_set_intype, _cmd_set_intype,
prefs_autocomplete_boolean_choice,
{ "/intype on|off", "Show when contact is typing.", { "/intype on|off", "Show when contact is typing.",
{ "/intype on|off", { "/intype on|off",
"--------------", "--------------",
@@ -270,6 +291,7 @@ static struct cmd_t setting_commands[] =
{ "/showsplash", { "/showsplash",
_cmd_set_showsplash, _cmd_set_showsplash,
prefs_autocomplete_boolean_choice,
{ "/showsplash on|off", "Splash logo on startup.", { "/showsplash on|off", "Splash logo on startup.",
{ "/showsplash on|off", { "/showsplash on|off",
"------------------", "------------------",
@@ -281,6 +303,7 @@ static struct cmd_t setting_commands[] =
{ "/vercheck", { "/vercheck",
_cmd_vercheck, _cmd_vercheck,
prefs_autocomplete_boolean_choice,
{ "/vercheck [on|off]", "Check for a new release.", { "/vercheck [on|off]", "Check for a new release.",
{ "/vercheck [on|off]", { "/vercheck [on|off]",
"------------------", "------------------",
@@ -291,6 +314,7 @@ static struct cmd_t setting_commands[] =
{ "/chlog", { "/chlog",
_cmd_set_chlog, _cmd_set_chlog,
prefs_autocomplete_boolean_choice,
{ "/chlog on|off", "Chat logging to file", { "/chlog on|off", "Chat logging to file",
{ "/chlog on|off", { "/chlog on|off",
"-------------", "-------------",
@@ -307,6 +331,7 @@ static struct cmd_t setting_commands[] =
{ "/history", { "/history",
_cmd_set_history, _cmd_set_history,
prefs_autocomplete_boolean_choice,
{ "/history on|off", "Chat history in message windows.", { "/history on|off", "Chat history in message windows.",
{ "/history on|off", { "/history on|off",
"-------------", "-------------",
@@ -322,6 +347,7 @@ static struct cmd_t status_commands[] =
{ {
{ "/away", { "/away",
_cmd_away, _cmd_away,
NULL,
{ "/away [msg]", "Set status to away.", { "/away [msg]", "Set status to away.",
{ "/away [msg]", { "/away [msg]",
"-----------", "-----------",
@@ -333,6 +359,7 @@ static struct cmd_t status_commands[] =
{ "/chat", { "/chat",
_cmd_chat, _cmd_chat,
NULL,
{ "/chat [msg]", "Set status to chat (available for chat).", { "/chat [msg]", "Set status to chat (available for chat).",
{ "/chat [msg]", { "/chat [msg]",
"-----------", "-----------",
@@ -345,6 +372,7 @@ static struct cmd_t status_commands[] =
{ "/dnd", { "/dnd",
_cmd_dnd, _cmd_dnd,
NULL,
{ "/dnd [msg]", "Set status to dnd (do not disturb.", { "/dnd [msg]", "Set status to dnd (do not disturb.",
{ "/dnd [msg]", { "/dnd [msg]",
"----------", "----------",
@@ -357,6 +385,7 @@ static struct cmd_t status_commands[] =
{ "/online", { "/online",
_cmd_online, _cmd_online,
NULL,
{ "/online [msg]", "Set status to online.", { "/online [msg]", "Set status to online.",
{ "/online [msg]", { "/online [msg]",
"-------------", "-------------",
@@ -368,6 +397,7 @@ static struct cmd_t status_commands[] =
{ "/xa", { "/xa",
_cmd_xa, _cmd_xa,
NULL,
{ "/xa [msg]", "Set status to xa (extended away).", { "/xa [msg]", "Set status to xa (extended away).",
{ "/xa [msg]", { "/xa [msg]",
"---------", "---------",
@@ -446,8 +476,8 @@ cmd_reset_completer(void)
} }
// Command help autocomplete // Command help autocomplete
char * static char *
cmd_help_complete(char *inp) _cmd_help_complete(char *inp)
{ {
return p_autocomplete_complete(help_ac, inp); return p_autocomplete_complete(help_ac, inp);
} }
@@ -545,6 +575,32 @@ cmd_execute_default(const char * const inp)
return TRUE; return TRUE;
} }
void
cmd_complete_parameters(char *input, int *size)
{
_parameter_autocomplete(input, size, "/beep",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/intype",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/flash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/showsplash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/chlog",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/history",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/vercheck",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/msg",
contact_list_find_contact);
_parameter_autocomplete(input, size, "/connect",
prefs_find_login);
_parameter_autocomplete(input, size, "/help",
_cmd_help_complete);
}
// The command functions // The command functions
static gboolean static gboolean
@@ -1114,3 +1170,33 @@ _cmd_get_command(const char * const command)
return NULL; return NULL;
} }
static void
_parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func)
{
char *found = NULL;
char *auto_msg = NULL;
char inp_cpy[*size];
int i;
char *command_cpy = malloc(strlen(command) + 2);
sprintf(command_cpy, "%s ", command);
int len = strlen(command_cpy);
if ((strncmp(input, command_cpy, len) == 0) && (*size > len)) {
for(i = len; i < *size; i++) {
inp_cpy[i-len] = input[i];
}
inp_cpy[(*size) - len] = '\0';
found = func(inp_cpy);
if (found != NULL) {
auto_msg = (char *) malloc((len + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, command_cpy);
strcat(auto_msg, found);
inp_replace_input(input, auto_msg, size);
free(auto_msg);
free(found);
}
}
free(command_cpy);
}

View File

@@ -36,6 +36,7 @@ void cmd_init(void);
void cmd_close(void); void cmd_close(void);
char * cmd_complete(char *inp); char * cmd_complete(char *inp);
void cmd_reset_completer(void); void cmd_reset_completer(void);
void cmd_complete_parameters(char *input, int *size);
gboolean cmd_execute(const char * const command, const char * const inp); gboolean cmd_execute(const char * const command, const char * const inp);
gboolean cmd_execute_default(const char * const inp); gboolean cmd_execute_default(const char * const inp);

View File

@@ -58,16 +58,11 @@
#include "preferences.h" #include "preferences.h"
#include "ui.h" #include "ui.h"
typedef char*(*autocomplete_func)(char *);
static WINDOW *inp_win; static WINDOW *inp_win;
static int pad_start = 0; static int pad_start = 0;
static int _handle_edit(const int ch, char *input, int *size); static int _handle_edit(const int ch, char *input, int *size);
static int _printable(const int ch); static int _printable(const int ch);
static void _replace_input(char *input, const char * const new_input, int *size);
static void _parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func);
static void _notify_autocomplete(char *input, int *size); static void _notify_autocomplete(char *input, int *size);
void void
@@ -206,6 +201,19 @@ inp_put_back(void)
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1); prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
} }
void
inp_replace_input(char *input, const char * const new_input, int *size)
{
int i;
strcpy(input, new_input);
*size = strlen(input);
inp_clear();
for (i = 0; i < *size; i++)
waddch(inp_win, input[i]);
}
/* /*
* Deal with command editing, return 1 if ch was an edit * Deal with command editing, return 1 if ch was an edit
* key press: up, down, left, right or backspace * key press: up, down, left, right or backspace
@@ -307,7 +315,7 @@ _handle_edit(const int ch, char *input, int *size)
case KEY_UP: case KEY_UP:
prev = history_previous(input, size); prev = history_previous(input, size);
if (prev) { if (prev) {
_replace_input(input, prev, size); inp_replace_input(input, prev, size);
pad_start = 0; pad_start = 0;
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1); prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
} }
@@ -316,7 +324,7 @@ _handle_edit(const int ch, char *input, int *size)
case KEY_DOWN: case KEY_DOWN:
next = history_next(input, size); next = history_next(input, size);
if (next) { if (next) {
_replace_input(input, next, size); inp_replace_input(input, next, size);
pad_start = 0; pad_start = 0;
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1); prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
} }
@@ -348,33 +356,13 @@ _handle_edit(const int ch, char *input, int *size)
if (found != NULL) { if (found != NULL) {
auto_msg = (char *) malloc((strlen(found) + 1) * sizeof(char)); auto_msg = (char *) malloc((strlen(found) + 1) * sizeof(char));
strcpy(auto_msg, found); strcpy(auto_msg, found);
_replace_input(input, auto_msg, size); inp_replace_input(input, auto_msg, size);
free(auto_msg); free(auto_msg);
free(found); free(found);
} }
} }
_parameter_autocomplete(input, size, "/beep", cmd_complete_parameters(input, size);
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/intype",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/flash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/showsplash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/chlog",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/history",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/vercheck",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/msg",
contact_list_find_contact);
_parameter_autocomplete(input, size, "/connect",
prefs_find_login);
_parameter_autocomplete(input, size, "/help",
cmd_help_complete);
_notify_autocomplete(input, size); _notify_autocomplete(input, size);
@@ -397,47 +385,6 @@ _printable(const int ch)
ch != KEY_IC && ch != KEY_EIC && ch != KEY_RESIZE); ch != KEY_IC && ch != KEY_EIC && ch != KEY_RESIZE);
} }
static void
_replace_input(char *input, const char * const new_input, int *size)
{
int i;
strcpy(input, new_input);
*size = strlen(input);
inp_clear();
for (i = 0; i < *size; i++)
waddch(inp_win, input[i]);
}
static void
_parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func)
{
char *found = NULL;
char *auto_msg = NULL;
char inp_cpy[*size];
int i;
char *command_cpy = malloc(strlen(command) + 2);
sprintf(command_cpy, "%s ", command);
int len = strlen(command_cpy);
if ((strncmp(input, command_cpy, len) == 0) && (*size > len)) {
for(i = len; i < *size; i++) {
inp_cpy[i-len] = input[i];
}
inp_cpy[(*size) - len] = '\0';
found = func(inp_cpy);
if (found != NULL) {
auto_msg = (char *) malloc((len + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, command_cpy);
strcat(auto_msg, found);
_replace_input(input, auto_msg, size);
free(auto_msg);
free(found);
}
}
free(command_cpy);
}
static void static void
_notify_autocomplete(char *input, int *size) _notify_autocomplete(char *input, int *size)
{ {
@@ -456,7 +403,7 @@ _notify_autocomplete(char *input, int *size)
auto_msg = (char *) malloc((16 + (strlen(found) + 1)) * sizeof(char)); auto_msg = (char *) malloc((16 + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, "/notify message "); strcpy(auto_msg, "/notify message ");
strcat(auto_msg, found); strcat(auto_msg, found);
_replace_input(input, auto_msg, size); inp_replace_input(input, auto_msg, size);
free(auto_msg); free(auto_msg);
free(found); free(found);
} }
@@ -470,7 +417,7 @@ _notify_autocomplete(char *input, int *size)
auto_msg = (char *) malloc((15 + (strlen(found) + 1)) * sizeof(char)); auto_msg = (char *) malloc((15 + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, "/notify typing "); strcpy(auto_msg, "/notify typing ");
strcat(auto_msg, found); strcat(auto_msg, found);
_replace_input(input, auto_msg, size); inp_replace_input(input, auto_msg, size);
free(auto_msg); free(auto_msg);
free(found); free(found);
} }
@@ -484,7 +431,7 @@ _notify_autocomplete(char *input, int *size)
auto_msg = (char *) malloc((8 + (strlen(found) + 1)) * sizeof(char)); auto_msg = (char *) malloc((8 + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, "/notify "); strcpy(auto_msg, "/notify ");
strcat(auto_msg, found); strcat(auto_msg, found);
_replace_input(input, auto_msg, size); inp_replace_input(input, auto_msg, size);
free(auto_msg); free(auto_msg);
free(found); free(found);
} }

View File

@@ -136,5 +136,6 @@ void inp_put_back(void);
void inp_non_block(void); void inp_non_block(void);
void inp_block(void); void inp_block(void);
void inp_get_password(char *passwd); void inp_get_password(char *passwd);
void inp_replace_input(char *input, const char * const new_input, int *size);
#endif #endif