summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--chat.h3
-rw-r--r--edit.c25
-rw-r--r--ui.c76
3 files changed, 55 insertions, 49 deletions
diff --git a/chat.h b/chat.h
index 896549e..914fde6 100644
--- a/chat.h
+++ b/chat.h
@@ -156,8 +156,7 @@ enum Edit {
 	EditEnter,
 };
 void edit(size_t id, enum Edit op, wchar_t ch);
-char *editHead(void);
-char *editTail(void);
+char *editBuffer(size_t *pos);
 
 const char *complete(size_t id, const char *prefix);
 void completeAccept(void);
diff --git a/edit.c b/edit.c
index 0c50f33..38dadcd 100644
--- a/edit.c
+++ b/edit.c
@@ -27,21 +27,22 @@ static wchar_t buf[Cap];
 static size_t len;
 static size_t pos;
 
-char *editHead(void) {
+char *editBuffer(size_t *mbsPos) {
 	static char mbs[MB_LEN_MAX * Cap];
+
 	const wchar_t *ptr = buf;
-	size_t n = wcsnrtombs(mbs, &ptr, pos, sizeof(mbs) - 1, NULL);
-	assert(n != (size_t)-1);
-	mbs[n] = '\0';
-	return mbs;
-}
+	size_t mbsLen = wcsnrtombs(mbs, &ptr, pos, sizeof(mbs) - 1, NULL);
+	assert(mbsLen != (size_t)-1);
+	if (mbsPos) *mbsPos = mbsLen;
 
-char *editTail(void) {
-	static char mbs[MB_LEN_MAX * Cap];
-	const wchar_t *ptr = &buf[pos];
-	size_t n = wcsnrtombs(mbs, &ptr, len - pos, sizeof(mbs) - 1, NULL);
+	ptr = &buf[pos];
+	size_t n = wcsnrtombs(
+		&mbs[mbsLen], &ptr, len - pos, sizeof(mbs) - mbsLen - 1, NULL
+	);
 	assert(n != (size_t)-1);
-	mbs[n] = '\0';
+	mbsLen += n;
+
+	mbs[mbsLen] = '\0';
 	return mbs;
 }
 
@@ -78,7 +79,7 @@ void edit(size_t id, enum Edit op, wchar_t ch) {
 		}
 		break; case EditEnter: {
 			pos = 0;
-			command(id, editTail());
+			command(id, editBuffer(NULL));
 			len = 0;
 		}
 	}
diff --git a/ui.c b/ui.c
index 23bf929..c342339 100644
--- a/ui.c
+++ b/ui.c
@@ -507,48 +507,54 @@ static void inputAdd(struct Style *style, const char *str) {
 
 static void inputUpdate(void) {
 	size_t id = windows.active->id;
-	const char *nick = self.nick;
-	const char *head = editHead();
+	size_t pos;
+	char *buf = editBuffer(&pos);
+
 	const char *skip = NULL;
-	const char *pre = "";
-	const char *suf = " ";
-	struct Style style = { .fg = self.color, .bg = Default };
-	struct Style reset = Reset;
-	if (NULL != (skip = commandIsPrivmsg(id, head))) {
-		pre = "<";
-		suf = "> ";
-	} else if (NULL != (skip = commandIsNotice(id, head))) {
-		pre = "-";
-		suf = "- ";
-		reset.fg = LightGray;
-	} else if (NULL != (skip = commandIsAction(id, head))) {
-		style.attr |= A_ITALIC;
-		pre = "* ";
-		reset.attr |= A_ITALIC;
+	struct Style init = { .fg = self.color, .bg = Default };
+	struct Style rest = Reset;
+	const char *prefix = "";
+	const char *prompt = (self.nick ? self.nick : "");
+	const char *suffix = "";
+	if (NULL != (skip = commandIsPrivmsg(id, buf))) {
+		prefix = "<"; suffix = "> ";
+	} else if (NULL != (skip = commandIsNotice(id, buf))) {
+		prefix = "-"; suffix = "- ";
+		rest.fg = LightGray;
+	} else if (NULL != (skip = commandIsAction(id, buf))) {
+		init.attr |= A_ITALIC;
+		prefix = "* "; suffix = " ";
+		rest.attr |= A_ITALIC;
 	} else if (id == Debug) {
-		skip = head;
-		style.fg = Gray;
-		pre = "<<";
-		nick = NULL;
+		skip = buf;
+		init.fg = Gray;
+		prompt = "<< ";
+	} else {
+		prompt = "";
+	}
+	if (skip && skip > &buf[pos]) {
+		skip = NULL;
+		prefix = prompt = suffix = "";
 	}
 
 	int y, x;
 	wmove(input, 0, 0);
-	if (skip) {
-		wattr_set(
-			input,
-			style.attr | colorAttr(mapColor(style.fg)),
-			colorPair(mapColor(style.fg), mapColor(style.bg)),
-			NULL
-		);
-		waddstr(input, pre);
-		if (nick) waddstr(input, nick);
-		waddstr(input, suf);
-	}
-	style = reset;
-	inputAdd(&style, (skip ? skip : head));
+	wattr_set(
+		input,
+		init.attr | colorAttr(mapColor(init.fg)),
+		colorPair(mapColor(init.fg), mapColor(init.bg)),
+		NULL
+	);
+	waddstr(input, prefix);
+	waddstr(input, prompt);
+	waddstr(input, suffix);
+	struct Style style = rest;
+	char p = buf[pos];
+	buf[pos] = '\0';
+	inputAdd(&style, (skip ? skip : buf));
 	getyx(input, y, x);
-	inputAdd(&style, editTail());
+	buf[pos] = p;
+	inputAdd(&style, &buf[pos]);
 	wclrtoeol(input);
 	wmove(input, y, x);
 }