Implement cycling tab complete

Not properly hooked up to the UI yet.
master
Curtis McEnroe 2018-08-07 22:40:05 -04:00
parent ee49c36655
commit 43eee8da71
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
2 changed files with 39 additions and 7 deletions

3
chat.h
View File

@ -64,6 +64,9 @@ void input(char *line);
void tabTouch(const char *word);
void tabRemove(const char *word);
void tabReplace(const char *prev, const char *next);
const char *tabNext(const char *prefix);
void tabAccept(void);
void tabReject(void);
wchar_t *ambstowcs(const char *src);
char *awcstombs(const wchar_t *src);

43
tab.c
View File

@ -40,12 +40,16 @@ static void remove(struct Entry *entry) {
if (head == entry) head = entry->next;
}
void tabTouch(const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (strcmp(entry->word, word)) continue;
static void touch(struct Entry *entry) {
if (head == entry) return;
remove(entry);
prepend(entry);
}
void tabTouch(const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (strcmp(entry->word, word)) continue;
touch(entry);
return;
}
@ -55,18 +59,43 @@ void tabTouch(const char *word) {
prepend(entry);
}
void tabReplace(const char *prev, const char *next) {
tabTouch(prev);
free(head->word);
head->word = strdup(next);
}
static struct Entry *match;
void tabRemove(const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (strcmp(entry->word, word)) continue;
remove(entry);
if (match == entry) match = entry->next;
free(entry->word);
free(entry);
return;
}
}
void tabReplace(const char *prev, const char *next) {
tabTouch(prev);
free(head->word);
head->word = strdup(next);
const char *tabNext(const char *prefix) {
size_t len = strlen(prefix);
struct Entry *start = (match ? match->next : head);
for (struct Entry *entry = start; entry; entry = entry->next) {
if (strncasecmp(entry->word, prefix, len)) continue;
match = entry;
return entry->word;
}
if (!match) return NULL;
match = NULL;
return tabNext(prefix);
}
void tabAccept(void) {
if (match) touch(match);
match = NULL;
}
void tabReject(void) {
match = NULL;
}