@@ -15,6 +15,14 @@ type Position struct {
15
15
Index int
16
16
}
17
17
18
+ func (pos Position ) Add (pos2 Position ) Position {
19
+ return Position {
20
+ Line : max (pos .Line + pos2 .Line , 0 ),
21
+ Column : max (pos .Column + pos2 .Column , 0 ),
22
+ Index : max (pos .Index + pos2 .Index , 0 ),
23
+ }
24
+ }
25
+
18
26
func (a Position ) Eq (b Position ) bool {
19
27
return a .Column == b .Column &&
20
28
a .Line == b .Line &&
@@ -53,22 +61,22 @@ func (loc Location) Range() sitter.Range {
53
61
}
54
62
55
63
type Changeset struct {
56
- Id int
57
- NewText string
58
- StartPos Position
59
- EndPos Position
60
- linesAdded int
61
- IsChanged bool
64
+ Id int
65
+ NewText string
66
+ StartPos Position
67
+ EndPos Position
68
+ IsChanged bool
62
69
}
63
70
64
71
func (c Changeset ) AddLines (lines int ) Changeset {
65
72
if lines != 0 {
66
- fmt .Println ("adding lines" , lines )
67
-
68
- c .linesAdded += lines
69
- c .StartPos .Line += lines
70
- c .EndPos .Line += lines
71
- c .IsChanged = true
73
+ return Changeset {
74
+ Id : c .Id ,
75
+ NewText : c .NewText ,
76
+ StartPos : c .StartPos .Add (Position {Line : lines }),
77
+ EndPos : c .EndPos .Add (Position {Line : lines }),
78
+ IsChanged : true ,
79
+ }
72
80
}
73
81
return c
74
82
}
@@ -131,53 +139,45 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
131
139
}
132
140
133
141
if changeset .IsChanged {
134
- changeset .StartPos . Index = doc .FillIndex (changeset .StartPos ). Index
135
- changeset .EndPos . Index = doc .FillIndex (changeset .EndPos ). Index
142
+ changeset .StartPos = doc .FillIndex (changeset .StartPos )
143
+ changeset .EndPos = doc .FillIndex (changeset .EndPos )
136
144
changeset .IsChanged = false
137
145
}
138
146
139
147
// if the changeset text is empty but has a definite position range, this means that the changeset is a deletion
140
- if len (changeset .NewText ) == 0 {
141
- total := 0
142
-
148
+ if len (changeset .NewText ) == 0 && changeset .StartPos .Line != changeset .EndPos .Line {
143
149
// if the changeset start line is not the same as the end line, split it
144
- for i := changeset .StartPos .Line ; i < len (doc .modifiedLines ); {
145
- if i > changeset .EndPos .Line {
146
- break
150
+ for line := changeset .StartPos .Line ; line <= changeset .EndPos .Line ; line ++ {
151
+ startPos := Position {Line : line , Column : 0 }
152
+ endPos := Position {Line : line , Column : 0 }
153
+
154
+ if line < len (doc .modifiedLines ) {
155
+ // if the line is the last line, set the end position to the length of the line.
156
+ // take note, this is the length of the original line, not the modified line
157
+ endPos .Column = len (doc .modifiedLines [line ])
147
158
}
148
159
149
- startPos := Position {Line : i , Column : 0 }
150
- endPos := Position {Line : i , Column : len (doc .modifiedLines [i ])}
151
-
152
- if i == changeset .StartPos .Line {
160
+ if line == changeset .StartPos .Line {
153
161
startPos .Column = changeset .StartPos .Column
154
- } else if i == changeset .EndPos .Line {
162
+ } else if line == changeset .EndPos .Line {
155
163
endPos .Column = changeset .EndPos .Column
156
164
}
157
165
158
- if i != changeset .StartPos .Line {
159
- startPos .Line = i - 1
160
- endPos .Line = i - 1
161
- }
162
-
163
- changeset := Changeset {
164
- Id : changeset .Id ,
165
- NewText : changeset .NewText ,
166
- StartPos : doc .FillIndex (startPos ),
167
- EndPos : doc .FillIndex (endPos ),
168
- }
169
-
170
- total += doc .Apply (changeset .AddLines (total ))
166
+ totalLinesAdded += doc .Apply (Changeset {
167
+ Id : changeset .Id ,
168
+ StartPos : startPos ,
169
+ EndPos : endPos ,
170
+ IsChanged : true , // turn it on so that FillIndex will be called in the earlier part of this function
171
+ }.AddLines (totalLinesAdded ))
171
172
}
172
173
173
- return total
174
+ return totalLinesAdded
174
175
}
175
176
176
177
// if the changeset is a newline, split the new text into lines and apply them
177
178
nlCount := strings .Count (changeset .NewText , "\n " )
178
179
if (nlCount == 1 && ! strings .HasSuffix (changeset .NewText , "\n " )) || nlCount > 1 {
179
180
newLines := strings .Split (changeset .NewText , "\n " )
180
- total := 0
181
181
182
182
for i , line := range newLines {
183
183
textToAdd := line
@@ -195,26 +195,24 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
195
195
endPos .Column = changeset .EndPos .Column
196
196
}
197
197
198
- changeset := Changeset {
198
+ totalLinesAdded += doc . Apply ( Changeset {
199
199
Id : changeset .Id ,
200
200
NewText : textToAdd ,
201
201
StartPos : startPos ,
202
202
EndPos : endPos ,
203
- }
204
-
205
- total += doc .Apply (changeset .AddLines (total ))
203
+ }.AddLines (totalLinesAdded ))
206
204
}
207
205
208
- return total
206
+ return totalLinesAdded
209
207
}
210
208
211
209
// to avoid out of bounds error. limit the endpos column to the length of the doc line
212
- changeset .EndPos .Column = min (changeset .EndPos .Column , len (doc .modifiedLines [changeset .EndPos .Line ]))
210
+ changeset .EndPos .Column = min (max ( changeset .EndPos .Column , 0 ) , len (doc .modifiedLines [changeset .EndPos .Line ]))
213
211
214
- if len (changeset .NewText ) == 0 && changeset .StartPos .Column == 0 && changeset .EndPos .Column == len (doc .modifiedLines [changeset .StartPos .Line ]) {
212
+ if len (changeset .NewText ) == 0 && changeset .StartPos .Column == 0 && changeset .EndPos .Column == len (doc .modifiedLines [changeset .EndPos .Line ]) {
215
213
// remove the line if the changeset is an empty and the position covers the entire line
216
- doc .modifiedLines = append (doc .modifiedLines [:changeset .StartPos .Line ], doc .modifiedLines [changeset .EndPos .Line :]... )
217
- changeset . linesAdded = - 1
214
+ doc .modifiedLines = append (doc .modifiedLines [:changeset .StartPos .Line ], doc .modifiedLines [changeset .EndPos .Line + 1 :]... )
215
+ totalLinesAdded = - 1
218
216
} else {
219
217
left := doc .modifiedLines [changeset .StartPos .Line ][:changeset .StartPos .Column ]
220
218
right := doc .modifiedLines [changeset .EndPos .Line ][changeset .EndPos .Column :]
@@ -231,16 +229,14 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
231
229
doc .modifiedLines [changeset .EndPos .Line :]... )
232
230
233
231
doc .modifiedLines [changeset .StartPos .Line ] = left + changeset .NewText
234
- changeset . linesAdded ++
232
+ totalLinesAdded ++
235
233
} else {
236
- fmt .Println (changeset .EndPos .Line )
237
-
238
234
doc .modifiedLines [changeset .StartPos .Line ] = left + changeset .NewText + right
239
- changeset . linesAdded = 0
235
+ totalLinesAdded = 0
240
236
}
241
237
}
242
238
243
- fmt .Printf ("new: %q for %q\n " , changeset . NewText , doc .modifiedLines )
239
+ // fmt.Printf("new: %v for %q\n", changeset, doc.modifiedLines)
244
240
245
241
// add changeset
246
242
doc .changesets = append (doc .changesets , changeset )
0 commit comments