Skip to content

Commit a38148c

Browse files
committed
fix: tests and make editable document work
1 parent b2a867f commit a38148c

File tree

2 files changed

+94
-59
lines changed

2 files changed

+94
-59
lines changed

source.go

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ type Position struct {
1515
Index int
1616
}
1717

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+
1826
func (a Position) Eq(b Position) bool {
1927
return a.Column == b.Column &&
2028
a.Line == b.Line &&
@@ -53,22 +61,22 @@ func (loc Location) Range() sitter.Range {
5361
}
5462

5563
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
6269
}
6370

6471
func (c Changeset) AddLines(lines int) Changeset {
6572
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+
}
7280
}
7381
return c
7482
}
@@ -131,53 +139,45 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
131139
}
132140

133141
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)
136144
changeset.IsChanged = false
137145
}
138146

139147
// 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 {
143149
// 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])
147158
}
148159

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 {
153161
startPos.Column = changeset.StartPos.Column
154-
} else if i == changeset.EndPos.Line {
162+
} else if line == changeset.EndPos.Line {
155163
endPos.Column = changeset.EndPos.Column
156164
}
157165

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))
171172
}
172173

173-
return total
174+
return totalLinesAdded
174175
}
175176

176177
// if the changeset is a newline, split the new text into lines and apply them
177178
nlCount := strings.Count(changeset.NewText, "\n")
178179
if (nlCount == 1 && !strings.HasSuffix(changeset.NewText, "\n")) || nlCount > 1 {
179180
newLines := strings.Split(changeset.NewText, "\n")
180-
total := 0
181181

182182
for i, line := range newLines {
183183
textToAdd := line
@@ -195,26 +195,24 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
195195
endPos.Column = changeset.EndPos.Column
196196
}
197197

198-
changeset := Changeset{
198+
totalLinesAdded += doc.Apply(Changeset{
199199
Id: changeset.Id,
200200
NewText: textToAdd,
201201
StartPos: startPos,
202202
EndPos: endPos,
203-
}
204-
205-
total += doc.Apply(changeset.AddLines(total))
203+
}.AddLines(totalLinesAdded))
206204
}
207205

208-
return total
206+
return totalLinesAdded
209207
}
210208

211209
// 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]))
213211

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]) {
215213
// 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
218216
} else {
219217
left := doc.modifiedLines[changeset.StartPos.Line][:changeset.StartPos.Column]
220218
right := doc.modifiedLines[changeset.EndPos.Line][changeset.EndPos.Column:]
@@ -231,16 +229,14 @@ func (doc *EditableDocument) Apply(changeset Changeset) int {
231229
doc.modifiedLines[changeset.EndPos.Line:]...)
232230

233231
doc.modifiedLines[changeset.StartPos.Line] = left + changeset.NewText
234-
changeset.linesAdded++
232+
totalLinesAdded++
235233
} else {
236-
fmt.Println(changeset.EndPos.Line)
237-
238234
doc.modifiedLines[changeset.StartPos.Line] = left + changeset.NewText + right
239-
changeset.linesAdded = 0
235+
totalLinesAdded = 0
240236
}
241237
}
242238

243-
fmt.Printf("new: %q for %q\n", changeset.NewText, doc.modifiedLines)
239+
// fmt.Printf("new: %v for %q\n", changeset, doc.modifiedLines)
244240

245241
// add changeset
246242
doc.changesets = append(doc.changesets, changeset)

source_test.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var testLanguage = &Language{
1515
StackTracePattern: `\s+File "(?P<path>\S+)", line (?P<position>\d+), in (?P<symbol>\S+)`,
1616
ErrorPattern: `Traceback \(most recent call last\):$stacktrace$message`,
1717
AnalyzerFactory: func(cd *ContextData) LanguageAnalyzer {
18-
return &pyAnalyzer{cd}
18+
return &testAnalyzer{cd}
1919
},
2020
SymbolsToCapture: `
2121
(expression_statement
@@ -25,20 +25,20 @@ var testLanguage = &Language{
2525
`,
2626
}
2727

28-
type pyAnalyzer struct {
28+
type testAnalyzer struct {
2929
*ContextData
3030
}
3131

32-
func (an *pyAnalyzer) FallbackSymbol() Symbol {
32+
func (an *testAnalyzer) FallbackSymbol() Symbol {
3333
return Builtin("any")
3434
}
3535

36-
func (an *pyAnalyzer) AnalyzeNode(n SyntaxNode) Symbol {
36+
func (an *testAnalyzer) AnalyzeNode(n SyntaxNode) Symbol {
3737
// TODO:
3838
return Builtin("void")
3939
}
4040

41-
func (an *pyAnalyzer) AnalyzeImport(params ImportParams) ResolvedImport {
41+
func (an *testAnalyzer) AnalyzeImport(params ImportParams) ResolvedImport {
4242
// TODO:
4343

4444
return ResolvedImport{
@@ -240,4 +240,43 @@ func TestEditableDocument(t *testing.T) {
240240
t.Errorf("Expected contents to be \"a = 1\", got %q", editableDoc.String())
241241
}
242242
})
243+
244+
t.Run("EditableDocument.RemoveMultipleLines2", func(t *testing.T) {
245+
editableDoc := doc.Editable()
246+
247+
editableDoc.Apply(Changeset{
248+
NewText: "a = 1\nb = 2\n",
249+
StartPos: Position{
250+
Line: 0,
251+
Column: 0,
252+
Index: 0,
253+
},
254+
EndPos: Position{
255+
Line: 0,
256+
Column: 0,
257+
Index: 0,
258+
},
259+
})
260+
261+
if editableDoc.String() != "a = 1\nb = 2\nhello = 1" {
262+
t.Errorf("Expected contents to be \"a = 1\\nb = 2\\nhello = 1\", got %q", editableDoc.String())
263+
}
264+
265+
editableDoc.Apply(Changeset{
266+
StartPos: Position{
267+
Line: 1,
268+
Column: 0,
269+
Index: 6,
270+
},
271+
EndPos: Position{
272+
Line: 2,
273+
Column: 1,
274+
Index: 9,
275+
},
276+
})
277+
278+
if editableDoc.String() != "a = 1\nello = 1" {
279+
t.Errorf("Expected contents to be \"a = 1\\nello = 1\", got %q", editableDoc.String())
280+
}
281+
})
243282
}

0 commit comments

Comments
 (0)