summary refs log tree commit diff
diff options
context:
space:
mode:
authorbx2023-01-22 08:51:12 +0000
committerbx2023-01-22 08:51:12 +0000
commit7bae4f2285f4d53e0b1e873ea84c504aab725a19 (patch)
tree5ffdc8f4281ef6de94553864d893a8cc7aac2464
parent91ad4c416345b32e90c02b3f25581a1c41e00053 (diff)
changed colors to be based on nicks, and to mirror gur colours used by weechat 2.8, also changed usernames to be aligned, max 12 chars
-rw-r--r--Makefile1
-rw-r--r--chat.h3
-rw-r--r--handle.c73
-rw-r--r--weechat_nick_colors.c204
4 files changed, 250 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index e8ef63a..27fa332 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@ OBJS += ui.o
 OBJS += url.o
 OBJS += window.o
 OBJS += xdg.o
+OBJS += weechat_nick_colors.o
 
 TESTS += edit.t
 
diff --git a/chat.h b/chat.h
index 15c757f..c473f65 100644
--- a/chat.h
+++ b/chat.h
@@ -465,3 +465,6 @@ int getopt_config(
 	int argc, char *const *argv,
 	const char *optstring, const struct option *longopts, int *longindex
 );
+
+uint32_t weechat_nick_colors(const char *nick);
+#define hash weechat_nick_colors
diff --git a/handle.c b/handle.c
index 74c3a28..bd3ef0d 100644
--- a/handle.c
+++ b/handle.c
@@ -366,7 +366,7 @@ static void handleJoin(struct Message *msg) {
 	if (!strcmp(msg->nick, self.nick)) {
 		if (!self.user || strcmp(self.user, msg->user)) {
 			set(&self.user, msg->user);
-			self.color = hash(msg->user);
+			self.color = hash(msg->nick);
 		}
 		if (!self.host || strcmp(self.host, msg->host)) {
 			set(&self.host, msg->host);
@@ -378,14 +378,14 @@ static void handleJoin(struct Message *msg) {
 			replies[ReplyJoin]--;
 		}
 	}
-	cacheInsert(true, id, msg->nick)->color = hash(msg->user);
+	cacheInsert(true, id, msg->nick)->color = hash(msg->nick);
 	if (msg->params[2] && !strcasecmp(msg->params[2], msg->nick)) {
 		msg->params[2] = NULL;
 	}
 	uiFormat(
 		id, filterCheck(Cold, id, msg), tagTime(msg),
 		"\3%02d%s\3\t%s%s%sarrives in \3%02d%s\3",
-		hash(msg->user), msg->nick,
+		hash(msg->nick), msg->nick,
 		(msg->params[2] ? "(" : ""),
 		(msg->params[2] ?: ""),
 		(msg->params[2] ? "\17) " : ""),
@@ -418,7 +418,7 @@ static void handlePart(struct Message *msg) {
 	uiFormat(
 		id, heat, tagTime(msg),
 		"\3%02d%s\3\tleaves \3%02d%s\3%s%s",
-		hash(msg->user), msg->nick, hash(msg->params[0]), msg->params[0],
+		hash(msg->nick), msg->nick, hash(msg->params[0]), msg->params[0],
 		(msg->params[1] ? ": " : ""), (msg->params[1] ?: "")
 	);
 	logFormat(
@@ -432,13 +432,13 @@ static void handleKick(struct Message *msg) {
 	require(msg, true, 2);
 	uint id = idFor(msg->params[0]);
 	bool kicked = !strcmp(msg->params[1], self.nick);
-	cacheInsert(true, id, msg->nick)->color = hash(msg->user);
+	cacheInsert(true, id, msg->nick)->color = hash(msg->nick);
 	urlScan(id, msg->nick, msg->params[2]);
 	uiFormat(
 		id, (kicked ? Hot : Cold), tagTime(msg),
 		"%s\3%02d%s\17\tkicks \3%02d%s\3 out of \3%02d%s\3%s%s",
 		(kicked ? "\26" : ""),
-		hash(msg->user), msg->nick,
+		hash(msg->nick), msg->nick,
 		cacheGet(id, msg->params[1])->color, msg->params[1],
 		hash(msg->params[0]), msg->params[0],
 		(msg->params[2] ? ": " : ""), (msg->params[2] ?: "")
@@ -466,7 +466,7 @@ static void handleNick(struct Message *msg) {
 		uiFormat(
 			id, filterCheck(Cold, id, msg), 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]
+			hash(msg->nick), msg->nick, hash(msg->nick), msg->params[0]
 		);
 		if (id == Network) continue;
 		logFormat(
@@ -484,7 +484,7 @@ static void handleSetname(struct Message *msg) {
 		uiFormat(
 			id, filterCheck(Cold, id, msg), tagTime(msg),
 			"\3%02d%s\3\tis now known as \3%02d%s\3 (%s\17)",
-			hash(msg->user), msg->nick, hash(msg->user), msg->nick,
+			hash(msg->nick), msg->nick, hash(msg->nick), msg->nick,
 			msg->params[0]
 		);
 	}
@@ -499,7 +499,7 @@ static void handleQuit(struct Message *msg) {
 		uiFormat(
 			id, heat, tagTime(msg),
 			"\3%02d%s\3\tleaves%s%s",
-			hash(msg->user), msg->nick,
+			hash(msg->nick), msg->nick,
 			(msg->params[0] ? ": " : ""), (msg->params[0] ?: "")
 		);
 		if (id == Network) continue;
@@ -519,14 +519,14 @@ static void handleInvite(struct Message *msg) {
 		uiFormat(
 			Network, filterCheck(Hot, Network, msg), tagTime(msg),
 			"\3%02d%s\3\tinvites you to \3%02d%s\3",
-			hash(msg->user), msg->nick, hash(msg->params[1]), msg->params[1]
+			hash(msg->nick), msg->nick, hash(msg->params[1]), msg->params[1]
 		);
 	} else {
 		uint id = idFor(msg->params[1]);
 		uiFormat(
 			id, Cold, tagTime(msg),
 			"\3%02d%s\3\tinvites %s to \3%02d%s\3",
-			hash(msg->user), msg->nick,
+			hash(msg->nick), msg->nick,
 			msg->params[0],
 			hash(msg->params[1]), msg->params[1]
 		);
@@ -570,7 +570,7 @@ static void handleReplyNames(struct Message *msg) {
 		char *prefixes = strsep(&name, "!");
 		char *nick = &prefixes[strspn(prefixes, network.prefixes)];
 		char *user = strsep(&name, "@");
-		enum Color color = (user ? hash(user) : Default);
+		enum Color color = (user ? hash(nick) : Default); /* NOTE(bx): changed this from user to nick, bc it was getting gur wrong hash and color for people using bouncers + bots */
 		uint bits = 0;
 		for (char *p = prefixes; p < nick; ++p) {
 			bits |= prefixBit(*p);
@@ -681,7 +681,7 @@ static void handleTopic(struct Message *msg) {
 		uiFormat(
 			id, Warm, tagTime(msg),
 			"\3%02d%s\3\tremoves the sign in \3%02d%s\3",
-			hash(msg->user), msg->nick, hash(msg->params[0]), msg->params[0]
+			hash(msg->nick), msg->nick, hash(msg->params[0]), msg->params[0]
 		);
 		logFormat(
 			id, tagTime(msg), "%s removes the sign in %s",
@@ -716,14 +716,14 @@ static void handleTopic(struct Message *msg) {
 	char *ptr = buf, *end = &buf[sizeof(buf)];
 	ptr = seprintf(
 		ptr, end, "\3%02d%s\3\ttakes down the sign in \3%02d%s\3: ",
-		hash(msg->user), msg->nick, hash(msg->params[0]), msg->params[0]
+		hash(msg->nick), msg->nick, hash(msg->params[0]), msg->params[0]
 	);
 	ptr = highlightMiddle(ptr, end, Brown, old, pre, osuf);
 	if (osuf != pre) uiWrite(id, Cold, tagTime(msg), buf);
 	ptr = buf;
 	ptr = seprintf(
 		ptr, end, "\3%02d%s\3\tplaces a new sign in \3%02d%s\3: ",
-		hash(msg->user), msg->nick, hash(msg->params[0]), msg->params[0]
+		hash(msg->nick), msg->nick, hash(msg->params[0]), msg->params[0]
 	);
 	ptr = highlightMiddle(ptr, end, Green, new, pre, nsuf);
 	uiWrite(id, Warm, tagTime(msg), buf);
@@ -733,7 +733,7 @@ plain:
 	uiFormat(
 		id, Warm, tagTime(msg),
 		"\3%02d%s\3\tplaces a new sign in \3%02d%s\3: %s",
-		hash(msg->user), msg->nick, hash(msg->params[0]), msg->params[0],
+		hash(msg->nick), msg->nick, hash(msg->params[0]), msg->params[0],
 		msg->params[1]
 	);
 log:
@@ -831,7 +831,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				Network, Warm, tagTime(msg),
 				"\3%02d%s\3\t%ssets \3%02d%s\3 %c%c%s%s",
-				hash(msg->user), msg->nick,
+				hash(msg->nick), msg->nick,
 				(set ? "" : "un"),
 				self.color, msg->params[0],
 				set["-+"], *ch, (name ? " " : ""), (name ?: "")
@@ -872,7 +872,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				id, Cold, tagTime(msg),
 				"\3%02d%s\3\t%s \3%02d%c%s\3 %s%s in \3%02d%s\3",
-				hash(msg->user), msg->nick, verb,
+				hash(msg->nick), msg->nick, verb,
 				cacheGet(id, nick)->color, prefix, nick,
 				mode, name, hash(msg->params[0]), msg->params[0]
 			);
@@ -892,7 +892,7 @@ static void handleMode(struct Message *msg) {
 				uiFormat(
 					id, Cold, tagTime(msg),
 					"\3%02d%s\3\t%s %c%c %s from \3%02d%s\3",
-					hash(msg->user), msg->nick, verb, set["-+"], *ch, mask,
+					hash(msg->nick), msg->nick, verb, set["-+"], *ch, mask,
 					hash(msg->params[0]), msg->params[0]
 				);
 				logFormat(
@@ -905,7 +905,7 @@ static void handleMode(struct Message *msg) {
 				uiFormat(
 					id, Cold, tagTime(msg),
 					"\3%02d%s\3\t%s %s %s the \3%02d%s\3 %s%s list",
-					hash(msg->user), msg->nick, verb, mask, to,
+					hash(msg->nick), msg->nick, verb, mask, to,
 					hash(msg->params[0]), msg->params[0], mode, name
 				);
 				logFormat(
@@ -923,7 +923,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				id, Cold, tagTime(msg),
 				"\3%02d%s\3\t%s \3%02d%s\3 %s%s %s",
-				hash(msg->user), msg->nick, verb,
+				hash(msg->nick), msg->nick, verb,
 				hash(msg->params[0]), msg->params[0], mode, name, param
 			);
 			logFormat(
@@ -940,7 +940,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				id, Cold, tagTime(msg),
 				"\3%02d%s\3\t%s \3%02d%s\3 %s%s %s",
-				hash(msg->user), msg->nick, verb,
+				hash(msg->nick), msg->nick, verb,
 				hash(msg->params[0]), msg->params[0], mode, name, param
 			);
 			logFormat(
@@ -951,7 +951,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				id, Cold, tagTime(msg),
 				"\3%02d%s\3\t%s \3%02d%s\3 %s%s",
-				hash(msg->user), msg->nick, verb,
+				hash(msg->nick), msg->nick, verb,
 				hash(msg->params[0]), msg->params[0], mode, name
 			);
 			logFormat(
@@ -964,7 +964,7 @@ static void handleMode(struct Message *msg) {
 			uiFormat(
 				id, Cold, tagTime(msg),
 				"\3%02d%s\3\t%s \3%02d%s\3 %s%s",
-				hash(msg->user), msg->nick, verb,
+				hash(msg->nick), msg->nick, verb,
 				hash(msg->params[0]), msg->params[0], mode, name
 			);
 			logFormat(
@@ -1278,7 +1278,7 @@ static void handlePrivmsg(struct Message *msg) {
 		id = Network;
 	} else if (query && !mine) {
 		id = idFor(msg->nick);
-		idColors[id] = hash(msg->user);
+		idColors[id] = hash(msg->nick);
 	} else {
 		id = idFor(msg->params[0]);
 	}
@@ -1290,10 +1290,13 @@ static void handlePrivmsg(struct Message *msg) {
 	heat = filterCheck(heat, id, msg);
 	if (heat > Warm && !mine && !query) highlight = true;
 	if (!notice && !mine && heat > Ice) {
-		cacheInsert(true, id, msg->nick)->color = hash(msg->user);
+		cacheInsert(true, id, msg->nick)->color = hash(msg->nick);
 	}
 	if (heat > Ice) urlScan(id, msg->nick, msg->params[1]);
 
+	static char last_nick[128] = "";
+	int reset_last_nick = 1;
+
 	char buf[1024];
 	char *ptr = buf, *end = &buf[sizeof(buf)];
 	if (statusmsg) {
@@ -1307,20 +1310,22 @@ static void handlePrivmsg(struct Message *msg) {
 		}
 		ptr = seprintf(
 			ptr, end, "\3%d-%s-\3%d\t",
-			hash(msg->user), msg->nick, LightGray
+			hash(msg->nick), msg->nick, LightGray
 		);
 	} else if (action) {
 		logFormat(id, tagTime(msg), "* %s %s", msg->nick, msg->params[1]);
 		ptr = seprintf(
-			ptr, end, "%s\35\3%d* %s\17\35\t",
-			(highlight ? "\26" : ""), hash(msg->user), msg->nick
+			ptr, end, "%s\35\3%d            * %s\17\35\t",
+			(highlight ? "\26" : ""), hash(msg->nick), msg->nick
 		);
 	} else {
 		logFormat(id, tagTime(msg), "<%s> %s", msg->nick, msg->params[1]);
 		ptr = seprintf(
-			ptr, end, "%s\3%d<%s>\17\t",
-			(highlight ? "\26" : ""), hash(msg->user), msg->nick
+			ptr, end, "%s\3%d %12.12s\17\t", /* NOTE(bx): i changed this cause i like things to line up */
+			(highlight ? "\26" : ""), hash(msg->nick),
+			(strncmp(msg->nick, last_nick, sizeof(last_nick) - 1) != 0) ? msg->nick : ""
 		);
+		reset_last_nick = 0;
 	}
 	if (notice) {
 		ptr = seprintf(ptr, end, "%s", msg->params[1]);
@@ -1328,6 +1333,12 @@ static void handlePrivmsg(struct Message *msg) {
 		ptr = colorMentions(ptr, end, id, msg->params[1]);
 	}
 	uiWrite(id, heat, tagTime(msg), buf);
+
+	if (reset_last_nick) {
+		strncpy(last_nick, "", sizeof(last_nick) - 1);
+	} else {
+		strncpy(last_nick, msg->nick, sizeof(last_nick) - 1);
+	}
 }
 
 static void handlePing(struct Message *msg) {
diff --git a/weechat_nick_colors.c b/weechat_nick_colors.c
new file mode 100644
index 0000000..c4011ad
--- /dev/null
+++ b/weechat_nick_colors.c
@@ -0,0 +1,204 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <curses.h>
+
+#include "chat.h"
+
+int utf8_char_int (const char *string);
+const char *utf8_next_char (const char *string);
+void gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64);
+int gui_nick_hash_color (const char *nickname);
+enum Color bx_weechat_nick_colors(const char *nick);
+
+int
+utf8_char_int (const char *string)
+{
+    const unsigned char *ptr_string;
+
+    if (!string)
+        return 0;
+
+    ptr_string = (unsigned char *)string;
+
+    /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */
+    if ((ptr_string[0] & 0xE0) == 0xC0)
+    {
+        if (!ptr_string[1])
+            return (int)(ptr_string[0] & 0x1F);
+        return ((int)(ptr_string[0] & 0x1F) << 6) +
+            ((int)(ptr_string[1] & 0x3F));
+    }
+    /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */
+    else if ((ptr_string[0] & 0xF0) == 0xE0)
+    {
+        if (!ptr_string[1])
+            return (int)(ptr_string[0] & 0x0F);
+        if (!ptr_string[2])
+            return (((int)(ptr_string[0] & 0x0F)) << 6) +
+                ((int)(ptr_string[1] & 0x3F));
+        return (((int)(ptr_string[0] & 0x0F)) << 12) +
+            (((int)(ptr_string[1] & 0x3F)) << 6) +
+            ((int)(ptr_string[2] & 0x3F));
+    }
+    /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */
+    else if ((ptr_string[0] & 0xF8) == 0xF0)
+    {
+        if (!ptr_string[1])
+            return (int)(ptr_string[0] & 0x07);
+        if (!ptr_string[2])
+            return (((int)(ptr_string[0] & 0x07)) << 6) +
+                ((int)(ptr_string[1] & 0x3F));
+        if (!ptr_string[3])
+            return (((int)(ptr_string[0] & 0x07)) << 12) +
+                (((int)(ptr_string[1] & 0x3F)) << 6) +
+                ((int)(ptr_string[2] & 0x3F));
+        return (((int)(ptr_string[0] & 0x07)) << 18) +
+            (((int)(ptr_string[1] & 0x3F)) << 12) +
+            (((int)(ptr_string[2] & 0x3F)) << 6) +
+            ((int)(ptr_string[3] & 0x3F));
+    }
+    /* UTF-8, 1 byte: 0vvvvvvv */
+    return (int)ptr_string[0];
+}
+
+const char *
+utf8_next_char (const char *string)
+{
+    if (!string)
+        return NULL;
+
+    /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */
+    if (((unsigned char)(string[0]) & 0xE0) == 0xC0)
+    {
+        if (!string[1])
+            return (char *)string + 1;
+        return (char *)string + 2;
+    }
+    /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */
+    else if (((unsigned char)(string[0]) & 0xF0) == 0xE0)
+    {
+        if (!string[1])
+            return (char *)string + 1;
+        if (!string[2])
+            return (char *)string + 2;
+        return (char *)string + 3;
+    }
+    /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */
+    else if (((unsigned char)(string[0]) & 0xF8) == 0xF0)
+    {
+        if (!string[1])
+            return (char *)string + 1;
+        if (!string[2])
+            return (char *)string + 2;
+        if (!string[3])
+            return (char *)string + 3;
+        return (char *)string + 4;
+    }
+    /* UTF-8, 1 byte: 0vvvvvvv */
+    return (char *)string + 1;
+}
+
+void
+gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64)
+{
+    while (nickname && nickname[0])
+    {
+        *color_64 ^= (*color_64 << 5) + (*color_64 >> 2) +
+            utf8_char_int (nickname);
+        nickname = utf8_next_char (nickname);
+    }
+}
+
+/* cyan, magenta, green, brown, lightblue,
+default, lightcyan, lightmagenta, lightgreen, blue */
+
+/*
+ * Hashes a nickname to find color.
+ *
+ * Returns a number which is the index of color in the nicks colors of option
+ * "weechat.color.chat_nick_colors".
+ */
+
+int
+gui_nick_hash_color (const char *nickname)
+{
+    const char *ptr_salt;
+    uint64_t color_64;
+
+    ptr_salt = "";
+
+    color_64 = 0;
+
+    switch (1)
+    {
+        default:
+            /* variant of djb2 hash */
+            color_64 = 5381;
+            gui_nick_hash_djb2_64 (ptr_salt, &color_64);
+            gui_nick_hash_djb2_64 (nickname, &color_64);
+            break;
+    }
+
+    return (color_64 % 10);
+}
+
+/*
+	cyan, magenta, green, brown, lightblue,
+	default, lightcyan, lightmagenta, lightgreen, blue
+*/
+
+/*
+struct t_gui_color gui_weechat_colors_bold[GUI_CURSES_NUM_WEECHAT_COLORS + 1] =
+{ { -1,                -1,                0,      "default"      },
+{ COLOR_BLACK,       COLOR_BLACK,       0,      "black"        },
+{ COLOR_BLACK,       COLOR_BLACK + 8,   A_BOLD, "darkgray"     },
+{ COLOR_RED,         COLOR_RED,         0,      "red"          },
+{ COLOR_RED,         COLOR_RED + 8,     A_BOLD, "lightred"     },
+{ COLOR_GREEN,       COLOR_GREEN,       0,      "green"        },
+{ COLOR_GREEN,       COLOR_GREEN + 8,   A_BOLD, "lightgreen"   },
+{ COLOR_YELLOW,      COLOR_YELLOW,      0,      "brown"        },
+{ COLOR_YELLOW,      COLOR_YELLOW + 8,  A_BOLD, "yellow"       },
+{ COLOR_BLUE,        COLOR_BLUE,        0,      "blue"         },
+{ COLOR_BLUE,        COLOR_BLUE + 8,    A_BOLD, "lightblue"    },
+{ COLOR_MAGENTA,     COLOR_MAGENTA,     0,      "magenta"      },
+{ COLOR_MAGENTA,     COLOR_MAGENTA + 8, A_BOLD, "lightmagenta" },
+{ COLOR_CYAN,        COLOR_CYAN,        0,      "cyan"         },
+{ COLOR_CYAN,        COLOR_CYAN + 8,    A_BOLD, "lightcyan"    },
+{ COLOR_WHITE,       COLOR_WHITE,       0,      "gray"         },
+{ COLOR_WHITE,       COLOR_WHITE + 8,   A_BOLD, "white"        },
+{ 0,                 0,                 0,      NULL           }
+};
+*/
+
+/*
+	[Default]    = -1,
+	[White]      = 8 + COLOR_WHITE,
+	[Black]      = 0 + COLOR_BLACK,
+	[Blue]       = 0 + COLOR_BLUE,
+	[Green]      = 0 + COLOR_GREEN,
+	[Red]        = 8 + COLOR_RED,
+	[Brown]      = 0 + COLOR_RED,
+	[Magenta]    = 0 + COLOR_MAGENTA,
+	[Orange]     = 0 + COLOR_YELLOW,
+	[Yellow]     = 8 + COLOR_YELLOW,
+	[LightGreen] = 8 + COLOR_GREEN,
+	[Cyan]       = 0 + COLOR_CYAN,
+	[LightCyan]  = 8 + COLOR_CYAN,
+	[LightBlue]  = 8 + COLOR_BLUE,
+	[Pink]       = 8 + COLOR_MAGENTA,
+	[Gray]       = 8 + COLOR_BLACK,
+	[LightGray]  = 0 + COLOR_WHITE,
+*/
+
+// enum Color bx_weechat_nick_colors(const char *nick) {
+uint32_t weechat_nick_colors(const char *nick) {
+	enum Color weechat_colors[] = {
+		Cyan, Magenta, Green, Orange, LightBlue,
+		Default, LightCyan, Pink, LightGreen, Blue,
+	};
+
+	int color = gui_nick_hash_color(nick);
+
+	return (uint32_t) weechat_colors[color];
+}