[PATCH] Add "/window -j" to print channels in -j/join format

[PATCH] Add "/window -j" to print channels in -j/join format

From: Klemens Nanni
Joining channels at runtime desyncs with join strings passed on the
command line or in configuration files.

Provide means to print a ready-to-use join string to avoid hand-crafting
it (after having joined many channels permanently over time).

`-j/join' and `/window -j' are round-trip safe except when using
`join = channels keys' since `/window -j' does not print keys.

Code-wise, the join string's trailing comma is stripped iff the string
has been crafted;  this isn't strictly needed as `-j/join' gracefully
accepts trailing commas, but it looks ugly nonetheless.
---
 catgirl.1 |  4 ++++
 chat.h    |  2 +-
 command.c |  4 +++-
 ui.c      | 22 +++++++++++++++++-----
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/catgirl.1 b/catgirl.1
index bb425cc..2481d08 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -548,6 +548,10 @@ Temporarily remove a message highlight pattern.
 Temporarily remove a message ignore pattern.
 .It Ic /window
 List all windows.
+.It Ic /window Fl j
+List all channels in
+.Fl j | Cm join
+format.
 .It Ic /window Ar name | substring
 Switch to window by name
 or matching substring.
diff --git a/chat.h b/chat.h
index dd9c823..777baac 100644
--- a/chat.h
+++ b/chat.h
@@ -304,7 +304,7 @@ void uiInitLate(void);
 void uiShow(void);
 void uiHide(void);
 void uiDraw(void);
-void uiWindows(void);
+void uiWindows(bool);
 void uiShowID(uint id);
 void uiShowNum(uint num);
 void uiMoveID(uint id, uint num);
diff --git a/command.c b/command.c
index 5c97ef5..946a8fd 100644
--- a/command.c
+++ b/command.c
@@ -375,7 +375,9 @@ static void commandQuery(uint id, char *params) {
 
 static void commandWindow(uint id, char *params) {
 	if (!params) {
-		uiWindows();
+		uiWindows(false);
+	} else if (!strcmp(params, "-j")) {
+		uiWindows(true);
 	} else if (isdigit(params[0])) {
 		uiShowNum(strtoul(params, NULL, 10));
 	} else {
diff --git a/ui.c b/ui.c
index 561db65..03d77bb 100644
--- a/ui.c
+++ b/ui.c
@@ -816,13 +816,25 @@ static void inputUpdate(void) {
 	wmove(input, y, x);
 }
 
-void uiWindows(void) {
+void uiWindows(bool printJoin) {
+	char join[1024];
+	char *ptr = join;
+	char *end = &join[sizeof(join)];
 	for (uint num = 0; num < windows.len; ++num) {
 		const struct Window *window = windows.ptrs[num];
-		uiFormat(
-			Network, Warm, NULL, "\3%02d%u %s",
-			idColors[window->id], num, idNames[window->id]
-		);
+		if (printJoin) {
+			if (idNames[window->id][0] != '#') continue;
+			ptr = seprintf(ptr, end, "%s,", idNames[window->id]);
+		} else {
+			uiFormat(
+				Network, Warm, NULL, "\3%02d%u %s",
+				idColors[window->id], num, idNames[window->id]
+			);
+		}
+	}
+	if (ptr > join) {
+		*--ptr = '\0';
+		uiFormat(Network, Warm, NULL, "%s", join);
 	}
 }
 
-- 
2.32.0

Re: [PATCH] Add "/window -j" to print channels in -j/join format

From: june
> On Jul 27, 2021, at 13:52, Klemens Nanni <klemens@posteo.de> wrote:
> 
> Joining channels at runtime desyncs with join strings passed on the
> command line or in configuration files.
> 
> Provide means to print a ready-to-use join string to avoid hand-crafting
> it (after having joined many channels permanently over time).
> 
> `-j/join' and `/window -j' are round-trip safe except when using
> `join = channels keys' since `/window -j' does not print keys.

I really don’t like the idea of adding “flags” to /commands... And
I don’t think this function is worth doing it for.

Re: [PATCH] Add "/window -j" to print channels in -j/join format

From: Klemens Nanni
To: june
On Mon, Aug 02, 2021 at 01:10:43PM -0400, june wrote:
> > On Jul 27, 2021, at 13:52, Klemens Nanni <klemens@posteo.de> wrote:
> > 
> > Joining channels at runtime desyncs with join strings passed on the
> > command line or in configuration files.
> > 
> > Provide means to print a ready-to-use join string to avoid hand-crafting
> > it (after having joined many channels permanently over time).
> > 
> > `-j/join' and `/window -j' are round-trip safe except when using
> > `join = channels keys' since `/window -j' does not print keys.
> 
> I really don’t like the idea of adding “flags” to /commands... And
> I don’t think this function is worth doing it for.

Alright :)

I also thought about a more general `/dump' that writes out all options
(modulo passwords, maybe);  this would not only be helpful for channels
but ignores and highlights as well that accumulated during runtime.

It seems cumbersome to copy/paste these things between `/window', `/ignore'
and the other values one might passed on the command line but now wants to
see in a file.

Would that be a feasible approach?

Re: [PATCH] Add "/window -j" to print channels in -j/join format

From: june
> On Aug 2, 2021, at 13:28, Klemens Nanni <klemens@posteo.de> wrote:
> 
> Alright :)
> 
> I also thought about a more general `/dump' that writes out all options
> (modulo passwords, maybe);  this would not only be helpful for channels
> but ignores and highlights as well that accumulated during runtime.
> 
> It seems cumbersome to copy/paste these things between `/window', `/ignore'
> and the other values one might passed on the command line but now wants to
> see in a file.
> 
> Would that be a feasible approach?

To me a /dump command sounds like an inconvenient way to do a kind
of “dynamic configuration”, which is a non-feature. Its implementation
would be awkward too, if it’s not limited to joins and ignores,
since there’s plenty of configuration that never leaves main()
currently. To me, joining new channels and adding new ignores is
rare enough that it’s not unreasonable to also update the configuration
file manually. (In my case, I ssh to a server running pounce and
add joins to the configuration file there.)