diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | chat.h | 3 | ||||
| -rw-r--r-- | handle.c | 73 | ||||
| -rw-r--r-- | weechat_nick_colors.c | 204 | 
4 files changed, 250 insertions, 31 deletions
| @@ -27,6 +27,7 @@ OBJS += ui.o  OBJS += url.o  OBJS += window.o  OBJS += xdg.o +OBJS += weechat_nick_colors.o  TESTS += edit.t @@ -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 @@ -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]; +} | 
