-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhighlight.go
More file actions
65 lines (56 loc) · 1.7 KB
/
highlight.go
File metadata and controls
65 lines (56 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package diffx
// highlight represents a byte range [start, end) within a line that should
// be visually highlighted (the part that actually changed).
type highlight struct {
start, end int
}
// inlineDiff computes character-level differences between two lines. It
// returns whether the lines are "similar enough" to warrant inline
// highlighting (common=true), plus the highlighted byte ranges for each line.
//
// Lines are considered similar if more than 50% of characters are shared.
func inlineDiff(a, b string) (common bool, aHighlights, bHighlights []highlight) {
// Find common prefix.
prefixLen := commonPrefix(a, b)
// Find common suffix (on the remaining part after the prefix).
suffixLen := commonSuffix(a[prefixLen:], b[prefixLen:])
// The differing middle sections.
aMid := a[prefixLen : len(a)-suffixLen]
bMid := b[prefixLen : len(b)-suffixLen]
if len(aMid) == 0 && len(bMid) == 0 {
// Lines are identical, no highlights needed.
return true, nil, nil
}
// Check similarity: common chars vs total.
commonChars := prefixLen + suffixLen
totalChars := max(len(a), len(b))
if totalChars > 0 && float64(commonChars)/float64(totalChars) < 0.5 {
return false, nil, nil
}
if len(aMid) > 0 {
aHighlights = []highlight{{start: prefixLen, end: prefixLen + len(aMid)}}
}
if len(bMid) > 0 {
bHighlights = []highlight{{start: prefixLen, end: prefixLen + len(bMid)}}
}
return true, aHighlights, bHighlights
}
func commonPrefix(a, b string) int {
n := min(len(a), len(b))
for i := range n {
if a[i] != b[i] {
return i
}
}
return n
}
func commonSuffix(a, b string) int {
la, lb := len(a), len(b)
n := min(la, lb)
for i := range n {
if a[la-1-i] != b[lb-1-i] {
return i
}
}
return n
}