1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-23 01:13:01 +01:00

print multiple matches for all tab-complete operations, fix bug when tab-completing at end of line

This commit is contained in:
Jfreegman 2014-07-18 12:42:53 -04:00
parent d4e41d6053
commit 7e667a8028
5 changed files with 47 additions and 46 deletions

View File

@ -36,9 +36,23 @@
#include "line_info.h" #include "line_info.h"
#include "execute.h" #include "execute.h"
static void print_matches(ToxWindow *self, Tox *m, const void *list, int n_items, int size)
{
if (m)
execute(self->chatwin->history, self, m, "/clear", GLOBAL_COMMAND_MODE);
const char *L = (char *) list;
int i;
for (i = 0; i < n_items; ++i)
line_info_add(self, NULL, NULL, NULL, &L[i * size], SYS_MSG, 0, 0);
line_info_add(self, NULL, NULL, NULL, "", SYS_MSG, 0, 0); /* formatting */
}
/* puts match in match buffer. if more than one match, add first n chars that are identical. /* puts match in match buffer. if more than one match, add first n chars that are identical.
e.g. if matches contains: [foo, foobar, foe] we put fo in matches. */ e.g. if matches contains: [foo, foobar, foe] we put fo in matches. */
static void get_str_match(char *match, char (*matches)[MAX_STR_SIZE], int n) static void get_str_match(ToxWindow *self, char *match, char (*matches)[MAX_STR_SIZE], int n)
{ {
if (n == 1) { if (n == 1) {
strcpy(match, matches[0]); strcpy(match, matches[0]);
@ -46,16 +60,8 @@ static void get_str_match(char *match, char (*matches)[MAX_STR_SIZE], int n)
} }
int i; int i;
int shortest = MAX_STR_SIZE;
for (i = 0; i < n; ++i) { for (i = 0; i < MAX_STR_SIZE; ++i) {
int m_len = strlen(matches[i]);
if (m_len < shortest)
shortest = m_len;
}
for (i = 0; i < shortest; ++i) {
char ch = matches[0][i]; char ch = matches[0][i];
int j; int j;
@ -71,21 +77,22 @@ static void get_str_match(char *match, char (*matches)[MAX_STR_SIZE], int n)
strcpy(match, matches[0]); strcpy(match, matches[0]);
} }
/* looks for the first instance in list that begins with the last entered word in line according to pos, /* looks for all instances in list that begin with the last entered word in line according to pos,
then fills line with the complete word. e.g. "Hello jo" would complete the line then fills line with the complete word. e.g. "Hello jo" would complete the line
with "Hello john". Works slightly differently for directory paths with the same results. with "Hello john". If multiple matches, prints out all the matches and semi-completes line.
list is a pointer to the list of strings being compared, n_items is the number of items list is a pointer to the list of strings being compared, n_items is the number of items
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 line on success, -1 if error */ Returns the difference between the old len and new len of line on success, -1 if error */
int complete_line(ChatContext *ctx, const void *list, int n_items, int size) int complete_line(ToxWindow *self, const void *list, int n_items, int size)
{ {
ChatContext *ctx = self->chatwin;
if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE) if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE)
return -1; return -1;
const char *L = (char *) list; const char *L = (char *) list;
const char *endchrs = " "; const char *endchrs = " ";
char ubuf[MAX_STR_SIZE]; char ubuf[MAX_STR_SIZE];
@ -147,8 +154,11 @@ int complete_line(ChatContext *ctx, const void *list, int n_items, int size)
if (!n_matches) if (!n_matches)
return -1; return -1;
char match[size]; if (!dir_search && n_matches > 1)
get_str_match(match, matches, n_matches); print_matches(self, NULL, matches, n_matches, MAX_STR_SIZE);
char match[MAX_STR_SIZE];
get_str_match(self, match, matches, n_matches);
if (dir_search) { if (dir_search) {
if (n_matches == 1) if (n_matches == 1)
@ -191,7 +201,6 @@ int complete_line(ChatContext *ctx, const void *list, int n_items, int size)
/* matches /sendfile "<incomplete-dir>" line to matching directories. /* matches /sendfile "<incomplete-dir>" line to matching directories.
if only one match, auto-complete line. if only one match, auto-complete line.
if > 1 match, print out all the matches and partially complete line
return diff between old len and new len of ctx->line, or -1 if no matches return diff between old len and new len of ctx->line, or -1 if no matches
*/ */
#define MAX_DIRS 256 #define MAX_DIRS 256
@ -237,14 +246,8 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line)
if (dircount == 0) if (dircount == 0)
return -1; return -1;
if (dircount > 1) { if (dircount > 1)
execute(self->chatwin->history, self, m, "/clear", GLOBAL_COMMAND_MODE); print_matches(self, m, dirnames, dircount, NAME_MAX);
int i; return complete_line(self, dirnames, dircount, NAME_MAX);
for (i = 0; i < dircount; ++i)
line_info_add(self, NULL, NULL, NULL, dirnames[i], SYS_MSG, 0, 0);
}
return complete_line(self->chatwin, dirnames, dircount, NAME_MAX);
} }

View File

@ -23,21 +23,21 @@
#ifndef _autocomplete_h #ifndef _autocomplete_h
#define _autocomplete_h #define _autocomplete_h
/* looks for the first instance in list that begins with the last entered word in line according to pos, /* looks for all instances in list that begin with the last entered word in line according to pos,
then fills line with the complete word. e.g. "Hello jo" would complete the line then fills line with the complete word. e.g. "Hello jo" would complete the line
with "Hello john". Works slightly differently for directory paths with the same results. with "Hello john". If multiple matches, prints out all the matches and semi-completes line.
list is a pointer to the list of strings being compared, n_items is the number of items list is a pointer to the list of strings being compared, n_items is the number of items
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 line on success, -1 if error */ Returns the difference between the old len and new len of line on success, -1 if error */
int complete_line(ChatContext *ctx, const void *list, int n_items, int size); int complete_line(ToxWindow *self, const void *list, int n_items, int size);
/* matches /sendfile "<incomplete-dir>" line to matching directories. /* matches /sendfile "<incomplete-dir>" line to matching directories.
if only one match, auto-complete line and return diff between old len and new len. if only one match, auto-complete line.
return 0 if > 1 match and print out all the matches return diff between old len and new len of ctx->line, or -1 if no matches
return -1 if no matches */ */
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line); int dir_match(ToxWindow *self, Tox *m, const wchar_t *line);
#endif /* #define _autocomplete_h */ #endif /* #define _autocomplete_h */

View File

@ -693,12 +693,14 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (wcsncmp(ctx->line, L"/sendfile \"", sf_len) == 0) { if (wcsncmp(ctx->line, L"/sendfile \"", sf_len) == 0) {
diff = dir_match(self, m, &ctx->line[sf_len]); diff = dir_match(self, m, &ctx->line[sf_len]);
} else { } else {
diff = complete_line(ctx, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE); diff = complete_line(self, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
} }
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) if (x + diff > x2 - 1) {
ctx->start += diff; int wlen = wcswidth(ctx->line, sizeof(ctx->line));
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
}
} else { } else {
beep(); beep();
} }

View File

@ -366,17 +366,15 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
int diff; int diff;
if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e')) if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e'))
diff = complete_line(ctx, groupchats[self->num].peer_names, diff = complete_line(self, groupchats[self->num].peer_names,
groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH); groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH);
else else
diff = complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE); diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
wmove(self->window, y, x + diff); int wlen = wcswidth(ctx->line, sizeof(ctx->line));
ctx->start += diff; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} else {
wmove(self->window, y, x + diff);
} }
} else { } else {
beep(); beep();

View File

@ -177,14 +177,12 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (key == '\t') { /* TAB key: auto-completes command */ if (key == '\t') { /* TAB key: auto-completes command */
if (ctx->len > 1 && ctx->line[0] == '/') { if (ctx->len > 1 && ctx->line[0] == '/') {
int diff = complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE); int diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
wmove(self->window, y, x + diff); int wlen = wcswidth(ctx->line, sizeof(ctx->line));
ctx->start += diff; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} else {
wmove(self->window, y, x + diff);
} }
} else { } else {
beep(); beep();