The previous patch had an error in the first hunk for normal.c. I
forgot to remove an "if" line when I removed the following conditional
line. Due to its placement before a "for" line that tested the same
condition, it didn't affect the behavior of the patch, but it was
unsightly. I've attached an updated patch.
Quoting "Dennis Lambe Jr." <[email protected]>:
Hello!
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.
I've attached a patch to reset ANSI color to the default at the end
of every line and restart it at the beginning of the next. It
patches normal and context mode. Side-by-side already worked in my
testing.
I hope it's useful to you. Please let me know if there are changes
you would like made before you can accept it.
--Dennis Lambe Jr.
diff --git a/src/context.c b/src/context.c
index 4dd882d..c8de512 100644
--- a/src/context.c
+++ b/src/context.c
@@ -43,8 +43,11 @@ 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 +74,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);
+ fprintf (outfile, "\n");
}
/* Print a header for a context diff, with the file names and dates. */
@@ -80,7 +85,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 +95,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 +222,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 +243,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 +260,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 +281,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 +389,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 +408,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);
}
diff --git a/tests/colors b/tests/colors
index f0f6246..5363cd8 100755
--- a/tests/colors
+++ b/tests/colors
@@ -25,9 +25,9 @@ gen_exp_u()
local de=$(printf "$e[${de}m")
local ln=$(printf "$e[${ln}m")
printf '%s' \
-"$hd--- a$tab$epoch_plus
-+++ b$tab$epoch_plus
-$rs${ln}@@ -1 +1 @@$rs
+"$hd--- a$tab$epoch_plus$rs
+$hd+++ b$tab$epoch_plus$rs
+${ln}@@ -1 +1 @@$rs
$de-a$rs
$ad+b$rs
"
@@ -42,9 +42,9 @@ gen_exp_c()
local de=$(printf "$e[${de}m")
local ln=$(printf "$e[${ln}m")
printf '%s' \
-"$hd*** a$tab$epoch_posix_1003_1_2001
---- b$tab$epoch_posix_1003_1_2001
-$rs***************
+"$hd*** a$tab$epoch_posix_1003_1_2001$rs
+$hd--- b$tab$epoch_posix_1003_1_2001$rs
+***************
$ln*** 1 ****$rs
$de! a$rs
$ln--- 1 ----$rs