@@ -9,47 +9,42 @@ import (
9
9
"strings"
10
10
11
11
"golang.org/x/tools/internal/lsp/diff"
12
+ "golang.org/x/tools/internal/span"
12
13
)
13
14
14
15
// Sources:
15
16
// https://blog.jcoglan.com/2017/02/17/the-myers-diff-algorithm-part-3/
16
17
// https://www.codeproject.com/Articles/42279/%2FArticles%2F42279%2FInvestigating-Myers-diff-algorithm-Part-1-of-2
17
18
18
- type Op struct {
19
+ func ComputeEdits (uri span.URI , before , after string ) []diff.TextEdit {
20
+ ops := operations (splitLines (before ), splitLines (after ))
21
+ edits := make ([]diff.TextEdit , 0 , len (ops ))
22
+ for _ , op := range ops {
23
+ s := span .New (uri , span .NewPoint (op .I1 + 1 , 1 , 0 ), span .NewPoint (op .I2 + 1 , 1 , 0 ))
24
+ switch op .Kind {
25
+ case diff .Delete :
26
+ // Delete: unformatted[i1:i2] is deleted.
27
+ edits = append (edits , diff.TextEdit {Span : s })
28
+ case diff .Insert :
29
+ // Insert: formatted[j1:j2] is inserted at unformatted[i1:i1].
30
+ if content := strings .Join (op .Content , "" ); content != "" {
31
+ edits = append (edits , diff.TextEdit {Span : s , NewText : content })
32
+ }
33
+ }
34
+ }
35
+ return edits
36
+ }
37
+
38
+ type operation struct {
19
39
Kind diff.OpKind
20
40
Content []string // content from b
21
41
I1 , I2 int // indices of the line in a
22
42
J1 int // indices of the line in b, J2 implied by len(Content)
23
43
}
24
44
25
- func ApplyEdits (a []string , operations []* Op ) []string {
26
- var b []string
27
- var prevI2 int
28
- for _ , op := range operations {
29
- // catch up to latest indices
30
- if op .I1 - prevI2 > 0 {
31
- for _ , c := range a [prevI2 :op .I1 ] {
32
- b = append (b , c )
33
- }
34
- }
35
- switch op .Kind {
36
- case diff .Equal , diff .Insert :
37
- b = append (b , op .Content ... )
38
- }
39
- prevI2 = op .I2
40
- }
41
- // final catch up
42
- if len (a )- prevI2 > 0 {
43
- for _ , c := range a [prevI2 :len (a )] {
44
- b = append (b , c )
45
- }
46
- }
47
- return b
48
- }
49
-
50
- // Operations returns the list of operations to convert a into b, consolidating
45
+ // operations returns the list of operations to convert a into b, consolidating
51
46
// operations for multiple lines and not including equal lines.
52
- func Operations (a , b []string ) []* Op {
47
+ func operations (a , b []string ) []* operation {
53
48
if len (a ) == 0 && len (b ) == 0 {
54
49
return nil
55
50
}
@@ -60,9 +55,9 @@ func Operations(a, b []string) []*Op {
60
55
M , N := len (a ), len (b )
61
56
62
57
var i int
63
- solution := make ([]* Op , len (a )+ len (b ))
58
+ solution := make ([]* operation , len (a )+ len (b ))
64
59
65
- add := func (op * Op , i2 , j2 int ) {
60
+ add := func (op * operation , i2 , j2 int ) {
66
61
if op == nil {
67
62
return
68
63
}
@@ -78,11 +73,11 @@ func Operations(a, b []string) []*Op {
78
73
if len (snake ) < 2 {
79
74
continue
80
75
}
81
- var op * Op
76
+ var op * operation
82
77
// delete (horizontal)
83
78
for snake [0 ]- snake [1 ] > x - y {
84
79
if op == nil {
85
- op = & Op {
80
+ op = & operation {
86
81
Kind : diff .Delete ,
87
82
I1 : x ,
88
83
J1 : y ,
@@ -98,7 +93,7 @@ func Operations(a, b []string) []*Op {
98
93
// insert (vertical)
99
94
for snake [0 ]- snake [1 ] < x - y {
100
95
if op == nil {
101
- op = & Op {
96
+ op = & operation {
102
97
Kind : diff .Insert ,
103
98
I1 : x ,
104
99
J1 : y ,
@@ -201,7 +196,7 @@ func shortestEditSequence(a, b []string) ([][]int, int) {
201
196
return nil , 0
202
197
}
203
198
204
- func SplitLines (text string ) []string {
199
+ func splitLines (text string ) []string {
205
200
lines := strings .SplitAfter (text , "\n " )
206
201
if lines [len (lines )- 1 ] == "" {
207
202
lines = lines [:len (lines )- 1 ]
0 commit comments