[PATCH] Add -V/visibility option for default heat

[PATCH] Add -V/visibility option for default heat

From: Klemens Nanni
This patch applies to HEAD both right now as well as applying all the
other patches sent so far.

`-L/[log]level' could be an alternative to the option chosen below,
but `loglevel' somewhat implies that logfiles are effected (not true)
and `level' does not seem specific enough.

`catgirl -R -h irc.hackint.eu -s ./save -V warm' now does exactly what
I want without messing up visiblity for special windows that I've tweaked
with `M--' and `M-+' :-)

-- >8 --

This enables users to silence the regular noise (JOINs, QUITs, server
messages, etc.) or get everything from the start with a single global
default.

`-s/save' still wins over this default, i.e. each window's individual
threshold is loaded and saved over the default so that adjusting windows
persists across reconnects.

`-V/visibility's argument is handled case insensitively for convenience:
`-Vwarm' is clear enough and shouldn't produce an error.

NB: Combining catgirl's internal representation (`enum Heat') with one
of the remains in the getopt(3) option character space (`-V') standing
for visibility seems... a bit off, but could be changed later if need
be.
---
 catgirl.1 | 16 ++++++++++++++++
 chat.c    | 10 +++++++++-
 chat.h    |  3 ++-
 ui.c      |  4 ++--
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/catgirl.1 b/catgirl.1
index 7e39408..ba78b28 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -16,6 +16,7 @@
 .Op Fl O Ar open
 .Op Fl S Ar bind
 .Op Fl T Ns Op Ar timestamp
+.Op Fl T Ar visibility
 .Op Fl a Ar plain
 .Op Fl c Ar cert
 .Op Fl h Ar host
@@ -344,6 +345,21 @@ Set username to
 .Ar user .
 The default username is the same as the nickname.
 .
+.It Fl V Ar heat | Cm visibility No = Ar heat
+Set the default message visibility threshold for new windows:
+.Pp
+.Bl -tag -width Warm -compact -offset indent
+.It Ar Ice
+Show all events and messages (including ignored ones).
+.It Ar Cold
+(default)
+Show general events and non-highlighted messages.
+.It Ar Warm
+Hide general events, show messages.
+.It Ar Hot
+Show only highlighted messages.
+.El
+.
 .It Fl v | Cm debug
 Log raw IRC messages to the
 .Sy <debug>
diff --git a/chat.c b/chat.c
index 9934fc3..ec60ace 100644
--- a/chat.c
+++ b/chat.c
@@ -84,7 +84,7 @@ enum Color idColors[IDCap] = {
 uint idNext = Network + 1;
 
 struct Network network = { .userLen = 9, .hostLen = 63 };
-struct Self self = { .color = Default };
+struct Self self = { .color = Default, .heat = Cold };
 
 static const char *save;
 static void exitSave(void) {
@@ -166,6 +166,7 @@ int main(int argc, char *argv[]) {
 		{ .val = 'R', .name = "restrict", no_argument },
 		{ .val = 'S', .name = "bind", required_argument },
 		{ .val = 'T', .name = "timestamp", optional_argument },
+		{ .val = 'V', .name = "visibility", required_argument },
 		{ .val = 'a', .name = "sasl-plain", required_argument },
 		{ .val = 'c', .name = "cert", required_argument },
 		{ .val = 'e', .name = "sasl-external", no_argument },
@@ -209,6 +210,13 @@ int main(int argc, char *argv[]) {
 				uiTime.enable = true;
 				if (optarg) uiTime.format = optarg;
 			}
+			break; case 'V': {
+				if      (!strcasecmp(optarg, "Ice"))  self.heat = Ice;
+				else if (!strcasecmp(optarg, "Cold")) self.heat = Cold;
+				else if (!strcasecmp(optarg, "Warm")) self.heat = Warm;
+				else if (!strcasecmp(optarg, "Hot"))  self.heat = Hot;
+				else errx(EX_USAGE, "invalid visibility");
+			}
 			break; case 'a': sasl = true; self.plain = optarg;
 			break; case 'c': cert = optarg;
 			break; case 'e': sasl = true;
diff --git a/chat.h b/chat.h
index a4c7670..1bd67f1 100644
--- a/chat.h
+++ b/chat.h
@@ -185,6 +185,7 @@ enum Cap {
 #undef X
 };
 
+enum Heat { Ice, Cold, Warm, Hot };
 extern struct Self {
 	bool debug;
 	bool kiosk;
@@ -199,6 +200,7 @@ extern struct Self {
 	char *host;
 	enum Color color;
 	char *quit;
+	enum Heat heat;
 } self;
 
 static inline void set(char **field, const char *value) {
@@ -288,7 +290,6 @@ const char *commandIsAction(uint id, const char *input);
 size_t commandWillSplit(uint id, const char *input);
 void commandCompleteAdd(void);
 
-enum Heat { Ice, Cold, Warm, Hot };
 enum { TimeCap = 64 };
 extern struct Time {
 	bool enable;
diff --git a/ui.c b/ui.c
index abf477c..dae6269 100644
--- a/ui.c
+++ b/ui.c
@@ -136,7 +136,7 @@ static uint windowFor(uint id) {
 	window->id = id;
 	window->mark = true;
 	window->time = uiTime.enable;
-	window->thresh = Cold;
+	window->thresh = self.heat;
 	window->buffer = bufferAlloc();
 	completeAdd(None, idNames[id], idColors[id]);
 	return windowPush(window);
@@ -457,7 +457,7 @@ static void mark(struct Window *window) {
 static void unmark(struct Window *window) {
 	if (!window->scroll) {
 		window->mark = false;
-		window->heat = Cold;
+		window->heat = self.heat;
 	}
 	statusUpdate();
 }
-- 
2.32.0

Re: [PATCH] Add -V/visibility option for default heat

From: Klemens Nanni
On Sat, Jul 03, 2021 at 07:34:26AM +0000, Klemens Nanni wrote:
 
> NB: Combining catgirl's internal representation (`enum Heat') with one
> of the remains in the getopt(3) option character space (`-V') standing
> for visibility seems... a bit off, but could be changed later if need
> be.

Given that there is currently no other spot in which catgirl exposes its
internal idea of "heat" to the user, we might as well keep it that way
and pick perhaps more appropiate:

> @@ -344,6 +345,21 @@ Set username to
>  .Ar user .
>  The default username is the same as the nickname.
>  .
> +.It Fl V Ar heat | Cm visibility No = Ar heat
> +Set the default message visibility threshold for new windows:
> +.Pp
> +.Bl -tag -width Warm -compact -offset indent
> +.It Ar Ice
> +Show all events and messages (including ignored ones).
> +.It Ar Cold
> +(default)
> +Show general events and non-highlighted messages.
> +.It Ar Warm
> +Hide general events, show messages.
> +.It Ar Hot
> +Show only highlighted messages.
> +.El
> +.

So these could be
"all" or "unfiltered",
"default" or "normal",
"filtered" or "quiet",
"important" or "silence"
for example...

Re: [PATCH] Add -V/visibility option for default heat

From: Klemens Nanni
On Sat, Jul 03, 2021 at 01:43:48PM +0000, Klemens Nanni wrote:
> On Sat, Jul 03, 2021 at 07:34:26AM +0000, Klemens Nanni wrote:
>  
> > NB: Combining catgirl's internal representation (`enum Heat') with one
> > of the remains in the getopt(3) option character space (`-V') standing
> > for visibility seems... a bit off, but could be changed later if need
> > be.
> 
> Given that there is currently no other spot in which catgirl exposes its
> internal idea of "heat" to the user, we might as well keep it that way
> and pick perhaps more appropiate:
> 
> > @@ -344,6 +345,21 @@ Set username to
> >  .Ar user .
> >  The default username is the same as the nickname.
> >  .
> > +.It Fl V Ar heat | Cm visibility No = Ar heat
> > +Set the default message visibility threshold for new windows:
> > +.Pp
> > +.Bl -tag -width Warm -compact -offset indent
> > +.It Ar Ice
> > +Show all events and messages (including ignored ones).
> > +.It Ar Cold
> > +(default)
> > +Show general events and non-highlighted messages.
> > +.It Ar Warm
> > +Hide general events, show messages.
> > +.It Ar Hot
> > +Show only highlighted messages.
> > +.El
> > +.
> 
> So these could be
> "all" or "unfiltered",
> "default" or "normal",
> "filtered" or "quiet",
> "important" or "silence"
> for example...

Here is my second attempt without case-insensitive matching that goes
for "all", "normal" "chat", "highlight".  Commit message is hopefully
clearer as well.

It also fixes a typo in the manual's synopsis (I reused `-V'),
thanks to Raf Czlonka for pointing it out.

Seems a bit tricky to come up with meaningful threshold names, so I've
picked "chat" as that would be my personal default:  no JOIN/PART noise
and no server messages but all regular chat messages while ignored ones
stay ignored, i.e. my expected chat experience.  "normal" is really
just to not repeat "default" but probably doesn't matter much there is
no need to use it explicitly anyway.  "all" seems like a given and
"highlight" was picked in favour of "private" as the former somewhat
implies the latter (for me, at least).

If that's a desirable direction, I can try next to improve the manual
a bit so that keybindings for changing the threshold and `-V' don't
overlap too much, possibly by moving the common bits to a separate
section similar to CertFP such that keybindings and `-V' just refer to
it instead of phrasing the same content in different ways.  Then we can
also mention how `-s/save' persists individual window thresholds.

-- >8 --

Setting the same visibility threshold with `M--' or `M-+' on all windows
can be cumbersome (each window's threshold will persist across load/save
cycles, i.e. when using the `-s/save' option).

Allow changing the default such that new windows pick it up;  not just
at runtime but also at startup without load/save enabled.
---
 catgirl.1 | 16 ++++++++++++++++
 chat.c    | 10 +++++++++-
 chat.h    |  4 +++-
 ui.c      |  4 ++--
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/catgirl.1 b/catgirl.1
index b8c42c2..dee45e7 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -16,6 +16,7 @@
 .Op Fl O Ar open
 .Op Fl S Ar bind
 .Op Fl T Ns Op Ar timestamp
+.Op Fl V Ar visibility
 .Op Fl a Ar plain
 .Op Fl c Ar cert
 .Op Fl h Ar host
@@ -358,6 +359,21 @@ Set username to
 .Ar user .
 The default username is the same as the nickname.
 .
+.It Fl V Ar heat | Cm visibility No = Ar heat
+Set the default message visibility threshold for new windows:
+.Pp
+.Bl -tag -width highlight -compact -offset indent
+.It Ar all
+Show all events and messages (including ignored ones).
+.It Ar normal
+(default)
+Show general events and non-highlighted messages.
+.It Ar chat
+Hide general events, show messages.
+.It Ar highlight
+Show only highlighted and private messages.
+.El
+.
 .It Fl v | Cm debug
 Log raw IRC messages to the
 .Sy <debug>
diff --git a/chat.c b/chat.c
index 5d9ad5e..5b6bbf7 100644
--- a/chat.c
+++ b/chat.c
@@ -84,7 +84,7 @@ enum Color idColors[IDCap] = {
 uint idNext = Network + 1;
 
 struct Network network = { .userLen = 9, .hostLen = 63 };
-struct Self self = { .color = Default };
+struct Self self = { .color = Default, .heat = Cold };
 
 static const char *save;
 static void exitSave(void) {
@@ -166,6 +166,7 @@ int main(int argc, char *argv[]) {
 		{ .val = 'R', .name = "restrict", no_argument },
 		{ .val = 'S', .name = "bind", required_argument },
 		{ .val = 'T', .name = "timestamp", optional_argument },
+		{ .val = 'V', .name = "visibility", required_argument },
 		{ .val = 'a', .name = "sasl-plain", required_argument },
 		{ .val = 'c', .name = "cert", required_argument },
 		{ .val = 'e', .name = "sasl-external", no_argument },
@@ -209,6 +210,13 @@ int main(int argc, char *argv[]) {
 				uiTime.enable = true;
 				if (optarg) uiTime.format = optarg;
 			}
+			break; case 'V': {
+				if      (!strcmp(optarg, "all"))       self.heat = Ice;
+				else if (!strcmp(optarg, "normal"))    self.heat = Cold;
+				else if (!strcmp(optarg, "chat"))      self.heat = Warm;
+				else if (!strcmp(optarg, "highlight")) self.heat = Hot;
+				else errx(EX_USAGE, "invalid visibility");
+			}
 			break; case 'a': sasl = true; self.plain = optarg;
 			break; case 'c': cert = optarg;
 			break; case 'e': sasl = true;
diff --git a/chat.h b/chat.h
index 9ad298f..4dca67e 100644
--- a/chat.h
+++ b/chat.h
@@ -185,6 +185,8 @@ enum Cap {
 #undef X
 };
 
+enum Heat { Ice, Cold, Warm, Hot };
+
 extern struct Self {
 	bool debug;
 	bool kiosk;
@@ -200,6 +202,7 @@ extern struct Self {
 	enum Color color;
 	char *invited;
 	char *quit;
+	enum Heat heat;
 } self;
 
 static inline void set(char **field, const char *value) {
@@ -289,7 +292,6 @@ const char *commandIsAction(uint id, const char *input);
 size_t commandWillSplit(uint id, const char *input);
 void commandCompleteAdd(void);
 
-enum Heat { Ice, Cold, Warm, Hot };
 enum { TimeCap = 64 };
 extern struct Time {
 	bool enable;
diff --git a/ui.c b/ui.c
index abf477c..dae6269 100644
--- a/ui.c
+++ b/ui.c
@@ -136,7 +136,7 @@ static uint windowFor(uint id) {
 	window->id = id;
 	window->mark = true;
 	window->time = uiTime.enable;
-	window->thresh = Cold;
+	window->thresh = self.heat;
 	window->buffer = bufferAlloc();
 	completeAdd(None, idNames[id], idColors[id]);
 	return windowPush(window);
@@ -457,7 +457,7 @@ static void mark(struct Window *window) {
 static void unmark(struct Window *window) {
 	if (!window->scroll) {
 		window->mark = false;
-		window->heat = Cold;
+		window->heat = self.heat;
 	}
 	statusUpdate();
 }
-- 
2.32.0

Re: [PATCH] Add -V/visibility option for default heat

From: june
Applied the patch for a simpler -q/quiet option instead, which
eliminates the need to give user-facing names to internal heat
values.