From eff7f6d9b1946fd09fbe1a4ad87ecbda2fb224f5 Mon Sep 17 00:00:00 2001 From: Eyal Posener Date: Thu, 8 Aug 2019 20:29:48 +0300 Subject: [PATCH] Add OptSuppressCommon Add option that supresses common lines. --- diff.go | 36 ++++++++++++++++++++++++++++++++---- diff_test.go | 45 ++++++++++++++++++++++++++++++--------------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/diff.go b/diff.go index 65e9111..2130201 100644 --- a/diff.go +++ b/diff.go @@ -10,12 +10,29 @@ import ( "strings" ) +type config struct { + suppressCommon bool +} + +type option func(*config) + +// OptSuppressCommon suppresses common lines. +func OptSuppressCommon() option { + return func(c *config) { + c.suppressCommon = true + } +} + // Format returns a formatted diff of the two texts, // showing the entire text and the minimum line-level // additions and removals to turn text1 into text2. // (That is, lines only in text1 appear with a leading -, // and lines only in text2 appear with a leading +.) -func Format(text1, text2 string) string { +func Format(text1, text2 string, options ...option) string { + var c config + for _, option := range options { + option(&c) + } if text1 != "" && !strings.HasSuffix(text1, "\n") { text1 += "(missing final newline)" } @@ -64,14 +81,25 @@ func Format(text1, text2 string) string { for i > 0 || j > 0 { cost := dist[i][j] if i > 0 && j > 0 && cost == dist[i-1][j-1] && lines1[len(lines1)-i] == lines2[len(lines2)-j] { - fmt.Fprintf(&buf, " %s\n", lines1[len(lines1)-i]) + if !c.suppressCommon { + k := len(lines1) - i + fmt.Fprintf(&buf, " %s\n", lines1[k]) + } i-- j-- } else if i > 0 && cost == dist[i-1][j]+1 { - fmt.Fprintf(&buf, "-%s\n", lines1[len(lines1)-i]) + k := len(lines1) - i + if c.suppressCommon { + fmt.Fprint(&buf, k+1) + } + fmt.Fprintf(&buf, "-%s\n", lines1[k]) i-- } else { - fmt.Fprintf(&buf, "+%s\n", lines2[len(lines2)-j]) + k := len(lines2) - j + if c.suppressCommon { + fmt.Fprint(&buf, k+1) + } + fmt.Fprintf(&buf, "+%s\n", lines2[k]) j-- } } diff --git a/diff_test.go b/diff_test.go index 7b803fb..2a4b7fa 100644 --- a/diff_test.go +++ b/diff_test.go @@ -10,16 +10,17 @@ import ( ) var formatTests = []struct { - text1 string - text2 string - diff string + text1 string + text2 string + diff string + suppressCommon string }{ - {"a b c", "a b d e f", "a b -c +d +e +f"}, - {"", "a b c", "+a +b +c"}, - {"a b c", "", "-a -b -c"}, - {"a b c", "d e f", "-a -b -c +d +e +f"}, - {"a b c d e f", "a b d e f", "a b -c d e f"}, - {"a b c e f", "a b c d e f", "a b c +d e f"}, + {"a b c", "a b d e f", "a b -c +d +e +f", "3-c 3+d 4+e 5+f"}, + {"", "a b c", "+a +b +c", "1+a 2+b 3+c"}, + {"a b c", "", "-a -b -c", "1-a 2-b 3-c"}, + {"a b c", "d e f", "-a -b -c +d +e +f", "1-a 2-b 3-c 1+d 2+e 3+f"}, + {"a b c d e f", "a b d e f", "a b -c d e f", "3-c"}, + {"a b c e f", "a b c d e f", "a b c +d e f", "4+d"}, } func TestFormat(t *testing.T) { @@ -33,11 +34,25 @@ func TestFormat(t *testing.T) { if text2 != "" { text2 += "\n" } - out := Format(text1, text2) - // Cut final \n, cut spaces, turn remaining \n into spaces. - out = strings.ReplaceAll(strings.ReplaceAll(strings.TrimSuffix(out, "\n"), " ", ""), "\n", " ") - if out != tt.diff { - t.Errorf("diff(%q, %q) = %q, want %q", text1, text2, out, tt.diff) - } + compare(t, format, text1, text2, tt.diff) + compare(t, suppressCommon, text1, text2, tt.suppressCommon) + } +} + +func format(text1, text2 string) string { + return Format(text1, text2) +} + +func suppressCommon(text1, text2 string) string { + return Format(text1, text2, OptSuppressCommon()) +} + +func compare(t *testing.T, testFn func(string, string) string, text1, text2 string, want string) { + t.Helper() + got := testFn(text1, text2) + // Cut final \n, cut spaces, turn remaining \n into spaces. + got = strings.ReplaceAll(strings.ReplaceAll(strings.TrimSuffix(got, "\n"), " ", ""), "\n", " ") + if got != want { + t.Errorf("diff(%q, %q) = %q, want %q", text1, text2, got, want) } }