From 7bae4f2285f4d53e0b1e873ea84c504aab725a19 Mon Sep 17 00:00:00 2001 From: bx Date: Sun, 22 Jan 2023 08:51:12 +0000 Subject: [PATCH] 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 --- Makefile | 1 + chat.h | 3 + handle.c | 73 ++++++++------- weechat_nick_colors.c | 204 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 31 deletions(-) create mode 100644 weechat_nick_colors.c 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 +#include +#include + +#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]; +}