summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chat.h3
-rw-r--r--tab.c43
2 files changed, 39 insertions, 7 deletions
diff --git a/chat.h b/chat.h
index 838c51d..09f0d2c 100644
--- a/chat.h
+++ b/chat.h
@@ -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);
diff --git a/tab.c b/tab.c
index 56fe649..45670ad 100644
--- a/tab.c
+++ b/tab.c
@@ -40,12 +40,16 @@ static void remove(struct Entry *entry) {
if (head == entry) head = entry->next;
}
+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;
- if (head == entry) return;
- remove(entry);
- prepend(entry);
+ 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;
}