Hi Benjamin!

On Fr, 08 Jun 2012, Benjamin Fritz wrote:

> I've been working on a plugin to provide a manual diff alignment feature,
> similar to KDiff3 or BeyondCompare. The idea is that a human can sometimes
> figure out which lines should be shown side-by-side in a diff than a
> computer can, so we should let them.
> 
> :help diff-diffexpr simply says:
> 
> > The output of "diff" must be a normal "ed" style diff.  Do NOT use a context
> > diff.  This example explains the format that Vim expects: >
> >
> >     1a2
> >     > bbb
> >     4d4
> >     < 111
> >     7c7
> >     < GGG
> >     ---
> >     > ggg
> >
> > The "1a2" item appends the line "bbb".
> > The "4d4" item deletes the line "111".
> > The '7c7" item replaces the line "GGG" with "ggg".
> 
> I took this to mean that any valid ed-style diff can be generated by the
> diffexpr and used by Vim. I assumed that Vim would basically use the hunks
> in the diff to place filler lines and align the text for each buffer. with
> this assumption, my design for the manual alignment was to break each file
> into chunks, write the chunks with writefile(), diff the chunks, and
> combine the output of those diffs into one big diff for diffexpr to
> finally return to Vim (correcting line numbers based on the starting line
> number of the current chunk). For simple diffs, this seems to work fine.
> See the attached diff2_with_alignment.png.
> 
> But, a slightly more complicated example is shown in
> diff_without_alignment.png. This is the view before using the plugin to
> align things; the ed-style diff is attached as orig.patch.
> 
> Using my plugin, the diffexpr can generate the aligned.patch output. I can
> use GNU patch and this patch to transform either file into the other
> without errors. However, Vim displays the diff as shown in
> diff_with_alignment.png. Note that there is no diff filler whatsoever, and
> the highlighting is wrong! This also happens in gvim -N -u NONE -i NONE,
> after sourcing my plugin and running a diff.
> 
> I think I've accidentally uncovered a bug in Vim; or at least, an
> undocumented dependency on a specific diff *algorithm*, not just any old
> ed-style diff format. I spent a few minutes looking at the code in diff.c,
> but it looks like I'll need to spend a couple hours at least just to
> figure out what's going on in there. Any help? Am I doing something wrong?
> 
> Current version of the plugin is attached if you want to play with it and
> generate the diffs yourself, otherwise see the attached diffs and
> screenshots.
> 

How did you generate the aligned.patch file? No matter what I do, for me 
the plugin always generates:

2,7c2,4
< a
< b
< cb
< db
< eb
< f
---
> cc
> dd
> ee

But perhaps, I'm using your plugin wrongly, e.g. how many alignemnt 
points do I have to set and where? But even after I manually copied the 
aligned.patch file over the resulting file, Vim still gets the alignment 
wrong.

BTW: attached is a patch, that prevents the use of using diffexpr for 
checking if diff really works (using the "line1" vs. "line2" check):

regards,
Christian

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff --git a/src/diff.c b/src/diff.c
--- a/src/diff.c
+++ b/src/diff.c
@@ -42,7 +42,7 @@
 static int diff_check_sanity __ARGS((tabpage_T *tp, diff_T *dp));
 static void diff_redraw __ARGS((int dofold));
 static int diff_write __ARGS((buf_T *buf, char_u *fname));
-static void diff_file __ARGS((char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff));
+static void diff_file __ARGS((char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff, int doit));
 static int diff_equal_entry __ARGS((diff_T *dp, int idx1, int idx2));
 static int diff_cmp __ARGS((char_u *s1, char_u *s2));
 #ifdef FEAT_FOLDING
@@ -716,7 +716,7 @@
 		if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1)
 		    io_error = TRUE;
 		fclose(fd);
-		diff_file(tmp_orig, tmp_new, tmp_diff);
+		diff_file(tmp_orig, tmp_new, tmp_diff, FALSE);
 		fd = mch_fopen((char *)tmp_diff, "r");
 		if (fd == NULL)
 		    io_error = TRUE;
@@ -805,7 +805,7 @@
 	    continue;
 	if (diff_write(buf, tmp_new) == FAIL)
 	    continue;
-	diff_file(tmp_orig, tmp_new, tmp_diff);
+	diff_file(tmp_orig, tmp_new, tmp_diff, TRUE);
 
 	/* Read the diff output and add each entry to the diff list. */
 	diff_read(idx_orig, idx_new, tmp_diff);
@@ -829,16 +829,17 @@
  * Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
  */
     static void
-diff_file(tmp_orig, tmp_new, tmp_diff)
+diff_file(tmp_orig, tmp_new, tmp_diff, doit)
     char_u	*tmp_orig;
     char_u	*tmp_new;
     char_u	*tmp_diff;
+    int         doit; /* FALSE, when checking diff works, TRUE when really using a diff */
 {
     char_u	*cmd;
     size_t	len;
 
 #ifdef FEAT_EVAL
-    if (*p_dex != NUL)
+    if (*p_dex != NUL && doit)
 	/* Use 'diffexpr' to generate the diff file. */
 	eval_diff(tmp_orig, tmp_new, tmp_diff);
     else

Raspunde prin e-mail lui