diffview.go

  1package diffview
  2
  3import (
  4	"github.com/aymanbagabas/go-udiff"
  5	"github.com/aymanbagabas/go-udiff/myers"
  6	"github.com/charmbracelet/lipgloss/v2"
  7)
  8
  9type file struct {
 10	path    string
 11	content string
 12}
 13
 14type layout int
 15
 16const (
 17	layoutUnified layout = iota + 1
 18	layoutSplit
 19)
 20
 21// DiffView represents a view for displaying differences between two files.
 22type DiffView struct {
 23	layout       layout
 24	before       file
 25	after        file
 26	contextLines int
 27	baseStyle    lipgloss.Style
 28	highlight    bool
 29	height       int
 30	width        int
 31
 32	isComputed bool
 33	err        error
 34	unified    udiff.UnifiedDiff
 35	edits      []udiff.Edit
 36}
 37
 38// New creates a new DiffView with default settings.
 39func New() *DiffView {
 40	return &DiffView{
 41		layout:       layoutUnified,
 42		contextLines: udiff.DefaultContextLines,
 43	}
 44}
 45
 46// Unified sets the layout of the DiffView to unified.
 47func (dv *DiffView) Unified() *DiffView {
 48	dv.layout = layoutUnified
 49	return dv
 50}
 51
 52// Split sets the layout of the DiffView to split (side-by-side).
 53func (dv *DiffView) Split() *DiffView {
 54	dv.layout = layoutSplit
 55	return dv
 56}
 57
 58// Before sets the "before" file for the DiffView.
 59func (dv *DiffView) Before(path, content string) *DiffView {
 60	dv.before = file{path: path, content: content}
 61	return dv
 62}
 63
 64// After sets the "after" file for the DiffView.
 65func (dv *DiffView) After(path, content string) *DiffView {
 66	dv.after = file{path: path, content: content}
 67	return dv
 68}
 69
 70// ContextLines sets the number of context lines for the DiffView.
 71func (dv *DiffView) ContextLines(contextLines int) *DiffView {
 72	dv.contextLines = contextLines
 73	return dv
 74}
 75
 76// BaseStyle sets the base style for the DiffView.
 77// This is useful for setting a custom background color, for example.
 78func (dv *DiffView) BaseStyle(baseStyle lipgloss.Style) *DiffView {
 79	dv.baseStyle = baseStyle
 80	return dv
 81}
 82
 83// SyntaxHighlight sets whether to enable syntax highlighting in the DiffView.
 84func (dv *DiffView) SyntaxHighlight(highlight bool) *DiffView {
 85	dv.highlight = highlight
 86	return dv
 87}
 88
 89// Height sets the height of the DiffView.
 90func (dv *DiffView) Height(height int) *DiffView {
 91	dv.height = height
 92	return dv
 93}
 94
 95// Width sets the width of the DiffView.
 96func (dv *DiffView) Width(width int) *DiffView {
 97	dv.width = width
 98	return dv
 99}
100
101// String returns the string representation of the DiffView.
102func (dv *DiffView) String() string {
103	if !dv.isComputed {
104		dv.compute()
105	}
106	if dv.err != nil {
107		return dv.err.Error()
108	}
109	return dv.unified.String()
110}
111
112func (dv *DiffView) compute() {
113	dv.isComputed = true
114	dv.edits = myers.ComputeEdits(
115		dv.before.content,
116		dv.after.content,
117	)
118	dv.unified, dv.err = udiff.ToUnifiedDiff(
119		dv.before.path,
120		dv.after.path,
121		dv.before.content,
122		dv.edits,
123		dv.contextLines,
124	)
125}