package builtin import "strings" type DiffOp string const ( DiffEqual DiffOp = "equal" DiffAdd DiffOp = "add" DiffRemove DiffOp = "remove" ) type DiffLine struct { Op DiffOp Text string } // DiffResult ist die strukturierte UI-Repräsentation für write/edit. type DiffResult struct { Path string Lines []DiffLine } // lineDiff berechnet einen minimalen zeilenbasierten Diff via LCS. // Für Datei-großen Input (M1) ausreichend; kein externer Diff-Algorithmus nötig. func lineDiff(oldText, newText string) []DiffLine { oldLines := splitLines(oldText) newLines := splitLines(newText) n, m := len(oldLines), len(newLines) lcs := make([][]int, n+1) for i := range lcs { lcs[i] = make([]int, m+1) } for i := n - 1; i >= 0; i-- { for j := m - 1; j >= 0; j-- { if oldLines[i] == newLines[j] { lcs[i][j] = lcs[i+1][j+1] + 1 } else if lcs[i+1][j] >= lcs[i][j+1] { lcs[i][j] = lcs[i+1][j] } else { lcs[i][j] = lcs[i][j+1] } } } var out []DiffLine i, j := 0, 0 for i < n && j < m { switch { case oldLines[i] == newLines[j]: out = append(out, DiffLine{DiffEqual, oldLines[i]}) i++ j++ case lcs[i+1][j] >= lcs[i][j+1]: out = append(out, DiffLine{DiffRemove, oldLines[i]}) i++ default: out = append(out, DiffLine{DiffAdd, newLines[j]}) j++ } } for ; i < n; i++ { out = append(out, DiffLine{DiffRemove, oldLines[i]}) } for ; j < m; j++ { out = append(out, DiffLine{DiffAdd, newLines[j]}) } return out } func splitLines(s string) []string { if s == "" { return nil } return strings.Split(s, "\n") }