Mercurial > hg > nnchat
changeset 189:b0d64dde62af
Fix username tab completion. Should now work like in Irssi, though the
problem with usernames with whitespace still exists.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 16 Nov 2010 19:28:31 +0200 |
parents | 6b399b7ce40b |
children | df284de8b118 |
files | nnchat.c |
diffstat | 1 files changed, 63 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/nnchat.c Tue Nov 16 02:40:17 2010 +0200 +++ b/nnchat.c Tue Nov 16 19:28:31 2010 +0200 @@ -732,48 +732,78 @@ BOOL performTabCompletion(nn_editbuf_t *buf) { - static char *previous = NULL; - static char *pattern = NULL; + static char *previous = NULL, *pattern = NULL; + BOOL again = FALSE, hasSeparator = FALSE, newPattern = FALSE, hasSpace = FALSE; + char *str = buf->data; int mode = 0; - BOOL again = FALSE; - char *str = buf->data; - ssize_t endPos = 0, startPos = buf->pos; + ssize_t endPos, startPos = buf->pos; - if (startPos > 1 && str[startPos - 1] == ' ') { + /* previous word */ + if (startPos >= 2 && str[startPos - 1] == ' ' && str[startPos - 2] != ' ') { startPos -= 2; - if (str[startPos] == optNickSep) - startPos--; - if (startPos <= 0 || str[startPos] == ' ') - return FALSE; endPos = startPos; while (startPos > 0 && str[startPos - 1] != ' ') startPos--; mode = 1; } else - if (str[startPos - 1] != ' ' && (startPos == buf->len || str[startPos] == ' ')) { - char *npattern; - + /* middle of a word, new pattern */ + if (startPos < buf->len && str[startPos] != ' ') { + endPos = startPos; + while (startPos > 0 && str[startPos - 1] != ' ') startPos--; + while (endPos < buf->len - 1 && str[endPos + 1] != ' ') endPos++; + newPattern = TRUE; + mode = 2; + } else + /* previous word, new pattern */ + if (startPos >= 1 && str[startPos - 1] != ' ') { + startPos -= 1; endPos = startPos; while (startPos > 0 && str[startPos - 1] != ' ') startPos--; - while (endPos < buf->len && str[endPos] != ' ') endPos++; - while (endPos > 0 && str[endPos] == ' ') endPos--; - if (str[endPos] == optNickSep) + newPattern = TRUE; + mode = 3; + } else { + if (optDebug) + printMsg("no mode\n"); + return FALSE; + } + + if (str[endPos] == optNickSep) { + endPos--; + if (startPos > 0) { + if (optDebug) + printMsg("str[endPos] == optNickSep && startPos > 0 (%d)\n", startPos); return FALSE; - + } + hasSeparator = TRUE; + } + + if (buf->pos > 0 && str[buf->pos - 1] == ' ') + hasSpace = TRUE; + if (buf->pos <= buf->len && str[buf->pos] == ' ') + hasSpace = TRUE; + + if (newPattern) { /* Get pattern, check if it matches previous pattern and set 'again' flag */ - npattern = nn_editbuf_get_string(buf, startPos, endPos); + char *npattern = nn_editbuf_get_string(buf, startPos, endPos); if (pattern && npattern && strcasecmp(npattern, pattern) == 0) again = TRUE; - th_free(pattern); pattern = npattern; + + th_free(pattern); + pattern = npattern; + if (!again) { th_free(previous); previous = NULL; } - mode = 2; - } + } - if (optDebug) - printMsg("sPos=%d, ePos=%d <-> bLen=%d : pat='%s' (mode=%d, again=%s)\n", - startPos, endPos, buf->len, pattern, mode, again ? "yes" : "no"); + if (optDebug) { + printMsg("sPos=%d, ePos=%d <-> bPos=%d, bufLen=%d : pat='%s' (again=%s, hassep=%s, hasspc=%s, newpat=%s, mode=%d)\n", + startPos, endPos, buf->pos, buf->len, pattern, + again ? "yes" : "no", + hasSeparator ? "yes" : "no", + hasSpace ? "yes" : "no", + newPattern ? "yes" : "no", mode); + } if (pattern) { nn_user_t *user = nn_user_match(nnUsers, pattern, previous, again); @@ -790,14 +820,16 @@ for (i = startPos; *c; i++, c++) nn_editbuf_insert(buf, i, *c); - if (previous == NULL || again) { - if (startPos == 0) { - nn_editbuf_insert(buf, i++, optNickSep); - startPos++; - } + if (!hasSeparator && startPos == 0) { + nn_editbuf_insert(buf, i++, optNickSep); + startPos++; + } + if (hasSeparator) + startPos++; + if (!hasSpace) nn_editbuf_insert(buf, i++, ' '); - } - nn_editbuf_setpos(buf, startPos + 2 + strlen(user->name)); + + nn_editbuf_setpos(buf, startPos + 1 + strlen(user->name)); th_free(previous); previous = th_strdup(user->name);