about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-03-17 13:34:33 -0400
committerJune McEnroe <june@causal.agency>2021-03-17 13:34:33 -0400
commit8ea881a097360a8ed7dd07ee15dbe264ad5a0912 (patch)
treeeff988adf922992cd8b1560b81b75e349b016032
parentAllow multi-line /me and split long /me messages (diff)
downloadcatgirl-8ea881a097360a8ed7dd07ee15dbe264ad5a0912.tar.gz
catgirl-8ea881a097360a8ed7dd07ee15dbe264ad5a0912.zip
Show where too-long-messages will be automatically split
-rw-r--r--chat.h1
-rw-r--r--command.c27
-rw-r--r--ui.c30
3 files changed, 52 insertions, 6 deletions
diff --git a/chat.h b/chat.h
index 8249564..9f5d454 100644
--- a/chat.h
+++ b/chat.h
@@ -279,6 +279,7 @@ void command(uint id, char *input);
 const char *commandIsPrivmsg(uint id, const char *input);
 const char *commandIsNotice(uint id, const char *input);
 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 };
diff --git a/command.c b/command.c
index 5af3e25..0aefb2b 100644
--- a/command.c
+++ b/command.c
@@ -582,6 +582,33 @@ const char *commandIsAction(uint id, const char *input) {
 	return &input[4];
 }
 
+size_t commandWillSplit(uint id, const char *input) {
+	int chunk;
+	const char *params;
+	if (NULL != (params = commandIsPrivmsg(id, input))) {
+		chunk = splitChunk("PRIVMSG", id);
+	} else if (NULL != (params = commandIsNotice(id, input))) {
+		chunk = splitChunk("NOTICE", id);
+	} else if (NULL != (params = commandIsAction(id, input))) {
+		chunk = splitChunk("PRIVMSG \1ACTION\1", id);
+	} else if (id != Network && id != Debug && !strncmp(input, "/say ", 5)) {
+		params = &input[5];
+		chunk = splitChunk("PRIVMSG", id);
+	} else {
+		return 0;
+	}
+	if (strlen(params) <= (size_t)chunk) return 0;
+	for (
+		int split;
+		params[(split = splitLen(chunk, params))];
+		params = &params[split + 1]
+	) {
+		if (params[split] == '\n') continue;
+		return (params - input) + split;
+	}
+	return 0;
+}
+
 void command(uint id, char *input) {
 	if (id == Debug && input[0] != '/' && !self.restricted) {
 		commandQuote(id, input);
diff --git a/ui.c b/ui.c
index c3ceb0d..a78d5c8 100644
--- a/ui.c
+++ b/ui.c
@@ -716,6 +716,14 @@ static void inputAdd(struct Style *style, const char *str) {
 	}
 }
 
+static char *inputStop(struct Style *style, const char *str, char *stop) {
+	char ch = *stop;
+	*stop = '\0';
+	inputAdd(style, str);
+	*stop = ch;
+	return stop;
+}
+
 static void inputUpdate(void) {
 	size_t pos;
 	char *buf = editBuffer(&pos);
@@ -728,6 +736,7 @@ static void inputUpdate(void) {
 	struct Style stylePrompt = { .fg = self.color, .bg = Default };
 	struct Style styleInput = StyleDefault;
 
+	size_t split = commandWillSplit(window->id, buf);
 	const char *privmsg = commandIsPrivmsg(window->id, buf);
 	const char *notice = commandIsNotice(window->id, buf);
 	const char *action = commandIsAction(window->id, buf);
@@ -754,7 +763,6 @@ static void inputUpdate(void) {
 		skip = buf;
 	}
 
-	int y, x;
 	wmove(input, 0, 0);
 	if (window->time && window->id != Network) {
 		whline(input, ' ', uiTime.width);
@@ -764,13 +772,23 @@ static void inputUpdate(void) {
 	waddstr(input, prefix);
 	waddstr(input, prompt);
 	waddstr(input, suffix);
+
+	int y, x;
+	const char *ptr = skip;
 	struct Style style = styleInput;
-	char p = buf[pos];
-	buf[pos] = '\0';
-	inputAdd(&style, skip);
+	if (split && split < pos) {
+		ptr = inputStop(&style, ptr, &buf[split]);
+		style = styleInput;
+		style.bg = Red;
+	}
+	ptr = inputStop(&style, ptr, &buf[pos]);
 	getyx(input, y, x);
-	buf[pos] = p;
-	inputAdd(&style, &buf[pos]);
+	if (split && split >= pos) {
+		ptr = inputStop(&style, ptr, &buf[split]);
+		style = styleInput;
+		style.bg = Red;
+	}
+	inputAdd(&style, ptr);
 	wclrtoeol(input);
 	wmove(input, y, x);
 }