mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-23 02:23:02 +01:00
implement tab completion for commands
This commit is contained in:
parent
9c2551b3b9
commit
674aa682e7
22
src/chat.c
22
src/chat.c
@ -21,6 +21,8 @@ extern int store_data(Tox *m, char *path);
|
|||||||
extern FileSender file_senders[MAX_FILES];
|
extern FileSender file_senders[MAX_FILES];
|
||||||
extern ToxicFriend friends[MAX_FRIENDS_NUM];
|
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)
|
static void chat_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *msg, uint16_t len)
|
||||||
{
|
{
|
||||||
if (self->num != num)
|
if (self->num != num)
|
||||||
@ -344,7 +346,25 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
else
|
else
|
||||||
wmove(self->window, y, x+1);
|
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 HAVE_WIDECHAR
|
||||||
if (iswprint(key))
|
if (iswprint(key))
|
||||||
#else
|
#else
|
||||||
|
@ -15,8 +15,6 @@ struct cmd_func {
|
|||||||
void (*func)(WINDOW *w, ToxWindow *, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
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[] = {
|
static struct cmd_func global_commands[] = {
|
||||||
{ "/accept", cmd_accept },
|
{ "/accept", cmd_accept },
|
||||||
{ "/add", cmd_add },
|
{ "/add", cmd_add },
|
||||||
@ -33,8 +31,6 @@ static struct cmd_func global_commands[] = {
|
|||||||
{ "/status", cmd_status },
|
{ "/status", cmd_status },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHAT_NUM_COMMANDS 5
|
|
||||||
|
|
||||||
static struct cmd_func chat_commands[] = {
|
static struct cmd_func chat_commands[] = {
|
||||||
{ "/help", cmd_chat_help },
|
{ "/help", cmd_chat_help },
|
||||||
{ "/invite", cmd_groupinvite },
|
{ "/invite", cmd_groupinvite },
|
||||||
@ -43,6 +39,28 @@ static struct cmd_func chat_commands[] = {
|
|||||||
{ "/sendfile", cmd_sendfile },
|
{ "/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.
|
/* Parses input command and puts args into arg array.
|
||||||
Returns number of arguments on success, -1 on failure. */
|
Returns number of arguments on success, -1 on failure. */
|
||||||
static int parse_command(WINDOW *w, char *cmd, char (*args)[MAX_STR_SIZE])
|
static int parse_command(WINDOW *w, char *cmd, char (*args)[MAX_STR_SIZE])
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_NUM_ARGS 4 /* Includes command */
|
#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 {
|
enum {
|
||||||
GLOBAL_COMMAND_MODE,
|
GLOBAL_COMMAND_MODE,
|
||||||
|
@ -21,6 +21,8 @@ extern int store_data(Tox *m, char *path);
|
|||||||
static GroupChat groupchats[MAX_WINDOWS_NUM];
|
static GroupChat groupchats[MAX_WINDOWS_NUM];
|
||||||
static int max_groupchat_index = 0;
|
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 init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum)
|
||||||
{
|
{
|
||||||
int i;
|
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 */
|
else if (key == '\t') { /* TAB key: completes peer name */
|
||||||
if (ctx->len > 0) {
|
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);
|
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 (diff != -1) {
|
||||||
if (x + diff > x2 - 1) {
|
if (x + diff > x2 - 1) {
|
||||||
|
@ -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.
|
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 */
|
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)
|
if (*pos <= 0 || *len <= 0 || *len >= MAX_STR_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
const uint8_t *L = (uint8_t *) list;
|
||||||
|
|
||||||
uint8_t ubuf[MAX_STR_SIZE];
|
uint8_t ubuf[MAX_STR_SIZE];
|
||||||
/* work with multibyte string copy of buf for simplicity */
|
/* work with multibyte string copy of buf for simplicity */
|
||||||
if (wcs_to_mbs_buf(ubuf, buf, MAX_STR_SIZE) == -1)
|
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 */
|
/* look for a match in list */
|
||||||
for (i = 0; i < n_items; ++i) {
|
for (i = 0; i < n_items; ++i) {
|
||||||
match = &list[i*size];
|
match = &L[i*size];
|
||||||
if (is_match = strncasecmp(match, sub, s_len) == 0)
|
if (is_match = strncasecmp(match, sub, s_len) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
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 */
|
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);
|
||||||
|
10
src/prompt.c
10
src/prompt.c
@ -17,6 +17,7 @@
|
|||||||
uint8_t pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE] = {0};
|
uint8_t pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE] = {0};
|
||||||
uint8_t num_frnd_requests = 0;
|
uint8_t num_frnd_requests = 0;
|
||||||
extern ToxWindow *prompt;
|
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
|
/* prevents input string from eating system messages: call this prior to printing a prompt message
|
||||||
TODO: This is only a partial fix */
|
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) {
|
else if (key == KEY_RIGHT) {
|
||||||
if (prt->pos < prt->len)
|
if (prt->pos < prt->len)
|
||||||
++prt->pos;
|
++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 HAVE_WIDECHAR
|
||||||
if (iswprint(key))
|
if (iswprint(key))
|
||||||
#else
|
#else
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define MAX_WINDOWS_NUM 32
|
#define MAX_WINDOWS_NUM 32
|
||||||
#define MAX_FRIENDS_NUM 100
|
#define MAX_FRIENDS_NUM 100
|
||||||
#define MAX_STR_SIZE 256
|
#define MAX_STR_SIZE 256
|
||||||
|
#define MAX_CMDNAME_SIZE 64
|
||||||
#define KEY_SIZE_BYTES 32
|
#define KEY_SIZE_BYTES 32
|
||||||
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be < TOX_MAX_NAME_LENGTH */
|
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be < TOX_MAX_NAME_LENGTH */
|
||||||
#define N_DEFAULT_WINS 2 /* number of permanent default windows */
|
#define N_DEFAULT_WINS 2 /* number of permanent default windows */
|
||||||
|
Loading…
Reference in New Issue
Block a user