From 5d2b5cd51e64c3e49a536ef431c97dc1d0b78dfd Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Tue, 7 Aug 2018 14:58:32 -0400 Subject: Populate tab-complete list --- Makefile | 2 +- README | 1 + chat.h | 4 ++++ handle.c | 8 ++++++++ tab.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tab.c diff --git a/Makefile b/Makefile index 76e130b..38c14bf 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS += -Wall -Wextra -Wpedantic CFLAGS += -I/usr/local/include LDFLAGS += -L/usr/local/lib LDLIBS = -lcursesw -ltls -OBJS = chat.o handle.o input.o irc.o pls.o ui.o +OBJS = chat.o handle.o input.o irc.o pls.o tab.o ui.o all: tags chat diff --git a/README b/README index 0d39bf2..59079c1 100644 --- a/README +++ b/README @@ -8,4 +8,5 @@ This software targets FreeBSD and requires LibreSSL. irc.c TLS client connection input.c Input command handling handle.c Incoming command handling + tab.c Tab-complete pls.c Functions which should not have to be written diff --git a/chat.h b/chat.h index 47a7e1e..5d9dc1c 100644 --- a/chat.h +++ b/chat.h @@ -60,5 +60,9 @@ void uiFmt(const wchar_t *format, ...); void handle(char *line); void input(wchar_t *line); +void tabTouch(const char *word); +void tabRemove(const char *word); +void tabReplace(const char *prev, const char *next); + wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim); int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap); diff --git a/handle.c b/handle.c index 8073758..015960d 100644 --- a/handle.c +++ b/handle.c @@ -81,6 +81,7 @@ static void handleJoin(char *prefix, char *params) { free(chat.user); chat.user = strdup(user); } + tabTouch(nick); uiFmt( "\3%d%s\3 arrives in \3%d%s\3", color(user), nick, color(chan), chan @@ -91,6 +92,7 @@ static void handlePart(char *prefix, char *params) { char *nick = prift(&prefix); char *user = prift(&prefix); char *chan = shift(¶ms); + tabRemove(nick); if (params) { char *mesg = shift(¶ms); uiFmt( @@ -108,6 +110,7 @@ static void handlePart(char *prefix, char *params) { static void handleQuit(char *prefix, char *params) { char *nick = prift(&prefix); char *user = prift(&prefix); + tabRemove(nick); if (params) { char *mesg = shift(¶ms); char *quot = (mesg[0] == '"') ? "" : "\""; @@ -126,6 +129,7 @@ static void handleKick(char *prefix, char *params) { char *chan = shift(¶ms); char *kick = shift(¶ms); char *mesg = shift(¶ms); + tabRemove(nick); uiFmt( "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", color(user), nick, color(kick), kick, color(chan), chan, mesg @@ -176,6 +180,7 @@ static void handle352(char *prefix, char *params) { shift(¶ms); shift(¶ms); char *nick = shift(¶ms); + tabTouch(nick); size_t cap = sizeof(who.buf) - who.len; int len = snprintf( &who.buf[who.len], cap, @@ -204,6 +209,7 @@ static void handleNick(char *prefix, char *params) { free(chat.nick); chat.nick = strdup(next); } + tabReplace(prev, next); uiFmt( "\3%d%s\3 is now known as \3%d%s\3", color(user), prev, color(user), next @@ -215,6 +221,7 @@ static void handlePrivmsg(char *prefix, char *params) { char *user = prift(&prefix); shift(¶ms); char *mesg = shift(¶ms); + tabTouch(nick); if (mesg[0] == '\1') { strsep(&mesg, " "); char *action = strsep(&mesg, "\1"); @@ -230,6 +237,7 @@ static void handleNotice(char *prefix, char *params) { char *chan = shift(¶ms); char *mesg = shift(¶ms); if (strcmp(chat.chan, chan)) return; + tabTouch(nick); uiFmt("-\3%d%s\3- %s", color(user), nick, mesg); } diff --git a/tab.c b/tab.c new file mode 100644 index 0000000..56fe649 --- /dev/null +++ b/tab.c @@ -0,0 +1,72 @@ +/* Copyright (C) 2018 Curtis McEnroe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include "chat.h" + +static struct Entry { + char *word; + struct Entry *prev; + struct Entry *next; +} *head; + +static void prepend(struct Entry *entry) { + entry->prev = NULL; + entry->next = head; + if (head) head->prev = entry; + head = entry; +} + +static void remove(struct Entry *entry) { + if (entry->prev) entry->prev->next = entry->next; + if (entry->next) entry->next->prev = entry->prev; + 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; + if (head == entry) return; + remove(entry); + prepend(entry); + return; + } + + struct Entry *entry = malloc(sizeof(*entry)); + if (!entry) err(EX_OSERR, "malloc"); + entry->word = strdup(word); + prepend(entry); +} + +void tabRemove(const char *word) { + for (struct Entry *entry = head; entry; entry = entry->next) { + if (strcmp(entry->word, word)) continue; + remove(entry); + free(entry->word); + free(entry); + return; + } +} + +void tabReplace(const char *prev, const char *next) { + tabTouch(prev); + free(head->word); + head->word = strdup(next); +} -- cgit 1.4.1-2-gfad0