The word diffing is not line oriented and would need some serious
effort to be transformed into a line oriented approach, so
just go with a symbol DIFF_SYMBOL_WORD_DIFF that is a partial line.

Signed-off-by: Stefan Beller <sbel...@google.com>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
---
 diff.c | 79 ++++++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 46 insertions(+), 33 deletions(-)

diff --git a/diff.c b/diff.c
index 76d4b8ebf9..e0d39d04da 100644
--- a/diff.c
+++ b/diff.c
@@ -570,6 +570,7 @@ enum diff_symbol {
        DIFF_SYMBOL_STATS_SUMMARY_ABBREV,
        DIFF_SYMBOL_STATS_SUMMARY_INSERTS_DELETES,
        DIFF_SYMBOL_STATS_LINE,
+       DIFF_SYMBOL_WORD_DIFF,
        DIFF_SYMBOL_SUBMODULE_ADD,
        DIFF_SYMBOL_SUBMODULE_DEL,
        DIFF_SYMBOL_SUBMODULE_UNTRACKED,
@@ -762,6 +763,9 @@ static void emit_diff_symbol(struct diff_options *o, enum 
diff_symbol s,
        case DIFF_SYMBOL_STATS_SUMMARY_ABBREV:
                emit_line(o, "", "", " ...\n", strlen(" ...\n"));
                break;
+       case DIFF_SYMBOL_WORD_DIFF:
+               fprintf(o->file, "%.*s", len, line);
+               break;
        default:
                die("BUG: unknown diff symbol");
        }
@@ -1092,37 +1096,49 @@ struct diff_words_data {
        struct diff_words_style *style;
 };
 
-static int fn_out_diff_words_write_helper(FILE *fp,
+static int fn_out_diff_words_write_helper(struct diff_options *o,
                                          struct diff_words_style_elem *st_el,
                                          const char *newline,
-                                         size_t count, const char *buf,
-                                         const char *line_prefix)
+                                         size_t count, const char *buf)
 {
        int print = 0;
+       struct strbuf sb = STRBUF_INIT;
 
        while (count) {
                char *p = memchr(buf, '\n', count);
                if (print)
-                       fputs(line_prefix, fp);
+                       strbuf_addstr(&sb, diff_line_prefix(o));
+
                if (p != buf) {
-                       if (st_el->color && fputs(st_el->color, fp) < 0)
-                               return -1;
-                       if (fputs(st_el->prefix, fp) < 0 ||
-                           fwrite(buf, p ? p - buf : count, 1, fp) != 1 ||
-                           fputs(st_el->suffix, fp) < 0)
-                               return -1;
-                       if (st_el->color && *st_el->color
-                           && fputs(GIT_COLOR_RESET, fp) < 0)
-                               return -1;
+                       const char *reset = st_el->color && *st_el->color ?
+                                           GIT_COLOR_RESET : NULL;
+                       if (st_el->color && *st_el->color)
+                               strbuf_addstr(&sb, st_el->color);
+                       strbuf_addstr(&sb, st_el->prefix);
+                       strbuf_add(&sb, buf, p ? p - buf : count);
+                       strbuf_addstr(&sb, st_el->suffix);
+                       if (reset)
+                               strbuf_addstr(&sb, reset);
                }
                if (!p)
-                       return 0;
-               if (fputs(newline, fp) < 0)
-                       return -1;
+                       goto out;
+
+               strbuf_addstr(&sb, newline);
                count -= p + 1 - buf;
                buf = p + 1;
                print = 1;
+               if (count) {
+                       emit_diff_symbol(o, DIFF_SYMBOL_WORD_DIFF,
+                                        sb.buf, sb.len, 0);
+                       strbuf_reset(&sb);
+               }
        }
+
+out:
+       if (sb.len)
+               emit_diff_symbol(o, DIFF_SYMBOL_WORD_DIFF,
+                                sb.buf, sb.len, 0);
+       strbuf_release(&sb);
        return 0;
 }
 
@@ -1204,24 +1220,20 @@ static void fn_out_diff_words_aux(void *priv, char 
*line, unsigned long len)
                fputs(line_prefix, diff_words->opt->file);
        }
        if (diff_words->current_plus != plus_begin) {
-               fn_out_diff_words_write_helper(diff_words->opt->file,
+               fn_out_diff_words_write_helper(diff_words->opt,
                                &style->ctx, style->newline,
                                plus_begin - diff_words->current_plus,
-                               diff_words->current_plus, line_prefix);
-               if (*(plus_begin - 1) == '\n')
-                       fputs(line_prefix, diff_words->opt->file);
+                               diff_words->current_plus);
        }
        if (minus_begin != minus_end) {
-               fn_out_diff_words_write_helper(diff_words->opt->file,
+               fn_out_diff_words_write_helper(diff_words->opt,
                                &style->old, style->newline,
-                               minus_end - minus_begin, minus_begin,
-                               line_prefix);
+                               minus_end - minus_begin, minus_begin);
        }
        if (plus_begin != plus_end) {
-               fn_out_diff_words_write_helper(diff_words->opt->file,
+               fn_out_diff_words_write_helper(diff_words->opt,
                                &style->new, style->newline,
-                               plus_end - plus_begin, plus_begin,
-                               line_prefix);
+                               plus_end - plus_begin, plus_begin);
        }
 
        diff_words->current_plus = plus_end;
@@ -1315,11 +1327,12 @@ static void diff_words_show(struct diff_words_data 
*diff_words)
 
        /* special case: only removal */
        if (!diff_words->plus.text.size) {
-               fputs(line_prefix, diff_words->opt->file);
-               fn_out_diff_words_write_helper(diff_words->opt->file,
+               emit_diff_symbol(diff_words->opt, DIFF_SYMBOL_WORD_DIFF,
+                                line_prefix, strlen(line_prefix), 0);
+               fn_out_diff_words_write_helper(diff_words->opt,
                        &style->old, style->newline,
                        diff_words->minus.text.size,
-                       diff_words->minus.text.ptr, line_prefix);
+                       diff_words->minus.text.ptr);
                diff_words->minus.text.size = 0;
                return;
        }
@@ -1342,12 +1355,12 @@ static void diff_words_show(struct diff_words_data 
*diff_words)
        if (diff_words->current_plus != diff_words->plus.text.ptr +
                        diff_words->plus.text.size) {
                if (color_words_output_graph_prefix(diff_words))
-                       fputs(line_prefix, diff_words->opt->file);
-               fn_out_diff_words_write_helper(diff_words->opt->file,
+                       emit_diff_symbol(diff_words->opt, DIFF_SYMBOL_WORD_DIFF,
+                                        line_prefix, strlen(line_prefix), 0);
+               fn_out_diff_words_write_helper(diff_words->opt,
                        &style->ctx, style->newline,
                        diff_words->plus.text.ptr + diff_words->plus.text.size
-                       - diff_words->current_plus, diff_words->current_plus,
-                       line_prefix);
+                       - diff_words->current_plus, diff_words->current_plus);
        }
        diff_words->minus.text.size = diff_words->plus.text.size = 0;
 }
-- 
2.13.0.31.g9b732c453e

Reply via email to