diff options
author | Dennis Lambe Jr <malsyned@malsyned.net> | 2018-12-29 13:04:10 -0800 |
---|---|---|
committer | Jim Meyering <meyering@fb.com> | 2018-12-30 22:22:10 -0800 |
commit | aaf0efa70d9a72175e7847df196cda21ab3bd3a9 (patch) | |
tree | e7483ef990b0a19484c0f56f60b35e6e65af9534 /src | |
parent | b9e2f4f3b395c8eff525a95e00ca14e7dd44a5b4 (diff) | |
download | diffutils-aaf0efa70d9a72175e7847df196cda21ab3bd3a9.tar.gz |
diff: adjust ANSI escapes for compatibility with less -R
GNU less can display ANSI-colored text with the -R flag, but this
support has some limitations. One of them is that if an escape
sequence starts on one line and ends on a different line, only the
first line will be colored in less.
As a result, when diff creates colored output with multi-line deletes
or adds, less will only color the first line.
This change resets ANSI color to the default at the end of
each line and restarts it at the beginning of the next. It patches
normal and context mode. Side-by-side already worked in my testing.
* src/context.c (print_context_label, pr_context_hunk): As above.
(pr_unidiff_hunk, print_context_header): Likewise.
* src/normal.c (print_normal_hunk): Likewise.
* tests/colors: Adjust existing tests to accommodate this.
* NEWS (Improvements): Mention it.
Proposed in http://bugs.gnu.org/31105
Diffstat (limited to 'src')
-rw-r--r-- | src/context.c | 37 | ||||
-rw-r--r-- | src/normal.c | 12 |
2 files changed, 19 insertions, 30 deletions
diff --git a/src/context.c b/src/context.c index 4dd882d..d1930d9 100644 --- a/src/context.c +++ b/src/context.c @@ -43,8 +43,9 @@ print_context_label (char const *mark, char const *name, char const *label) { + set_color_context (HEADER_CONTEXT); if (label) - fprintf (outfile, "%s %s\n", mark, label); + fprintf (outfile, "%s %s", mark, label); else { char buf[MAX (INT_STRLEN_BOUND (int) + 32, @@ -71,8 +72,10 @@ print_context_label (char const *mark, sprintf (buf, "%"PRIuMAX".%.9d", sec, nsec); } } - fprintf (outfile, "%s %s\t%s\n", mark, name, buf); + fprintf (outfile, "%s %s\t%s", mark, name, buf); } + set_color_context (RESET_CONTEXT); + putc ('\n', outfile); } /* Print a header for a context diff, with the file names and dates. */ @@ -80,7 +83,6 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { - set_color_context (HEADER_CONTEXT); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -91,7 +93,6 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } - set_color_context (RESET_CONTEXT); } /* Print an edit script in context format. */ @@ -219,11 +220,10 @@ pr_context_hunk (struct change *hunk) { struct change *next = hunk; - if (first0 <= last0) - set_color_context (DELETE_CONTEXT); - for (i = first0; i <= last0; i++) { + set_color_context (DELETE_CONTEXT); + /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -241,8 +241,7 @@ pr_context_hunk (struct change *hunk) prefix = (next->inserted > 0 ? "!" : "-"); } print_1_line_nl (prefix, &files[0].linbuf[i], true); - if (i == last0) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (files[0].linbuf[i + 1][-1] == '\n') putc ('\n', out); } @@ -259,11 +258,10 @@ pr_context_hunk (struct change *hunk) { struct change *next = hunk; - if (first1 <= last1) - set_color_context (ADD_CONTEXT); - for (i = first1; i <= last1; i++) { + set_color_context (ADD_CONTEXT); + /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -281,8 +279,7 @@ pr_context_hunk (struct change *hunk) prefix = (next->deleted > 0 ? "!" : "+"); } print_1_line_nl (prefix, &files[1].linbuf[i], true); - if (i == last1) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (files[1].linbuf[i + 1][-1] == '\n') putc ('\n', out); } @@ -390,19 +387,17 @@ pr_unidiff_hunk (struct change *hunk) /* For each difference, first output the deleted part. */ k = next->deleted; - if (k) - set_color_context (DELETE_CONTEXT); while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE_CONTEXT); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line_nl (NULL, line, true); - if (!k) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (line[1][-1] == '\n') putc ('\n', out); @@ -411,19 +406,17 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; - if (k) - set_color_context (ADD_CONTEXT); while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD_CONTEXT); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line_nl (NULL, line, true); - if (!k) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (line[1][-1] == '\n') putc ('\n', out); diff --git a/src/normal.c b/src/normal.c index c6aac07..bdb718b 100644 --- a/src/normal.c +++ b/src/normal.c @@ -59,13 +59,11 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) { - if (first0 <= last0) - set_color_context (DELETE_CONTEXT); for (i = first0; i <= last0; i++) { + set_color_context (DELETE_CONTEXT); print_1_line_nl ("<", &files[0].linbuf[i], true); - if (i == last0) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (files[0].linbuf[i + 1][-1] == '\n') putc ('\n', outfile); } @@ -77,13 +75,11 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the second file has. */ if (changes & NEW) { - if (first1 <= last1) - set_color_context (ADD_CONTEXT); for (i = first1; i <= last1; i++) { + set_color_context (ADD_CONTEXT); print_1_line_nl (">", &files[1].linbuf[i], true); - if (i == last1) - set_color_context (RESET_CONTEXT); + set_color_context (RESET_CONTEXT); if (files[1].linbuf[i + 1][-1] == '\n') putc ('\n', outfile); } |