The earlier implementation used to just strip color escapes. This makes them
output 'raw', coloring the screen. Like less, it assumes that the codes don't
move the cursor. Emits NORMAL at newlines, like less, to deal with malformed
input.

count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape,
essentially matching for "\033\[[0-9;]*m".

Doesn't work in regex find mode, but neither does the normal escape
highlighting.

[1] 
https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters

Signed-off-by: FriendlyNeighborhoodShane <shane.880088.s...@gmail.com>
---
 miscutils/less.c | 54 +++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/miscutils/less.c b/miscutils/less.c
index 8a0525cb7..1e2c4c5cf 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -139,7 +139,7 @@
 //usage:     "\n       -S      Truncate long lines"
 //usage:       )
 //usage:       IF_FEATURE_LESS_RAW(
-//usage:     "\n       -R      Remove color escape codes in input"
+//usage:     "\n       -R      Output 'raw' color escape codes"
 //usage:       )
 //usage:     "\n       -~      Suppress ~s displayed past EOF"
 
@@ -229,9 +229,6 @@ struct globals {
        regex_t pattern;
        smallint pattern_valid;
 #endif
-#if ENABLE_FEATURE_LESS_RAW
-       smallint in_escape;
-#endif
 #if ENABLE_FEATURE_LESS_ASK_TERMINAL
        smallint winsize_err;
 #endif
@@ -541,26 +538,6 @@ static void read_lines(void)
                                *--p = '\0';
                                continue;
                        }
-#if ENABLE_FEATURE_LESS_RAW
-                       if (option_mask32 & FLAG_R) {
-                               if (c == '\033')
-                                       goto discard;
-                               if (G.in_escape) {
-                                       if (isdigit(c)
-                                        || c == '['
-                                        || c == ';'
-                                        || c == 'm'
-                                       ) {
- discard:
-                                               G.in_escape = (c != 'm');
-                                               readpos++;
-                                               continue;
-                                       }
-                                       /* Hmm, unexpected end of "ESC [ N ; N 
m" sequence */
-                                       G.in_escape = 0;
-                               }
-                       }
-#endif
                        {
                                size_t new_last_line_pos = last_line_pos + 1;
                                if (c == '\t') {
@@ -864,13 +841,34 @@ static void print_found(const char *line)
 void print_found(const char *line);
 #endif
 
+static size_t count_colctrl(const char *str)
+{
+    size_t n;
+    if (str[1] == '['
+     && (n = strspn(str+2, "0123456789;")) >= 0 // always true
+     && str[n+2] == 'm')
+        return n+3;
+    return 0;
+}
+
 static void print_ascii(const char *str)
 {
        char buf[width+1];
        char *p;
        size_t n;
+#if ENABLE_FEATURE_LESS_RAW
+       size_t esc = 0;
+#endif
 
        while (*str) {
+#if ENABLE_FEATURE_LESS_RAW
+               if (esc) {
+                       printf("%.*s", (int) esc, str);
+                       str += esc;
+                       esc = 0;
+                       continue;
+               }
+#endif
                n = strcspn(str, controls);
                if (n) {
                        if (!str[n]) break;
@@ -886,6 +884,13 @@ static void print_ascii(const char *str)
                        /* VT100's CSI, aka Meta-ESC. Who's inventor? */
                        /* I want to know who committed this sin */
                                *p++ = '{';
+#if ENABLE_FEATURE_LESS_RAW
+                       else if ((option_mask32 & FLAG_R)
+                                        && *str == '\033'
+                                        && (esc = count_colctrl(str))) {
+                               break; // flush collected control chars
+                       }
+#endif
                        else
                                *p++ = ctrlconv[(unsigned char)*str];
                        str++;
@@ -894,6 +899,7 @@ static void print_ascii(const char *str)
                print_hilite(buf);
        }
        puts(str);
+       printf(NORMAL);
 }
 
 /* Print the buffer */
-- 
2.36.1

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to