diff src/diff.c @ 14762:b43ea03bb522 v8.1.0393

patch 8.1.0393: not all white space difference options available commit https://github.com/vim/vim/commit/785fc6567f572b8caefbc89ec29bbd8b801464ae Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 15 19:17:38 2018 +0200 patch 8.1.0393: not all white space difference options available Problem: Not all white space difference options available. Solution: Add "iblank", "iwhiteall" and "iwhiteeol" to 'diffopt'.
author Christian Brabandt <cb@256bit.org>
date Sat, 15 Sep 2018 19:30:06 +0200
parents 193471015e1a
children f562b9fbd0d3
line wrap: on
line diff
--- a/src/diff.c
+++ b/src/diff.c
@@ -24,13 +24,17 @@
 static int	diff_busy = FALSE;	/* ex_diffgetput() is busy */
 
 /* flags obtained from the 'diffopt' option */
-#define DIFF_FILLER	1	// display filler lines
-#define DIFF_ICASE	2	// ignore case
-#define DIFF_IWHITE	4	// ignore change in white space
-#define DIFF_HORIZONTAL	8	// horizontal splits
-#define DIFF_VERTICAL	16	// vertical splits
-#define DIFF_HIDDEN_OFF	32	// diffoff when hidden
-#define DIFF_INTERNAL	64	// use internal xdiff algorithm
+#define DIFF_FILLER	0x001	// display filler lines
+#define DIFF_IBLANK	0x002	// ignore empty lines
+#define DIFF_ICASE	0x004	// ignore case
+#define DIFF_IWHITE	0x008	// ignore change in white space
+#define DIFF_IWHITEALL	0x010	// ignore all white space changes
+#define DIFF_IWHITEEOL	0x020	// ignore change in white space at EOL
+#define DIFF_HORIZONTAL	0x040	// horizontal splits
+#define DIFF_VERTICAL	0x080	// vertical splits
+#define DIFF_HIDDEN_OFF	0x100	// diffoff when hidden
+#define DIFF_INTERNAL	0x200	// use internal xdiff algorithm
+#define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL)
 static int	diff_flags = DIFF_INTERNAL | DIFF_FILLER;
 
 static long diff_algorithm = 0;
@@ -1050,6 +1054,12 @@ diff_file_internal(diffio_T *diffio)
 
     if (diff_flags & DIFF_IWHITE)
 	param.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+    if (diff_flags & DIFF_IWHITEALL)
+	param.flags |= XDF_IGNORE_WHITESPACE;
+    if (diff_flags & DIFF_IWHITEEOL)
+	param.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+    if (diff_flags & DIFF_IBLANK)
+	param.flags |= XDF_IGNORE_BLANK_LINES;
 
     emit_cfg.ctxlen = 0; // don't need any diff_context here
     emit_cb.priv = &diffio->dio_diff;
@@ -1106,7 +1116,7 @@ diff_file(diffio_T *dio)
 	// Build the diff command and execute it.  Always use -a, binary
 	// differences are of no use.  Ignore errors, diff returns
 	// non-zero when differences have been found.
-	vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s %s",
+	vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s",
 		diff_a_works == FALSE ? "" : "-a ",
 #if defined(MSWIN)
 		diff_bin_works == TRUE ? "--binary " : "",
@@ -1114,6 +1124,9 @@ diff_file(diffio_T *dio)
 		"",
 #endif
 		(diff_flags & DIFF_IWHITE) ? "-b " : "",
+		(diff_flags & DIFF_IWHITEALL) ? "-w " : "",
+		(diff_flags & DIFF_IWHITEEOL) ? "-Z " : "",
+		(diff_flags & DIFF_IBLANK) ? "-B " : "",
 		(diff_flags & DIFF_ICASE) ? "-i " : "",
 		tmp_orig, tmp_new);
 	append_redir(cmd, (int)len, p_srr, tmp_diff);
@@ -1946,17 +1959,25 @@ diff_cmp(char_u *s1, char_u *s2)
     char_u	*p1, *p2;
     int		l;
 
-    if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0)
+    if ((diff_flags & DIFF_IBLANK)
+	    && (*skipwhite(s1) == NUL || *skipwhite(s2) == NUL))
+	return 0;
+
+    if ((diff_flags & (DIFF_ICASE | ALL_WHITE_DIFF)) == 0)
 	return STRCMP(s1, s2);
-    if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE))
+    if ((diff_flags & DIFF_ICASE) && !(diff_flags & ALL_WHITE_DIFF))
 	return MB_STRICMP(s1, s2);
 
-    /* Ignore white space changes and possibly ignore case. */
     p1 = s1;
     p2 = s2;
+
+    // Ignore white space changes and possibly ignore case.
     while (*p1 != NUL && *p2 != NUL)
     {
-	if (VIM_ISWHITE(*p1) && VIM_ISWHITE(*p2))
+	if (((diff_flags & DIFF_IWHITE)
+		    && VIM_ISWHITE(*p1) && VIM_ISWHITE(*p2))
+		|| ((diff_flags & DIFF_IWHITEALL)
+		    && (VIM_ISWHITE(*p1) || VIM_ISWHITE(*p2))))
 	{
 	    p1 = skipwhite(p1);
 	    p2 = skipwhite(p2);
@@ -1970,7 +1991,7 @@ diff_cmp(char_u *s1, char_u *s2)
 	}
     }
 
-    /* Ignore trailing white space. */
+    // Ignore trailing white space.
     p1 = skipwhite(p1);
     p2 = skipwhite(p2);
     if (*p1 != NUL || *p2 != NUL)
@@ -2142,11 +2163,26 @@ diffopt_changed(void)
 	    p += 8;
 	    diff_context_new = getdigits(&p);
 	}
+	else if (STRNCMP(p, "iblank", 6) == 0)
+	{
+	    p += 6;
+	    diff_flags_new |= DIFF_IBLANK;
+	}
 	else if (STRNCMP(p, "icase", 5) == 0)
 	{
 	    p += 5;
 	    diff_flags_new |= DIFF_ICASE;
 	}
+	else if (STRNCMP(p, "iwhiteall", 9) == 0)
+	{
+	    p += 9;
+	    diff_flags_new |= DIFF_IWHITEALL;
+	}
+	else if (STRNCMP(p, "iwhiteeol", 9) == 0)
+	{
+	    p += 9;
+	    diff_flags_new |= DIFF_IWHITEEOL;
+	}
 	else if (STRNCMP(p, "iwhite", 6) == 0)
 	{
 	    p += 6;
@@ -2315,9 +2351,12 @@ diff_find_change(
 	    si_org = si_new = 0;
 	    while (line_org[si_org] != NUL)
 	    {
-		if ((diff_flags & DIFF_IWHITE)
-			&& VIM_ISWHITE(line_org[si_org])
-			&& VIM_ISWHITE(line_new[si_new]))
+		if (((diff_flags & DIFF_IWHITE)
+			    && VIM_ISWHITE(line_org[si_org])
+					      && VIM_ISWHITE(line_new[si_new]))
+			|| ((diff_flags & DIFF_IWHITEALL)
+			    && (VIM_ISWHITE(line_org[si_org])
+					    || VIM_ISWHITE(line_new[si_new]))))
 		{
 		    si_org = (int)(skipwhite(line_org + si_org) - line_org);
 		    si_new = (int)(skipwhite(line_new + si_new) - line_new);
@@ -2351,9 +2390,12 @@ diff_find_change(
 		while (ei_org >= *startp && ei_new >= si_new
 						&& ei_org >= 0 && ei_new >= 0)
 		{
-		    if ((diff_flags & DIFF_IWHITE)
-			    && VIM_ISWHITE(line_org[ei_org])
-			    && VIM_ISWHITE(line_new[ei_new]))
+		    if (((diff_flags & DIFF_IWHITE)
+				&& VIM_ISWHITE(line_org[ei_org])
+					      && VIM_ISWHITE(line_new[ei_new]))
+			    || ((diff_flags & DIFF_IWHITEALL)
+				&& (VIM_ISWHITE(line_org[ei_org])
+					    || VIM_ISWHITE(line_new[ei_new]))))
 		    {
 			while (ei_org >= *startp
 					     && VIM_ISWHITE(line_org[ei_org]))