about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--chat.h2
-rw-r--r--complete.c21
-rw-r--r--handle.c17
3 files changed, 40 insertions, 0 deletions
diff --git a/chat.h b/chat.h
index 6eeed60..413cee4 100644
--- a/chat.h
+++ b/chat.h
@@ -151,8 +151,10 @@ char *editTail(void);
 const char *complete(size_t id, const char *prefix);
 void completeAccept(void);
 void completeReject(void);
+size_t completeID(const char *str);
 void completeAdd(size_t id, const char *str, enum Color color);
 void completeTouch(size_t id, const char *str, enum Color color);
+void completeReplace(size_t id, const char *old, const char *new);
 void completeRemove(size_t id, const char *str);
 void completeClear(size_t id);
 
diff --git a/complete.c b/complete.c
index 437bb7d..c194536 100644
--- a/complete.c
+++ b/complete.c
@@ -110,6 +110,27 @@ void completeReject(void) {
 	match = NULL;
 }
 
+size_t completeID(const char *str) {
+	for (match = (match ? match->next : head); match; match = match->next) {
+		if (match->id && !strcmp(match->str, str)) return match->id;
+	}
+	return None;
+}
+
+void completeReplace(size_t id, const char *old, const char *new) {
+	struct Node *next = NULL;
+	for (struct Node *node = head; node; node = node->next) {
+		next = node->next;
+		if (id && node->id != id) continue;
+		if (strcmp(node->str, old)) continue;
+		if (match == node) match = NULL;
+		free(node->str);
+		node->str = strdup(new);
+		if (!node->str) err(EX_OSERR, "strdup");
+		prepend(detach(node));
+	}
+}
+
 void completeRemove(size_t id, const char *str) {
 	struct Node *next = NULL;
 	for (struct Node *node = head; node; node = next) {
diff --git a/handle.c b/handle.c
index b73d200..fe64f33 100644
--- a/handle.c
+++ b/handle.c
@@ -261,6 +261,22 @@ static void handleTopic(struct Message *msg) {
 	}
 }
 
+static void handleNick(struct Message *msg) {
+	require(msg, true, 1);
+	if (self.nick && !strcmp(msg->nick, self.nick)) {
+		set(&self.nick, msg->params[0]);
+	}
+	size_t id;
+	completeReplace(None, msg->nick, msg->params[0]);
+	while (None != (id = completeID(msg->params[0]))) {
+		uiFormat(
+			id, Cold, tagTime(msg),
+			"\3%02d%s\3\tis now known as \3%02d%s\3",
+			hash(msg->user), msg->nick, hash(msg->user), msg->params[0]
+		);
+	}
+}
+
 static bool isAction(struct Message *msg) {
 	if (strncmp(msg->params[1], "\1ACTION ", 8)) return false;
 	msg->params[1] += 8;
@@ -354,6 +370,7 @@ static const struct Handler {
 	{ "CAP", handleCap },
 	{ "ERROR", handleError },
 	{ "JOIN", handleJoin },
+	{ "NICK", handleNick },
 	{ "NOTICE", handlePrivmsg },
 	{ "PART", handlePart },
 	{ "PING", handlePing },