Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 diff.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/diff.c b/diff.c
index 47d22e3..68a847d 100644
--- a/diff.c
+++ b/diff.c
@@ -457,6 +457,50 @@ struct tagged_pointer {
        enum pointer_tag tag;
 };
 
+static void emit_tagged_line(struct diff_options *o, const char *set,
+                            const char *line, int len,
+                            struct tagged_pointer *begin,
+                            struct tagged_pointer *end)
+{
+       struct tagged_pointer *current;
+       FILE *file = o->file;
+       const char *last_color = set;
+
+       for (current = begin; current < end; current++) {
+               struct tagged_pointer *next = current + 1;
+               const char *start = current->str;
+               const char *end = next->str;
+               const char *color = NULL;
+
+               switch (current->tag) {
+               case TAG_END_WORD:
+                       color = set;
+                       break;
+
+               case TAG_BEGIN_OLD_WORD:
+                       color = GIT_COLOR_BG_RED GIT_COLOR_YELLOW;
+                       break;
+
+               case TAG_BEGIN_NEW_WORD:
+                       color = GIT_COLOR_BG_GREEN GIT_COLOR_BLUE;
+                       break;
+
+               default:
+                       break;
+               }
+
+               if (color && color != last_color) {
+                       if (color == set)
+                               fputs(GIT_COLOR_RESET, file);
+                       fputs(color, file);
+                       last_color = color;
+               }
+               while (end > start && end[-1] == '\n')
+                       end--;
+               fwrite(start, end - start, 1, file);
+       }
+}
+
 static void emit_line_0(struct diff_options *o, const char *set, const char 
*reset,
                        int first, const char *line, int len,
                        struct tagged_pointer *begin,
@@ -487,7 +531,10 @@ static void emit_line_0(struct diff_options *o, const char 
*set, const char *res
                fputs(set, file);
                if (!nofirst)
                        fputc(first, file);
-               fwrite(line, len, 1, file);
+               if (begin)
+                       emit_tagged_line(o, set, line, len, begin, end);
+               else
+                       fwrite(line, len, 1, file);
                fputs(reset, file);
        }
        if (has_trailing_carriage_return)
@@ -531,7 +578,7 @@ static void emit_line_checked(const char *reset,
                        ws = NULL;
        }
 
-       if (!ws)
+       if (!ws || begin)
                emit_line_0(ecbdata->opt, set, reset, sign,
                            line, len, begin, end);
        else if (sign == '+' && new_blank_line_at_eof(ecbdata, line, len))
@@ -1312,7 +1359,7 @@ static void diff_words_flush_unified(struct emit_callback 
*ecb,
                emit_line_checked(reset, ecb, begin_line->str,
                                  end_line->str - begin_line->str,
                                  color, ws_error_highlight, sign,
-                                 NULL, NULL);
+                                 begin_line, end_line);
        }
        b->mark_nr = 0;
 }
-- 
2.3.0.rc1.137.g477eb31

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to