WriteUnifiedDiff compares two sequences of lines and generates the delta as a unified diff. Unified diffs are a compact way of showing line changes and a few lines of context. The number of context lines is set by 'n' which defaults to three. By default, the diff control lines (those with ---, ++
(writer io.Writer, diff LineDiffParams)
| 817 | // 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. |
| 818 | // The modification times are normally expressed in the ISO 8601 format. |
| 819 | func WriteUnifiedDiff(writer io.Writer, diff LineDiffParams) error { |
| 820 | //buf := bufio.NewWriter(writer) |
| 821 | //defer buf.Flush() |
| 822 | var bld strings.Builder |
| 823 | bld.Reset() |
| 824 | wf := func(format string, args ...any) error { |
| 825 | _, err := fmt.Fprintf(&bld, format, args...) |
| 826 | return err |
| 827 | } |
| 828 | ws := func(s string) error { |
| 829 | _, err := bld.WriteString(s) |
| 830 | return err |
| 831 | } |
| 832 | |
| 833 | if len(diff.Eol) == 0 { |
| 834 | diff.Eol = "\n" |
| 835 | } |
| 836 | |
| 837 | started := false |
| 838 | m := NewMatcher(diff.A, diff.B) |
| 839 | if diff.AutoJunk || diff.IsJunkLine != nil { |
| 840 | m = NewMatcherWithJunk(diff.A, diff.B, diff.AutoJunk, diff.IsJunkLine) |
| 841 | } |
| 842 | for _, g := range m.GetGroupedOpCodes(diff.Context) { |
| 843 | if !started { |
| 844 | started = true |
| 845 | fromDate := "" |
| 846 | if len(diff.FromDate) > 0 { |
| 847 | fromDate = "\t" + diff.FromDate |
| 848 | } |
| 849 | toDate := "" |
| 850 | if len(diff.ToDate) > 0 { |
| 851 | toDate = "\t" + diff.ToDate |
| 852 | } |
| 853 | if diff.FromFile != "" || diff.ToFile != "" { |
| 854 | err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) |
| 855 | if err != nil { |
| 856 | return err |
| 857 | } |
| 858 | err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) |
| 859 | if err != nil { |
| 860 | return err |
| 861 | } |
| 862 | } |
| 863 | } |
| 864 | first, last := g[0], g[len(g)-1] |
| 865 | range1 := formatRangeUnified(first.I1, last.I2) |
| 866 | range2 := formatRangeUnified(first.J1, last.J2) |
| 867 | if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { |
| 868 | return err |
| 869 | } |
| 870 | for _, c := range g { |
| 871 | i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 |
| 872 | if c.Tag == 'e' { |
| 873 | for _, line := range diff.A[i1:i2] { |
| 874 | if err := ws(" " + line); err != nil { |
| 875 | return err |
| 876 | } |
no test coverage detected