| | @@ -69,11 +69,11 @@ |
| 69 | 69 | struct DLine { |
| 70 | 70 | const char *z; /* The text of the line */ |
| 71 | 71 | unsigned int h; /* Hash of the line */ |
| 72 | 72 | unsigned int iNext; /* 1+(Index of next line with same the same hash) */ |
| 73 | 73 | |
| 74 | | - /* an array of DLine elements services two purposes. The fields |
| 74 | + /* an array of DLine elements serves two purposes. The fields |
| 75 | 75 | ** above are one per line of input text. But each entry is also |
| 76 | 76 | ** a bucket in a hash table, as follows: */ |
| 77 | 77 | unsigned int iHash; /* 1+(first entry in the hash chain) */ |
| 78 | 78 | }; |
| 79 | 79 | |
| | @@ -260,11 +260,11 @@ |
| 260 | 260 | if( html ) blob_append(pOut, "</span>", -1); |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | |
| 264 | 264 | /* |
| 265 | | -** Given a diff context in which the aEdit[] array has been filled |
| 265 | +** Given a raw diff p[] in which the p->aEdit[] array has been filled |
| 266 | 266 | ** in, compute a context diff into pOut. |
| 267 | 267 | */ |
| 268 | 268 | static void contextDiff( |
| 269 | 269 | DContext *p, /* The difference */ |
| 270 | 270 | Blob *pOut, /* Output a context diff to here */ |
| | @@ -643,11 +643,11 @@ |
| 643 | 643 | if( nPrefix+nSuffix==nLeft ){ |
| 644 | 644 | sbsWriteLineno(p, lnLeft); |
| 645 | 645 | p->iStart2 = p->iEnd2 = 0; |
| 646 | 646 | p->iStart = p->iEnd = -1; |
| 647 | 647 | sbsWriteText(p, pLeft, SBS_PAD); |
| 648 | | - sbsWrite(p, " | ", 3); |
| 648 | + sbsWrite(p, nLeft==nRight ? " " : " | ", 3); |
| 649 | 649 | sbsWriteLineno(p, lnRight); |
| 650 | 650 | p->iStart = nPrefix; |
| 651 | 651 | p->iEnd = nRight - nSuffix; |
| 652 | 652 | p->zStart = zClassAdd; |
| 653 | 653 | sbsWriteText(p, pRight, SBS_NEWLINE); |
| | @@ -905,10 +905,20 @@ |
| 905 | 905 | |
| 906 | 906 | /* Return the result */ |
| 907 | 907 | fossil_free(pToFree); |
| 908 | 908 | return aM; |
| 909 | 909 | } |
| 910 | + |
| 911 | +/* |
| 912 | +** R[] is an array of six integer, two COPY/DELETE/INSERT triples for a |
| 913 | +** pair of adjacent differences. Return true if the gap between these |
| 914 | +** two differences is so small that they should be rendered as a single |
| 915 | +** edit. |
| 916 | +*/ |
| 917 | +static int smallGap(int *R){ |
| 918 | + return R[3]<=2 || R[3]<=(R[1]+R[2]+R[4]+R[5])/8; |
| 919 | +} |
| 910 | 920 | |
| 911 | 921 | /* |
| 912 | 922 | ** Given a diff context in which the aEdit[] array has been filled |
| 913 | 923 | ** in, compute a side-by-side diff into pOut. |
| 914 | 924 | */ |
| | @@ -1012,10 +1022,21 @@ |
| 1012 | 1022 | /* Show the differences */ |
| 1013 | 1023 | for(i=0; i<nr; i++){ |
| 1014 | 1024 | unsigned char *alignment; |
| 1015 | 1025 | ma = R[r+i*3+1]; /* Lines on left but not on right */ |
| 1016 | 1026 | mb = R[r+i*3+2]; /* Lines on right but not on left */ |
| 1027 | + |
| 1028 | + /* If the gap between the current diff and then next diff within the |
| 1029 | + ** same block is not too great, then render them as if they are a |
| 1030 | + ** single diff. */ |
| 1031 | + while( i<nr-1 && smallGap(&R[r+i*3]) ){ |
| 1032 | + i++; |
| 1033 | + m = R[r+i*3]; |
| 1034 | + ma += R[r+i*3+1] + m; |
| 1035 | + mb += R[r+i*3+2] + m; |
| 1036 | + } |
| 1037 | + |
| 1017 | 1038 | alignment = sbsAlignment(&A[a], ma, &B[b], mb); |
| 1018 | 1039 | for(j=0; ma+mb>0; j++){ |
| 1019 | 1040 | if( alignment[j]==1 ){ |
| 1020 | 1041 | s.n = 0; |
| 1021 | 1042 | sbsWriteLineno(&s, a); |
| 1022 | 1043 | |