diff options
| author | Curtis McEnroe | 2018-08-07 22:40:05 -0400 | 
|---|---|---|
| committer | Curtis McEnroe | 2018-08-07 22:40:05 -0400 | 
| commit | 43eee8da713a7c7c3788238a6a5f301ae4672a79 (patch) | |
| tree | dbea290ee50c63340b63d2ab8af8a5cea714cb2d | |
| parent | ee49c3665523f89262d39bccf50e2c1f5b9c2e91 (diff) | |
Implement cycling tab complete
Not properly hooked up to the UI yet.
| -rw-r--r-- | chat.h | 3 | ||||
| -rw-r--r-- | tab.c | 43 | 
2 files changed, 39 insertions, 7 deletions
| @@ -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); @@ -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;  } | 
