about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--catgirl.12
-rw-r--r--chat.h2
-rw-r--r--command.c12
-rw-r--r--ui.c28
4 files changed, 44 insertions, 0 deletions
diff --git a/catgirl.1 b/catgirl.1
index 0702f58..9314e7a 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -146,6 +146,8 @@ Send a raw IRC command.
 .
 .Ss UI Commands
 .Bl -tag -width Ds
+.It Ic /close Op Ar name | num
+Close the named, numbered or current window.
 .It Ic /window Ar name
 Switch to window by name.
 .It Ic /window Ar num , Ic / Ns Ar num
diff --git a/chat.h b/chat.h
index 081370e..9daa38c 100644
--- a/chat.h
+++ b/chat.h
@@ -128,6 +128,8 @@ void uiHide(void);
 void uiDraw(void);
 void uiShowID(size_t id);
 void uiShowNum(size_t num);
+void uiCloseID(size_t id);
+void uiCloseNum(size_t id);
 void uiRead(void);
 void uiWrite(size_t id, enum Heat heat, const time_t *time, const char *str);
 void uiFormat(
diff --git a/command.c b/command.c
index 9047e95..e33c57e 100644
--- a/command.c
+++ b/command.c
@@ -100,10 +100,22 @@ static void commandWindow(size_t id, char *params) {
 	}
 }
 
+static void commandClose(size_t id, char *params) {
+	if (!params) {
+		uiCloseID(id);
+	} else if (isdigit(params[0])) {
+		uiCloseNum(strtoul(params, NULL, 10));
+	} else {
+		id = idFind(params);
+		if (id) uiCloseID(id);
+	}
+}
+
 static const struct Handler {
 	const char *cmd;
 	Command *fn;
 } Commands[] = {
+	{ "/close", commandClose },
 	{ "/join", commandJoin },
 	{ "/me", commandMe },
 	{ "/nick", commandNick },
diff --git a/ui.c b/ui.c
index 6d1338b..c738617 100644
--- a/ui.c
+++ b/ui.c
@@ -573,6 +573,34 @@ void uiShowNum(size_t num) {
 	windowShow(window);
 }
 
+static void windowClose(struct Window *window) {
+	if (window->id == Network) return;
+	if (windows.active == window) {
+		windowShow(window->prev ? window->prev : window->next);
+	}
+	if (windows.other == window) windows.other = NULL;
+	windowRemove(window);
+	for (size_t i = 0; i < BufferCap; ++i) {
+		free(window->buffer.lines[i]);
+	}
+	delwin(window->pad);
+	free(window);
+	statusUpdate();
+}
+
+void uiCloseID(size_t id) {
+	windowClose(windowFor(id));
+}
+
+void uiCloseNum(size_t num) {
+	struct Window *window = windows.head;
+	for (size_t i = 0; i < num; ++i) {
+		window = window->next;
+		if (!window) return;
+	}
+	windowClose(window);
+}
+
 static void keyCode(int code) {
 	size_t id = windows.active->id;
 	switch (code) {