From dc132b4350d207d147bb79d997c3f8b511c4ac30 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Fri, 7 Jul 2023 14:40:44 -0400 Subject: Work-in-progress showing prefixes --- catgirl.1 | 13 +++++- chat.c | 2 + chat.h | 1 + handle.c | 144 +++++++++++++++++++++++++++++++++++++------------------------- input.c | 23 +++++++--- 5 files changed, 116 insertions(+), 67 deletions(-) diff --git a/catgirl.1 b/catgirl.1 index 32eb365..acd7e10 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -1,4 +1,4 @@ -.Dd May 29, 2022 +.Dd February 5, 2023 .Dt CATGIRL 1 .Os . @@ -8,7 +8,7 @@ . .Sh SYNOPSIS .Nm -.Op Fl KRelqv +.Op Fl KPRelqv .Op Fl C Ar copy .Op Fl H Ar hash .Op Fl I Ar highlight @@ -188,6 +188,15 @@ The default is the first available of .Xr open 1 , .Xr xdg-open 1 . . +.It Fl P | Cm prefix +Show nick prefixes corresponding to modes. +The standard prefixes are +.Sy @ +for operator and +.Sy + +for voice. +Other prefixes are server software specific. +. .It Fl R | Cm restrict Disable the .Ic /copy , diff --git a/chat.c b/chat.c index 8c425d4..bb05d7d 100644 --- a/chat.c +++ b/chat.c @@ -248,6 +248,7 @@ int main(int argc, char *argv[]) { { .val = 'K', .name = "kiosk", no_argument }, { .val = 'N', .name = "notify", required_argument }, { .val = 'O', .name = "open", required_argument }, + { .val = 'P', .name = "prefix", no_argument }, { .val = 'R', .name = "restrict", no_argument }, { .val = 'S', .name = "bind", required_argument }, { .val = 'T', .name = "timestamp", optional_argument }, @@ -289,6 +290,7 @@ int main(int argc, char *argv[]) { break; case 'K': self.kiosk = true; break; case 'N': utilPush(&uiNotifyUtil, optarg); break; case 'O': utilPush(&urlOpenUtil, optarg); + break; case 'P': self.showPrefix = true; break; case 'R': self.restricted = true; break; case 'S': bind = optarg; break; case 'T': { diff --git a/chat.h b/chat.h index 6753fcb..d270831 100644 --- a/chat.h +++ b/chat.h @@ -204,6 +204,7 @@ extern struct Self { bool debug; bool kiosk; bool restricted; + bool showPrefix; size_t pos; enum Cap caps; const char *plainUser; diff --git a/handle.c b/handle.c index 5a2cf7c..76999f6 100644 --- a/handle.c +++ b/handle.c @@ -406,19 +406,26 @@ static void handleChghost(struct Message *msg) { } } +static const char *prefix(uint id, const char *nick) { + if (!self.showPrefix) return ""; + uint *bits = completeBits(id, nick); + if (!bits) return ""; + for (uint i = 0; network.prefixes[i]; ++i) { + if (*bits & (1 << i)) return &network.prefixes[i]; + } + return ""; +} + static void handlePart(struct Message *msg) { require(msg, true, 1); uint id = idFor(msg->params[0]); - if (!strcmp(msg->nick, self.nick)) { - completeRemove(id, NULL); - } - completeRemove(id, msg->nick); enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); 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], + "\3%02d%s%s\3\tleaves \3%02d%s\3%s%s", + hash(msg->user), prefix(id, msg->nick), msg->nick, + hash(msg->params[0]), msg->params[0], (msg->params[1] ? ": " : ""), (msg->params[1] ?: "") ); logFormat( @@ -426,6 +433,11 @@ static void handlePart(struct Message *msg) { msg->nick, msg->params[0], (msg->params[1] ? ": " : ""), (msg->params[1] ?: "") ); + if (!strcmp(msg->nick, self.nick)) { + completeRemove(id, NULL); + inputUpdate(); + } + completeRemove(id, msg->nick); } static void handleKick(struct Message *msg) { @@ -436,10 +448,11 @@ static void handleKick(struct Message *msg) { 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", + "%s\3%02d%s%s\17\tkicks \3%02d%s%s\3 out of \3%02d%s\3%s%s", (kicked ? "\26" : ""), - hash(msg->user), msg->nick, - completeColor(id, msg->params[1]), msg->params[1], + hash(msg->user), prefix(id, msg->nick), msg->nick, + completeColor(id, msg->params[1]), + prefix(id, msg->params[1]), msg->params[1], hash(msg->params[0]), msg->params[0], (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); @@ -449,15 +462,14 @@ static void handleKick(struct Message *msg) { (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); completeRemove(id, msg->params[1]); - if (kicked) completeRemove(id, NULL); + if (kicked) { + completeRemove(id, NULL); + inputUpdate(); + } } static void handleNick(struct Message *msg) { require(msg, true, 1); - if (!strcmp(msg->nick, self.nick)) { - set(&self.nick, msg->params[0]); - inputUpdate(); - } struct Cursor curs = {0}; for (uint id; (id = completeEachID(&curs, msg->nick));) { if (!strcmp(idNames[id], msg->nick)) { @@ -465,8 +477,9 @@ 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] + "\3%02d%s%s\3\tis now known as \3%02d%s%s\3", + hash(msg->user), prefix(id, msg->nick), msg->nick, + hash(msg->user), prefix(id, msg->nick), msg->params[0] ); if (id == Network) continue; logFormat( @@ -475,6 +488,10 @@ static void handleNick(struct Message *msg) { ); } completeReplace(msg->nick, msg->params[0]); + if (!strcmp(msg->nick, self.nick)) { + set(&self.nick, msg->params[0]); + inputUpdate(); + } } static void handleSetname(struct Message *msg) { @@ -483,8 +500,9 @@ static void handleSetname(struct Message *msg) { for (uint id; (id = completeEachID(&curs, msg->nick));) { 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, + "\3%02d%s%s\3\tis now known as \3%02d%s%s\3 (%s\17)", + hash(msg->user), prefix(id, msg->nick), msg->nick, + hash(msg->user), prefix(id, msg->nick), msg->nick, msg->params[0] ); } @@ -498,8 +516,8 @@ static void handleQuit(struct Message *msg) { if (heat > Ice) urlScan(id, msg->nick, msg->params[0]); uiFormat( id, heat, tagTime(msg), - "\3%02d%s\3\tleaves%s%s", - hash(msg->user), msg->nick, + "\3%02d%s%s\3\tleaves%s%s", + hash(msg->user), prefix(id, msg->nick), msg->nick, (msg->params[0] ? ": " : ""), (msg->params[0] ?: "") ); if (id == Network) continue; @@ -525,8 +543,8 @@ static void handleInvite(struct Message *msg) { 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, + "\3%02d%s%s\3\tinvites %s to \3%02d%s\3", + hash(msg->user), prefix(id, msg->nick), msg->nick, msg->params[0], hash(msg->params[1]), msg->params[1] ); @@ -577,6 +595,7 @@ static void handleReplyNames(struct Message *msg) { } completePush(id, nick, color); *completeBits(id, nick) = bits; + if (!strcmp(nick, self.nick)) inputUpdate(); if (!replies[ReplyNames] && !replies[ReplyNamesAuto]) continue; ptr = seprintf( ptr, end, "%s\3%02d%s\3", (ptr > buf ? ", " : ""), color, prefixes @@ -679,8 +698,9 @@ static void handleTopic(struct Message *msg) { topicComplete(id, NULL); 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] + "\3%02d%s%s\3\tremoves the sign in \3%02d%s\3", + hash(msg->user), prefix(id, msg->nick), msg->nick, + hash(msg->params[0]), msg->params[0] ); logFormat( id, tagTime(msg), "%s removes the sign in %s", @@ -714,15 +734,17 @@ static void handleTopic(struct Message *msg) { char buf[1024]; 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] + ptr, end, "\3%02d%s%s\3\ttakes down the sign in \3%02d%s\3: ", + hash(msg->user), prefix(id, 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] + ptr, end, "\3%02d%s%s\3\tplaces a new sign in \3%02d%s\3: ", + hash(msg->user), prefix(id, 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); @@ -731,8 +753,9 @@ static void handleTopic(struct Message *msg) { 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], + "\3%02d%s%s\3\tplaces a new sign in \3%02d%s\3: %s", + hash(msg->user), prefix(id, msg->nick), msg->nick, + hash(msg->params[0]), msg->params[0], msg->params[1] ); log: @@ -860,26 +883,27 @@ static void handleMode(struct Message *msg) { errx(EX_PROTOCOL, "MODE missing %s parameter", mode); } char *nick = msg->params[i++]; - char prefix = network.prefixes[ + char p = network.prefixes[ strchr(network.prefixModes, *ch) - network.prefixModes ]; completePush(id, nick, Default); - if (set) { - *completeBits(id, nick) |= prefixBit(prefix); - } else { - *completeBits(id, nick) &= ~prefixBit(prefix); - } 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, - completeColor(id, nick), prefix, nick, + "\3%02d%s%s\3\t%s \3%02d%c%s\3 %s%s in \3%02d%s\3", + hash(msg->user), prefix(id, msg->nick), msg->nick, verb, + completeColor(id, nick), p, nick, mode, name, hash(msg->params[0]), msg->params[0] ); logFormat( id, tagTime(msg), "%s %s %c%s %s%s in %s", - msg->nick, verb, prefix, nick, mode, name, msg->params[0] + msg->nick, verb, p, nick, mode, name, msg->params[0] ); + if (set) { + *completeBits(id, nick) |= prefixBit(p); + } else { + *completeBits(id, nick) &= ~prefixBit(p); + } + if (!strcmp(nick, self.nick)) inputUpdate(); } if (strchr(network.listModes, *ch)) { @@ -891,8 +915,9 @@ static void handleMode(struct Message *msg) { verb = (set ? "bans" : "unbans"); 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, + "\3%02d%s%s\3\t%s %c%c %s from \3%02d%s\3", + hash(msg->user), prefix(id, msg->nick), msg->nick, + verb, set["-+"], *ch, mask, hash(msg->params[0]), msg->params[0] ); logFormat( @@ -904,8 +929,9 @@ static void handleMode(struct Message *msg) { const char *to = (set ? "to" : "from"); 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, + "\3%02d%s%s\3\t%s %s %s the \3%02d%s\3 %s%s list", + hash(msg->user), prefix(id, msg->nick), msg->nick, + verb, mask, to, hash(msg->params[0]), msg->params[0], mode, name ); logFormat( @@ -922,8 +948,8 @@ static void handleMode(struct Message *msg) { char *param = msg->params[i++]; uiFormat( id, Cold, tagTime(msg), - "\3%02d%s\3\t%s \3%02d%s\3 %s%s %s", - hash(msg->user), msg->nick, verb, + "\3%02d%s%s\3\t%s \3%02d%s\3 %s%s %s", + hash(msg->user), prefix(id, msg->nick), msg->nick, verb, hash(msg->params[0]), msg->params[0], mode, name, param ); logFormat( @@ -939,8 +965,8 @@ static void handleMode(struct Message *msg) { char *param = msg->params[i++]; uiFormat( id, Cold, tagTime(msg), - "\3%02d%s\3\t%s \3%02d%s\3 %s%s %s", - hash(msg->user), msg->nick, verb, + "\3%02d%s%s\3\t%s \3%02d%s\3 %s%s %s", + hash(msg->user), prefix(id, msg->nick), msg->nick, verb, hash(msg->params[0]), msg->params[0], mode, name, param ); logFormat( @@ -950,8 +976,8 @@ static void handleMode(struct Message *msg) { } else if (strchr(network.setParamModes, *ch)) { uiFormat( id, Cold, tagTime(msg), - "\3%02d%s\3\t%s \3%02d%s\3 %s%s", - hash(msg->user), msg->nick, verb, + "\3%02d%s%s\3\t%s \3%02d%s\3 %s%s", + hash(msg->user), prefix(id, msg->nick), msg->nick, verb, hash(msg->params[0]), msg->params[0], mode, name ); logFormat( @@ -963,8 +989,8 @@ static void handleMode(struct Message *msg) { if (strchr(network.channelModes, *ch)) { uiFormat( id, Cold, tagTime(msg), - "\3%02d%s\3\t%s \3%02d%s\3 %s%s", - hash(msg->user), msg->nick, verb, + "\3%02d%s%s\3\t%s \3%02d%s\3 %s%s", + hash(msg->user), prefix(id, msg->nick), msg->nick, verb, hash(msg->params[0]), msg->params[0], mode, name ); logFormat( @@ -1306,20 +1332,22 @@ static void handlePrivmsg(struct Message *msg) { logFormat(id, tagTime(msg), "-%s- %s", msg->nick, msg->params[1]); } ptr = seprintf( - ptr, end, "\3%d-%s-\3%d\t", - hash(msg->user), msg->nick, LightGray + ptr, end, "\3%d-%s%s-\3%d\t", + hash(msg->user), prefix(id, 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%s\17\35\t", + (highlight ? "\26" : ""), + hash(msg->user), prefix(id, 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<%s%s>\17\t", + (highlight ? "\26" : ""), + hash(msg->user), prefix(id, msg->nick), msg->nick ); } if (notice) { diff --git a/input.c b/input.c index 6b33b93..b4f5b5e 100644 --- a/input.c +++ b/input.c @@ -174,37 +174,45 @@ void inputUpdate(void) { const char *ptr = editString(&edits[id], &buf, &cap, &pos); if (!ptr) err(EX_OSERR, "editString"); - const char *prefix = ""; + const char *head = ""; + char prefix[2] = ""; const char *prompt = self.nick; - const char *suffix = ""; + const char *tail = ""; const char *skip = buf; struct Style stylePrompt = { .fg = self.color, .bg = Default }; struct Style styleInput = StyleDefault; + if (self.showPrefix) { + uint *bits = completeBits(id, self.nick); + if (bits) prefix[0] = bitPrefix(*bits); + } size_t split = commandWillSplit(id, buf); const char *privmsg = commandIsPrivmsg(id, buf); const char *notice = commandIsNotice(id, buf); const char *action = commandIsAction(id, buf); if (privmsg) { - prefix = "<"; suffix = "> "; + head = "<"; tail = "> "; skip = privmsg; } else if (notice) { - prefix = "-"; suffix = "- "; + head = "-"; tail = "- "; styleInput.fg = LightGray; skip = notice; } else if (action) { - prefix = "* "; suffix = " "; + head = "* "; tail = " "; stylePrompt.attr |= Italic; styleInput.attr |= Italic; skip = action; } else if (id == Debug && buf[0] != '/') { + prefix[0] = '\0'; prompt = "<< "; stylePrompt.fg = Gray; } else { + prefix[0] = '\0'; prompt = ""; } if (skip > &buf[pos]) { - prefix = prompt = suffix = ""; + prefix[0] = '\0'; + head = prompt = tail = ""; skip = buf; } @@ -215,9 +223,10 @@ void inputUpdate(void) { wmove(uiInput, 0, windowTime.width); } wattr_set(uiInput, uiAttr(stylePrompt), uiPair(stylePrompt), NULL); + waddstr(uiInput, head); waddstr(uiInput, prefix); waddstr(uiInput, prompt); - waddstr(uiInput, suffix); + waddstr(uiInput, tail); getyx(uiInput, y, x); int posx; -- cgit 1.4.1