diff

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 4 Imported by: 0

README

unidiff

A small, dependency-free Go library that produces and parses unified diffs.

unidiff is an independent implementation of Myers' O(ND) difference algorithm (Eugene Myers, "An O(ND) Difference Algorithm and Its Variations", 1986) followed by a change-compaction pass, written from the published algorithms. It depends on nothing but the standard library.

Features

  • Unified(old, new string, contextLines int) string — generate unified diff hunk bodies (@@ headers and +/-/space lines) between two strings; returns "" when they match. Handles the \ No newline at end of file marker for unterminated final lines.
  • Parse(unified string) []Line — the inverse of Unified: classify each row (LineContext, LineAdd, LineDel, LineHunk, LineMeta, LineNoNewline) and attach 1-based file line numbers, so a renderer never has to know the @@/+/- syntax.
  • WordSplit(oldStr, newStr string) (prefix, oldMid, newMid, suffix string) — decompose a changed line pair into shared prefix, the differing middle on each side, and shared suffix, for GitHub-style word-level highlighting. Operates on runes so multibyte characters are never split.

Example

diff := unidiff.Unified("alpha\nbeta\ngamma\n", "alpha\nBETA\ngamma\n", 1)
// @@ -1,3 +1,3 @@
//  alpha
// -beta
// +BETA
//  gamma

Correctness

The output is verified byte-for-byte against git diff --no-index over a suite of adversarial inputs (see gitoracle_test.go), and every change-group compaction choice is covered by invariant tests. The implementation never panics, even on pathological inputs.

License

MIT

Documentation

Overview

Package diff produces and parses unified diffs.

The engine is an independent implementation of Myers' O(ND) algorithm (Eugene Myers, "An O(ND) Difference Algorithm and Its Variations", 1986) followed by a change-compaction pass, written from the published algorithms rather than derived from any existing implementation. git is used as the reference for OUTPUT, not for code: gitoracle_test.go diffs the same inputs with the installed git and compares byte for byte.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Unified

func Unified(oldStr, newStr string, contextLines int) string

Unified returns a unified diff of oldStr against newStr with contextLines of context, or "" when they match.

Output is the hunk bodies only — "@@" headers and +/-/space lines — with no "diff --git" or "---"/"+++" preamble, since callers here render the result rather than feeding it to patch.

Word-level highlighting inside a changed pair is the caller's business; see WordSplit.

func WordSplit

func WordSplit(oldStr, newStr string) (prefix, oldMid, newMid, suffix string)

WordSplit decomposes a changed line pair (the bare text of a "-old"/"+new" diff row, without the marker) into the shared leading text, the differing middle on each side, and the shared trailing text. It is the basis for a GitHub-style inline (word-level) highlight: render prefix/suffix in the plain add/del color and oldMid/newMid in the deeper "changed" color.

The split is computed on runes, so a multibyte character (e.g. "↑", which shares leading bytes with "↓"/"→") is never cut mid-rune into orphaned bytes. prefix and suffix are shared by both sides by construction.

Types

type Line

type Line struct {
	Kind  LineKind
	Text  string
	OldNo int
	NewNo int
}

Line is one parsed unified-diff line: its kind, the raw text (including the leading +/-/space marker), and the 1-based file line numbers it maps to (0 when not applicable — e.g. NewNo on a deletion, both on a hunk header).

func Parse

func Parse(unified string) []Line

Parse turns unified-diff text (as produced by Unified) into classified, line-numbered Line values. It is the inverse of the format Unified emits, so the two stay together; callers (e.g. the TUI) render the result without knowing the @@/+/- syntax. Line numbering follows the hunk headers.

type LineKind

type LineKind int

LineKind classifies one line of a unified diff.

const (
	LineContext LineKind = iota // unchanged line (leading space)
	LineAdd                     // inserted line (leading '+')
	LineDel                     // removed line (leading '-')
	LineHunk                    // "@@ -a,b +c,d @@" header
	LineMeta                    // any line before the first hunk (e.g. a summary)
	// LineNoNewline is the "\ No newline at end of file" marker. It belongs to
	// the line above it and occupies no line of either file, so it carries no
	// numbers — and it must not be classified as context, or a renderer strips
	// its leading backslash and shows the rest as a line of code.
	LineNoNewline
)

Directories

Path Synopsis
Package simples holds runnable, test-verified usage examples for pkg/diff.
Package simples holds runnable, test-verified usage examples for pkg/diff.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL