### Edit Type Definition and Examples Source: https://context7.com/akedrou/textdiff/llms.txt Demonstrates the core `Edit` struct, used to represent text replacements. Shows examples of creating edits for replacement, insertion, and deletion. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { e := diff.Edit{Start: 4, End: 9, New: "world"} fmt.Println(e) // {Start:4,End:9,New:"world"} // Insertion (Start == End): inserts "Go " at position 0 ins := diff.Edit{Start: 0, End: 0, New: "Go "} fmt.Println(ins) // {Start:0,End:0,New:"Go "} // Deletion (New == ""): removes bytes 0–3 del := diff.Edit{Start: 0, End: 3, New: ""} fmt.Println(del) // {Start:0,End:3,New:""} } ``` -------------------------------- ### SortEdits - Sort a Slice of Edits Source: https://context7.com/akedrou/textdiff/llms.txt Sorts a slice of edits by (Start, End) offset using a stable sort. Insertions at the same position are ordered before deletions, and multiple insertions preserve their original relative order. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { edits := []diff.Edit{ {Start: 10, End: 15, New: "world"}, {Start: 0, End: 0, New: "/*header*/\n"}, {Start: 0, End: 5, New: "Hello"}, } diff.SortEdits(edits) for _, e := range edits { fmt.Println(e) } // {Start:0,End:0,New:"/*header*/\n"} ← insertion before deletion at same pos // {Start:0,End:5,New:"Hello"} // {Start:10,End:15,New:"world"} } ``` -------------------------------- ### SortEdits Source: https://context7.com/akedrou/textdiff/llms.txt Sorts a slice of edits by (Start, End) offset using a stable sort. Insertions at the same position are ordered before deletions, and multiple insertions preserve their original relative order. ```APIDOC ## SortEdits — Sort an Edit Slice In Place `SortEdits(edits []Edit)` sorts a slice of edits by `(Start, End)` offset using a stable sort. Insertions (where `End == Start`) at the same position are ordered before deletions, and multiple insertions at the same point preserve their original relative order. ### Function Signature `func SortEdits(edits []Edit)` ### Parameters - **edits** ([]Edit) - The slice of edits to be sorted in place. ``` -------------------------------- ### Edit Type Source: https://context7.com/akedrou/textdiff/llms.txt The Edit type represents a single replacement in a text buffer, specifying a byte range to remove and a new string to insert. Insertions have Start == End, and deletions have New == "". ```APIDOC ## Edit Type `Edit` is the core data type representing a single replacement in a text buffer. It specifies a byte range `[Start, End)` to remove and a `New` string to insert in its place. An insertion has `Start == End`; a deletion has `New == ""`. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { e := diff.Edit{Start: 4, End: 9, New: "world"} fmt.Println(e) // {Start:4,End:9,New:"world"} // Insertion (Start == End): inserts "Go " at position 0 ins := diff.Edit{Start: 0, End: 0, New: "Go "} fmt.Println(ins) // {Start:0,End:0,New:"Go "} // Deletion (New == ""): removes bytes 0–3 del := diff.Edit{Start: 0, End: 3, New: ""} fmt.Println(del) // {Start:0,End:3,New:""} } ``` ``` -------------------------------- ### Unified - Generate Unified Diff String Source: https://context7.com/akedrou/textdiff/llms.txt Computes the edit sequence and returns a standard unified diff string with DefaultContextLines (3) lines of context. Returns "" when the strings are equal. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { old := `package main import "fmt" func main() { fmt.Println("hello") } ` new := `package main import "fmt" func main() { fmt.Println("hello, world") } ` fmt.Print(diff.Unified("main.go.orig", "main.go", old, new)) // --- main.go.orig // +++ main.go // @@ -5,4 +5,4 @@ // func main() { // -\tfmt.Println("hello") // + fmt.Println("hello, world") // } } ``` -------------------------------- ### Unified Source: https://context7.com/akedrou/textdiff/llms.txt Generates a standard unified diff string compatible with `patch(1)`. It computes the edit sequence and includes `DefaultContextLines` (3) lines of context. Returns an empty string when the input strings are equal. ```APIDOC ## Unified — Generate a Unified Diff String `Unified(oldLabel, newLabel, old, new string) string` is the high-level convenience function. It computes the edit sequence and returns a standard unified diff string (compatible with `patch(1)`) with `DefaultContextLines` (3) lines of context. Returns `""` when the strings are equal. ### Function Signature `func Unified(oldLabel, newLabel, old, new string) string` ### Parameters - **oldLabel** (string) - The label for the original file. - **newLabel** (string) - The label for the new file. - **old** (string) - The original content. - **new** (string) - The new content. ### Returns - (string) - The unified diff string. ``` -------------------------------- ### Use difftest.DiffTest to Validate Custom Diff Implementations Source: https://context7.com/akedrou/textdiff/llms.txt The difftest.DiffTest function is a reusable test harness for validating diff implementations. It ensures that a custom diff algorithm produces correct round-trip results against a canonical test suite. Use this to verify your own diff logic. ```go package myalgo_test import ( "testing" "github.com/akedrou/textdiff/difftest" diff "github.com/akedrou/textdiff" ) // customDiff is the algorithm under test. func customDiff(before, after string) []diff.Edit { return diff.Strings(before, after) // swap in your own implementation } func TestMyAlgorithm(t *testing.T) { difftest.DiffTest(t, customDiff) // Runs ~20 named cases: empty, no_diff, replace_all, insert_rune, // delete_rune, replace_partials, insert_line, replace_no_newline, // delete_empty, append_empty, add_end, add_newline, delete_front, // replace_last_line, multiple_replace, extra_newline, unified_lines, 60379, … } ``` -------------------------------- ### Apply Edits to a Byte Slice Source: https://context7.com/akedrou/textdiff/llms.txt Applies edits to a byte slice, returning a new byte slice. This is the byte-oriented equivalent of `Apply`. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { src := []byte("package main\n") edits := diff.Bytes(src, []byte("package foo\n")) patched, err := diff.ApplyBytes(src, edits) if err != nil { panic(err) } fmt.Printf("%s", patched) // package foo } ``` -------------------------------- ### Compute Edits Between Two Strings Source: https://context7.com/akedrou/textdiff/llms.txt Computes the minimal sequence of edits to transform one string into another. Handles Unicode correctly, respecting rune boundaries. Returns nil for identical strings. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { before := "Hello, world!\n" after := "Hello, Go!\n" edits := diff.Strings(before, after) for _, e := range edits { fmt.Printf("replace [%d:%d] with %q\n", e.Start, e.End, e.New) } // replace [7:12] with "Go" // Unicode example — rune boundaries respected before2 := "café\n" after2 := "cafe\n" edits2 := diff.Strings(before2, after2) for _, e := range edits2 { fmt.Printf("replace [%d:%d] with %q\n", e.Start, e.End, e.New) } // replace [3:5] with "e" (é is 2 bytes, correctly identified) // Identical strings → nil fmt.Println(diff.Strings("same\n", "same\n")) // [] } ``` -------------------------------- ### ApplyBytes — Apply Edits to a Byte Slice Source: https://context7.com/akedrou/textdiff/llms.txt The `ApplyBytes` function is identical to `Apply` but operates on byte slices (`[]byte`), returning a new byte slice or an error. It always allocates a new slice. ```APIDOC ## ApplyBytes — Apply Edits to a Byte Slice `ApplyBytes(src []byte, edits []Edit) ([]byte, error)` is identical to `Apply` but accepts and returns `[]byte`. Always allocates a new slice. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { src := []byte("package main\n") edits := diff.Bytes(src, []byte("package foo\n")) patched, err := diff.ApplyBytes(src, edits) if err != nil { panic(err) } fmt.Printf("%s", patched) // package foo } ``` ``` -------------------------------- ### ToUnified - Unified Diff with Custom Context Lines Source: https://context7.com/akedrou/textdiff/llms.txt Converts a pre-computed edit slice into a unified diff with a configurable number of surrounding context lines. Returns an error if the edits are inconsistent with content. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { before := "A\nB\nC\nD\nE\nF\nG\n" after := "A\nB\nX\nD\nE\nF\nG\n" edits := diff.Strings(before, after) // 1 line of context instead of the default 3 u, err := diff.ToUnified("before.txt", "after.txt", before, edits, 1) if err != nil { panic(err) } fmt.Print(u) // --- before.txt // +++ after.txt // @@ -2,3 +2,3 @@ // B // -C // +X // D // 0 context lines — hunks contain only changed lines u0, _ := diff.ToUnified("before.txt", "after.txt", before, edits, 0) fmt.Print(u0) // --- before.txt // +++ after.txt // @@ -3 +3 @@ // -C // +X } ``` -------------------------------- ### DefaultContextLines Source: https://context7.com/akedrou/textdiff/llms.txt A constant representing the default number of unchanged surrounding lines included in unified diff output. ```APIDOC ## DefaultContextLines Constant `DefaultContextLines = 3` is the number of unchanged surrounding lines included in unified diff output by `Unified`. Pass a different value to `ToUnified` to override it. ### Constant Value `const DefaultContextLines = 3` ``` -------------------------------- ### Apply Edits to a String Source: https://context7.com/akedrou/textdiff/llms.txt Applies a sequence of edits to a source string, returning the modified string. Handles sorting and validation of edits internally. Errors on overlapping edits. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { src := "The quick brown fox\n" edits := []diff.Edit{ {Start: 4, End: 9, New: "slow"}, // "quick" → "slow" {Start: 16, End: 19, New: "cat"}, // "fox" → "cat" } result, err := diff.Apply(src, edits) if err != nil { fmt.Println("error:", err) return } fmt.Print(result) // The slow brown cat // Error: overlapping edits bad := []diff.Edit{ {Start: 0, End: 5, New: "A"}, {Start: 3, End: 8, New: "B"}, } _, err = diff.Apply(src, bad) fmt.Println(err) // diff has overlapping edits } ``` -------------------------------- ### Compute Edits Between Two Byte Slices Source: https://context7.com/akedrou/textdiff/llms.txt Computes edits between two byte slices, useful for file content. Edit offsets are in bytes but respect rune boundaries. ```go package main import ( "fmt" "os" diff "github.com/akedrou/textdiff" ) func main() { before, _ := os.ReadFile("original.go") after, _ := os.ReadFile("modified.go") edits := diff.Bytes(before, after) fmt.Printf("%d edit(s) needed\n", len(edits)) for _, e := range edits { fmt.Printf(" [%d:%d] → %q\n", e.Start, e.End, e.New) } } ``` -------------------------------- ### myers.ComputeEdits Source: https://context7.com/akedrou/textdiff/llms.txt Computes a line-granularity diff using the classic Myers algorithm. This sub-package is deprecated and exists solely for backwards compatibility. New code should use `diff.Strings`. ```APIDOC ## myers.ComputeEdits — Legacy Myers Line-Based Diff (Deprecated) `myers.ComputeEdits(before, after string) []diff.Edit` computes a line-granularity diff using the classic Myers algorithm. This sub-package is **deprecated** — it exists solely for backwards compatibility with golden-test suites that assert exact diff output. New code should use `diff.Strings`. ### Function Signature `func ComputeEdits(before, after string) []diff.Edit` ### Parameters - **before** (string) - The original string. - **after** (string) - The new string. ### Returns - ([]diff.Edit) - A slice of edits representing the differences. ``` -------------------------------- ### myers.ComputeEdits - Legacy Myers Diff Source: https://context7.com/akedrou/textdiff/llms.txt Computes a line-granularity diff using the classic Myers algorithm. This sub-package is deprecated and exists solely for backwards compatibility. New code should use diff.Strings. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" "github.com/akedrou/textdiff/myers" ) func main() { before := "line1\nline2\nline3\n" after := "line1\nLINE2\nline3\n" // Legacy Myers edits (line-granularity) edits := myers.ComputeEdits(before, after) result, err := diff.Apply(before, edits) if err != nil { panic(err) } fmt.Print(result) // line1\nLINE2\nline3\n u, _ := diff.ToUnified("before", "after", before, edits, diff.DefaultContextLines) fmt.Print(u) // --- before // +++ after // @@ -1,3 +1,3 @@ // line1 // -line2 // +LINE2 // line3 } ``` -------------------------------- ### DefaultContextLines Constant Source: https://context7.com/akedrou/textdiff/llms.txt The default number of unchanged surrounding lines included in unified diff output by Unified. Pass a different value to ToUnified to override it. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { fmt.Println(diff.DefaultContextLines) // 3 } ``` -------------------------------- ### Bytes — Compute Edits Between Two Byte Slices Source: https://context7.com/akedrou/textdiff/llms.txt The `Bytes` function is the byte-slice counterpart to `Strings`, useful for computing differences when content is already in `[]byte` form. Edit offsets are in bytes and respect rune boundaries. ```APIDOC ## Bytes — Compute Edits Between Two Byte Slices `Bytes(before, after []byte) []Edit` is the byte-slice counterpart to `Strings`. Useful when content is already in `[]byte` form (e.g., file reads). Edit offsets are still in bytes and respect rune boundaries. ```go package main import ( "fmt" "os" diff "github.com/akedrou/textdiff" ) func main() { before, _ := os.ReadFile("original.go") after, _ := os.ReadFile("modified.go") edits := diff.Bytes(before, after) fmt.Printf("%d edit(s) needed\n", len(edits)) for _, e := range edits { fmt.Printf(" [%d:%d] → %q\n", e.Start, e.End, e.New) } } ``` ``` -------------------------------- ### Apply — Apply Edits to a String Source: https://context7.com/akedrou/textdiff/llms.txt The `Apply` function applies a sequence of edits to a source string, returning the modified string or an error if edits are out-of-bounds or overlapping. Edits are sorted internally. ```APIDOC ## Apply — Apply Edits to a String `Apply(src string, edits []Edit) (string, error)` applies a sorted, non-overlapping sequence of edits to `src` and returns the result. Returns an error for out-of-bounds or overlapping edits. Edits need not be pre-sorted — `Apply` sorts them internally. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { src := "The quick brown fox\n" edits := []diff.Edit{ {Start: 4, End: 9, New: "slow"}, // "quick" → "slow" {Start: 16, End: 19, New: "cat"}, // "fox" → "cat" } result, err := diff.Apply(src, edits) if err != nil { fmt.Println("error:", err) return } fmt.Print(result) // The slow brown cat // Error: overlapping edits bad := []diff.Edit{ {Start: 0, End: 5, New: "A"}, {Start: 3, End: 8, New: "B"}, } _, err = diff.Apply(src, bad) fmt.Println(err) // diff has overlapping edits } ``` ``` -------------------------------- ### ToUnified Source: https://context7.com/akedrou/textdiff/llms.txt Converts a pre-computed edit slice into a unified diff with a configurable number of surrounding context lines. Returns an error if the edits are inconsistent with the provided content. ```APIDOC ## ToUnified — Generate a Unified Diff with Custom Context Lines `ToUnified(oldLabel, newLabel, content string, edits []Edit, contextLines int) (string, error)` converts a pre-computed edit slice into a unified diff with a configurable number of surrounding context lines. Returns an error if the edits are inconsistent with `content`. ### Function Signature `func ToUnified(oldLabel, newLabel, content string, edits []Edit, contextLines int) (string, error)` ### Parameters - **oldLabel** (string) - The label for the original file. - **newLabel** (string) - The label for the new file. - **content** (string) - The original content against which edits are applied. - **edits** ([]Edit) - The pre-computed slice of edits. - **contextLines** (int) - The number of context lines to include around changes. ### Returns - (string) - The unified diff string. - (error) - An error if the edits are inconsistent with the content. ``` -------------------------------- ### Strings — Compute Edits Between Two Strings Source: https://context7.com/akedrou/textdiff/llms.txt The `Strings` function computes the minimal sequence of edits needed to transform one string into another. It handles Unicode correctly and returns nil for identical strings. ```APIDOC ## Strings — Compute Edits Between Two Strings `Strings(before, after string) []Edit` computes the minimal sequence of edits needed to transform `before` into `after`. Returns `nil` when the strings are equal. Edit boundaries always respect rune (Unicode code point) boundaries. ```go package main import ( "fmt" diff "github.com/akedrou/textdiff" ) func main() { before := "Hello, world!\n" after := "Hello, Go!\n" edits := diff.Strings(before, after) for _, e := range edits { fmt.Printf("replace [%d:%d] with %q\n", e.Start, e.End, e.New) } // replace [7:12] with "Go" // Unicode example — rune boundaries respected before2 := "café\n" after2 := "cafe\n" edits2 := diff.Strings(before2, after2) for _, e := range edits2 { fmt.Printf("replace [%d:%d] with %q\n", e.Start, e.End, e.New) } // replace [3:5] with "e" (é is 2 bytes, correctly identified) // Identical strings → nil fmt.Println(diff.Strings("same\n", "same\n")) // [] } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.