about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-09-11 19:12:42 -0400
committerJune McEnroe <june@causal.agency>2020-09-11 19:12:42 -0400
commitb2de129e3f48136bd56a5f0f1d9028c2ecef0bc2 (patch)
tree9100f366bc3867a4b5357ef8cd06c6393d76e4d1
parentSilence set-but-unused warning (diff)
downloadcatgirl-b2de129e3f48136bd56a5f0f1d9028c2ecef0bc2.tar.gz
catgirl-b2de129e3f48136bd56a5f0f1d9028c2ecef0bc2.zip
Copy style from wrapping point
This fixes a bug when wrapping on a word with style changes inside it,
where the copied style would be different depending on the width of the
terminal.
-rw-r--r--buffer.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/buffer.c b/buffer.c
index 91fe6b4..6a7fe6e 100644
--- a/buffer.c
+++ b/buffer.c
@@ -111,6 +111,7 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 	int align = 0;
 	char *wrap = NULL;
 	struct Style style = StyleDefault;
+	struct Style wrapStyle = StyleDefault;
 	for (char *str = line->str; *str;) {
 		size_t len = styleParse(&style, (const char **)&str);
 		if (!len) continue;
@@ -138,15 +139,26 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 			width += wcwidth(wc);
 		}
 
-		if (tab && width < cols) align = width;
-		if (iswspace(wc) && !tab) wrap = str;
+		if (tab && width < cols) {
+			align = width;
+		}
+		if (iswspace(wc) && !tab) {
+			wrap = str;
+			wrapStyle = style;
+		}
+		if (wc == L'-' && width <= cols) {
+			wrap = &str[n];
+			wrapStyle = style;
+		}
+
 		if (width <= cols) {
-			if (wc == L'-') wrap = &str[n];
 			str += n;
 			continue;
+		} else if (!wrap) {
+			wrap = str;
+			wrapStyle = style;
 		}
 
-		if (!wrap) wrap = str;
 		n = mbtowc(&wc, wrap, strlen(wrap));
 		if (n < 0) {
 			n = 1;
@@ -165,8 +177,9 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 
 		struct Cat cat = { line->str, cap, 0 };
 		catf(&cat, "%*s%n", align, "", &width);
-		styleCat(&cat, style);
+		styleCat(&cat, wrapStyle);
 		str = &line->str[cat.len];
+		style = wrapStyle;
 		catf(&cat, "%s", &wrap[n]);
 
 		*wrap = '\0';