strbuf_add_wrapped_text(): skip over colour codes
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Mon, 23 Nov 2009 22:40:03 +0000 (23:40 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 Nov 2009 23:36:07 +0000 (15:36 -0800)
Ignore display mode escape sequences (colour codes) for the purpose of
text wrapping because they don't have a visible width.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/pretty-formats.txt
utf8.c

index 7ff6a6ce22f735fa40b2b2d1ec3f66f9bce9cc64..0683fb3a3d34e89c67c6e37f2ee96adcd2821ea0 100644 (file)
@@ -136,9 +136,7 @@ The placeholders are:
 - '%n': newline
 - '%x00': print a byte from a hex code
 - '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
-  linkgit:git-shortlog[1].  NOTE: Color placeholders (`%C*`) are not
-  recognized as having no width, so they should not be put into wrapped
-  sections.
+  linkgit:git-shortlog[1].
 
 NOTE: Some placeholders may depend on other options given to the
 revision traversal engine. For example, the `%g*` reflog options will
diff --git a/utf8.c b/utf8.c
index 01d1869fa3df23e71879f15e566d8733168912cd..7ddff23fa77fbadf7723bca03d24ad5b8f2baca2 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -314,6 +314,20 @@ static void strbuf_add_indented_text(struct strbuf *buf, const char *text,
        }
 }
 
+static size_t display_mode_esc_sequence_len(const char *s)
+{
+       const char *p = s;
+       if (*p++ != '\033')
+               return 0;
+       if (*p++ != '[')
+               return 0;
+       while (isdigit(*p) || *p == ';')
+               p++;
+       if (*p++ != 'm')
+               return 0;
+       return p - s;
+}
+
 /*
  * Wrap the text, if necessary. The variable indent is the indent for the
  * first line, indent2 is the indent for all other lines.
@@ -337,7 +351,13 @@ int strbuf_add_wrapped_text(struct strbuf *buf,
        }
 
        for (;;) {
-               char c = *text;
+               char c;
+               size_t skip;
+
+               while ((skip = display_mode_esc_sequence_len(text)))
+                       text += skip;
+
+               c = *text;
                if (!c || isspace(c)) {
                        if (w < width || !space) {
                                const char *start = bol;