about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2022-05-29 18:09:52 -0400
committerJune McEnroe <june@causal.agency>2022-05-29 18:09:52 -0400
commit3475f03ec8c9ee26544c17b5f3d1cba7b1104f5e (patch)
tree51a7b2881e54369316856602f297827803a4ad53
parentDocument visibility of unknown replies (diff)
downloadcatgirl-3475f03ec8c9ee26544c17b5f3d1cba7b1104f5e.tar.gz
catgirl-3475f03ec8c9ee26544c17b5f3d1cba7b1104f5e.zip
Allow setting fallback nicks and highlight on any
As a side-effect, even with only one nick set you'll still be
highlighted by it even if your current nick is different.
-rw-r--r--catgirl.17
-rw-r--r--chat.c17
-rw-r--r--chat.h7
-rw-r--r--handle.c25
4 files changed, 39 insertions, 17 deletions
diff --git a/catgirl.1 b/catgirl.1
index 9e28bda..c5cb101 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -312,12 +312,17 @@ Log chat events to files in paths
 Set the user
 .Ar mode .
 .
-.It Fl n Ar nick | Cm nick No = Ar nick
+.It Fl n Ar nick Oo Ar ... Oc | Cm nick No = Ar nick Oo Ar ... Oc
 Set nickname to
 .Ar nick .
 The default nickname is
 the value of the environment variable
 .Ev USER .
+Additional space-separated nicks
+will be tried in order
+if the first is not available,
+and all nicks
+are treated as highlight words.
 .
 .It Fl o
 Print the server certificate chain
diff --git a/chat.c b/chat.c
index b74fdc0..2d35771 100644
--- a/chat.c
+++ b/chat.c
@@ -237,7 +237,6 @@ int main(int argc, char *argv[]) {
 	bool log = false;
 	bool sasl = false;
 	char *pass = NULL;
-	const char *nick = NULL;
 	const char *user = NULL;
 	const char *real = NULL;
 
@@ -306,7 +305,11 @@ int main(int argc, char *argv[]) {
 			break; case 'k': priv = optarg;
 			break; case 'l': log = true; logOpen();
 			break; case 'm': self.mode = optarg;
-			break; case 'n': nick = optarg;
+			break; case 'n': {
+				for (uint i = 0; i < ARRAY_LEN(self.nicks); ++i) {
+					self.nicks[i] = strsep(&optarg, " ");
+				}
+			}
 			break; case 'o': printCert = true;
 			break; case 'p': port = optarg;
 			break; case 'q': windowThreshold = Warm;
@@ -333,10 +336,10 @@ int main(int argc, char *argv[]) {
 		return EX_OK;
 	}
 
-	if (!nick) nick = getenv("USER");
-	if (!nick) errx(EX_CONFIG, "USER unset");
-	if (!user) user = nick;
-	if (!real) real = nick;
+	if (!self.nicks[0]) self.nicks[0] = getenv("USER");
+	if (!self.nicks[0]) errx(EX_CONFIG, "USER unset");
+	if (!user) user = self.nicks[0];
+	if (!real) real = self.nicks[0];
 
 	if (self.kiosk) {
 		char *hash;
@@ -404,7 +407,7 @@ int main(int argc, char *argv[]) {
 	}
 	if (sasl) ircFormat("CAP REQ :sasl\r\n");
 	ircFormat("CAP LS\r\n");
-	ircFormat("NICK :%s\r\n", nick);
+	ircFormat("NICK %s\r\n", self.nicks[0]);
 	ircFormat("USER %s 0 * :%s\r\n", user, real);
 
 	// Avoid disabling VINTR until main loop.
diff --git a/chat.h b/chat.h
index 1c46f00..b252210 100644
--- a/chat.h
+++ b/chat.h
@@ -193,10 +193,11 @@ extern struct Self {
 	bool restricted;
 	size_t pos;
 	enum Cap caps;
-	char *plainUser;
+	const char *plainUser;
 	char *plainPass;
-	char *mode;
-	char *join;
+	const char *nicks[8];
+	const char *mode;
+	const char *join;
 	char *nick;
 	char *user;
 	char *host;
diff --git a/handle.c b/handle.c
index f51323d..e4fe0ab 100644
--- a/handle.c
+++ b/handle.c
@@ -148,7 +148,12 @@ static void handleReplyGeneric(struct Message *msg) {
 static void handleErrorNicknameInUse(struct Message *msg) {
 	require(msg, false, 2);
 	if (!strcmp(self.nick, "*")) {
-		ircFormat("NICK :%s_\r\n", msg->params[1]);
+		static uint i = 1;
+		if (i < ARRAY_LEN(self.nicks) && self.nicks[i]) {
+			ircFormat("NICK %s\r\n", self.nicks[i++]);
+		} else {
+			ircFormat("NICK %s_\r\n", msg->params[1]);
+		}
 	} else {
 		handleErrorGeneric(msg);
 	}
@@ -1207,11 +1212,11 @@ static bool isAction(struct Message *msg) {
 	return true;
 }
 
-static bool isMention(const struct Message *msg) {
-	size_t len = strlen(self.nick);
-	const char *match = msg->params[1];
-	while (NULL != (match = strstr(match, self.nick))) {
-		char a = (match > msg->params[1] ? match[-1] : ' ');
+static bool matchWord(const char *str, const char *word) {
+	size_t len = strlen(word);
+	const char *match = str;
+	while (NULL != (match = strstr(match, word))) {
+		char a = (match > str ? match[-1] : ' ');
 		char b = (match[len] ?: ' ');
 		if ((isspace(a) || ispunct(a)) && (isspace(b) || ispunct(b))) {
 			return true;
@@ -1221,6 +1226,14 @@ static bool isMention(const struct Message *msg) {
 	return false;
 }
 
+static bool isMention(const struct Message *msg) {
+	if (matchWord(msg->params[1], self.nick)) return true;
+	for (uint i = 0; i < ARRAY_LEN(self.nicks) && self.nicks[i]; ++i) {
+		if (matchWord(msg->params[1], self.nicks[i])) return true;
+	}
+	return false;
+}
+
 static void colorMentions(char *buf, size_t cap, uint id, struct Message *msg) {
 	*buf = '\0';