1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-07-01 13:26:44 +02:00

auto-completion for paths when sending file & improved auto-complete algorithm to do partial matches

This commit is contained in:
Jfreegman
2014-07-18 01:29:46 -04:00
parent e61d070def
commit ea3fcd5b79
11 changed files with 334 additions and 121 deletions

View File

@ -208,97 +208,3 @@ void fetch_hist_item(ChatContext *ctx, int key_dir)
ctx->pos = h_len;
ctx->len = h_len;
}
/* looks for the first instance in list that begins 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
with "Hello john".
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.
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)
{
if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE)
return -1;
const char *L = (char *) list;
char ubuf[MAX_STR_SIZE];
/* work with multibyte string copy of buf for simplicity */
if (wcs_to_mbs_buf(ubuf, ctx->line, sizeof(ubuf)) == -1)
return -1;
/* isolate substring from space behind pos to pos */
char tmp[MAX_STR_SIZE];
snprintf(tmp, sizeof(tmp), "%s", ubuf);
tmp[ctx->pos] = '\0';
const char *s = strrchr(tmp, ' ');
int n_endchrs = 1; /* 1 = append space to end of match, 2 = append ": " */
char *sub = malloc(strlen(ubuf) + 1);
if (sub == NULL)
exit_toxic_err("failed in complete_line", FATALERR_MEMORY);
if (!s) {
strcpy(sub, tmp);
if (sub[0] != '/') /* make sure it's not a command */
n_endchrs = 2;
} else {
strcpy(sub, &s[1]);
}
if (string_is_empty(sub)) {
free(sub);
return -1;
}
int s_len = strlen(sub);
const char *match;
bool is_match = false;
int i;
/* look for a match in list */
for (i = 0; i < n_items; ++i) {
match = &L[i * size];
if ((is_match = strncasecmp(match, sub, s_len) == 0))
break;
}
free(sub);
if (!is_match)
return -1;
/* put match in correct spot in buf and append endchars (space or ": ") */
const char *endchrs = n_endchrs == 1 ? " " : ": ";
int m_len = strlen(match);
int strt = ctx->pos - s_len;
int diff = m_len - s_len + n_endchrs;
if (ctx->len + diff > MAX_STR_SIZE)
return -1;
char tmpend[MAX_STR_SIZE];
strcpy(tmpend, &ubuf[ctx->pos]);
strcpy(&ubuf[strt], match);
strcpy(&ubuf[strt + m_len], endchrs);
strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
/* convert to widechar and copy back to original buf */
wchar_t newbuf[MAX_STR_SIZE];
if (mbs_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1)
return -1;
wcscpy(ctx->line, newbuf);
ctx->len += diff;
ctx->pos += diff;
return diff;
}