From 674aa682e75facb876b71738df26c986ab31600e Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sun, 8 Dec 2013 18:14:57 -0500 Subject: [PATCH] implement tab completion for commands --- src/chat.c | 22 +++++++++++++++++++++- src/execute.c | 26 ++++++++++++++++++++++---- src/execute.h | 3 +++ src/groupchat.c | 9 ++++++++- src/misc_tools.c | 6 ++++-- src/misc_tools.h | 2 +- src/prompt.c | 10 +++++++++- src/toxic_windows.h | 1 + 8 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/chat.c b/src/chat.c index 55dd013..962b40a 100644 --- a/src/chat.c +++ b/src/chat.c @@ -21,6 +21,8 @@ extern int store_data(Tox *m, char *path); extern FileSender file_senders[MAX_FILES]; extern ToxicFriend friends[MAX_FRIENDS_NUM]; +extern cmd_list[TOT_NUM_COMMANDS][MAX_CMDNAME_SIZE]; + static void chat_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *msg, uint16_t len) { if (self->num != num) @@ -344,7 +346,25 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) else wmove(self->window, y, x+1); } - } else + } + + else if (key == '\t') { /* TAB key: command */ + if (ctx->len > 1 && ctx->line[0] == '/') { + int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, cmd_list, TOT_NUM_COMMANDS, + MAX_CMDNAME_SIZE); + + if (diff != -1) { + if (x + diff > x2 - 1) { + int ofst = (x + diff - 1) - (x2 - 1); + wmove(self->window, y+1, ofst); + } else { + wmove(self->window, y, x+diff); + } + } + } + } + + else #if HAVE_WIDECHAR if (iswprint(key)) #else diff --git a/src/execute.c b/src/execute.c index 911c565..d18cea5 100644 --- a/src/execute.c +++ b/src/execute.c @@ -15,8 +15,6 @@ struct cmd_func { void (*func)(WINDOW *w, ToxWindow *, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); }; -#define GLOBAL_NUM_COMMANDS 13 - static struct cmd_func global_commands[] = { { "/accept", cmd_accept }, { "/add", cmd_add }, @@ -33,8 +31,6 @@ static struct cmd_func global_commands[] = { { "/status", cmd_status }, }; -#define CHAT_NUM_COMMANDS 5 - static struct cmd_func chat_commands[] = { { "/help", cmd_chat_help }, { "/invite", cmd_groupinvite }, @@ -43,6 +39,28 @@ static struct cmd_func chat_commands[] = { { "/sendfile", cmd_sendfile }, }; +/* Array of all command names; used for tab completion. */ +const uint8_t cmd_list[TOT_NUM_COMMANDS][MAX_CMDNAME_SIZE] = { + { "/accept" }, + { "/add" }, + { "/clear" }, + { "/connect" }, + { "/exit" }, + { "/groupchat" }, + { "/help" }, + { "/invite" }, + { "/join" }, + { "/myid" }, + { "/nick" }, + { "/note" }, + { "/q" }, + { "/quit" }, + { "/savefile" }, + { "/sendfile" }, + { "/status" }, +}; + + /* Parses input command and puts args into arg array. Returns number of arguments on success, -1 on failure. */ static int parse_command(WINDOW *w, char *cmd, char (*args)[MAX_STR_SIZE]) diff --git a/src/execute.h b/src/execute.h index 2747d16..e7ce741 100644 --- a/src/execute.h +++ b/src/execute.h @@ -3,6 +3,9 @@ */ #define MAX_NUM_ARGS 4 /* Includes command */ +#define GLOBAL_NUM_COMMANDS 13 +#define CHAT_NUM_COMMANDS 5 +#define TOT_NUM_COMMANDS 17 /* -1 for duplicate /help command */ enum { GLOBAL_COMMAND_MODE, diff --git a/src/groupchat.c b/src/groupchat.c index 9a63bff..d425695 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -21,6 +21,8 @@ extern int store_data(Tox *m, char *path); static GroupChat groupchats[MAX_WINDOWS_NUM]; static int max_groupchat_index = 0; +extern cmd_list[TOT_NUM_COMMANDS][MAX_CMDNAME_SIZE]; + int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum) { int i; @@ -306,8 +308,13 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) else if (key == '\t') { /* TAB key: completes peer name */ if (ctx->len > 0) { - int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, groupchats[self->num].peer_names, + int diff; + if (ctx->line[0] != '/') + diff = complete_line(ctx->line, &ctx->pos, &ctx->len, groupchats[self->num].peer_names, groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH); + else + diff = complete_line(ctx->line, &ctx->pos, &ctx->len, cmd_list, TOT_NUM_COMMANDS, + MAX_CMDNAME_SIZE); if (diff != -1) { if (x + diff > x2 - 1) { diff --git a/src/misc_tools.c b/src/misc_tools.c index 9de0787..2cdb25c 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -276,11 +276,13 @@ void reset_buf(wchar_t *buf, size_t *pos, size_t *len) in the list, and size is the size of each item in the list. Returns the difference between the old len and new len of buf on success, -1 if error */ -int complete_line(wchar_t *buf, size_t *pos, size_t *len, const uint8_t *list, int n_items, int size) +int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int n_items, int size) { if (*pos <= 0 || *len <= 0 || *len >= MAX_STR_SIZE) return -1; + const uint8_t *L = (uint8_t *) list; + uint8_t ubuf[MAX_STR_SIZE]; /* work with multibyte string copy of buf for simplicity */ if (wcs_to_mbs_buf(ubuf, buf, MAX_STR_SIZE) == -1) @@ -309,7 +311,7 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const uint8_t *list, i /* look for a match in list */ for (i = 0; i < n_items; ++i) { - match = &list[i*size]; + match = &L[i*size]; if (is_match = strncasecmp(match, sub, s_len) == 0) break; } diff --git a/src/misc_tools.h b/src/misc_tools.h index 85b3ade..ed539ec 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -74,4 +74,4 @@ void reset_buf(wchar_t *buf, size_t *pos, size_t *len); in the list, and size is the size of each item in the list. Returns the difference between the old len and new len of buf on success, -1 if error */ -int complete_line(wchar_t *buf, size_t *pos, size_t *len, const uint8_t *list, int n_items, int size); +int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int n_items, int size); diff --git a/src/prompt.c b/src/prompt.c index dafc003..76bdf9c 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -17,6 +17,7 @@ uint8_t pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE] = {0}; uint8_t num_frnd_requests = 0; extern ToxWindow *prompt; +extern cmd_list[TOT_NUM_COMMANDS][MAX_CMDNAME_SIZE]; /* prevents input string from eating system messages: call this prior to printing a prompt message TODO: This is only a partial fix */ @@ -144,7 +145,14 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) else if (key == KEY_RIGHT) { if (prt->pos < prt->len) ++prt->pos; - } else + + } else if (key == '\t') { /* TAB key: completes command */ + if (prt->len > 1 && prt->line[0] == '/') + complete_line(prt->line, &prt->pos, &prt->len, cmd_list, TOT_NUM_COMMANDS, + MAX_CMDNAME_SIZE); + } + + else #if HAVE_WIDECHAR if (iswprint(key)) #else diff --git a/src/toxic_windows.h b/src/toxic_windows.h index 17699cd..9c5ef17 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -20,6 +20,7 @@ #define MAX_WINDOWS_NUM 32 #define MAX_FRIENDS_NUM 100 #define MAX_STR_SIZE 256 +#define MAX_CMDNAME_SIZE 64 #define KEY_SIZE_BYTES 32 #define TOXIC_MAX_NAME_LENGTH 32 /* Must be < TOX_MAX_NAME_LENGTH */ #define N_DEFAULT_WINS 2 /* number of permanent default windows */