Skip to content

Commit

Permalink
fixed text edits
Browse files Browse the repository at this point in the history
  • Loading branch information
georghinkel committed Nov 7, 2024
1 parent 161a0b1 commit 2013c83
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
19 changes: 17 additions & 2 deletions AnyText/AnyText.Core/Matcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ public RuleApplication Match(ParseContext context)
}

/// <summary>
/// Removes any memoization based on the given text edit
/// Removes any memoization based on the given text edit and updates the memo table
/// </summary>
/// <param name="edit">The change in the input text</param>
public void RemoveMemoizedRuleApplications(TextEdit edit)
public void Apply(TextEdit edit)
{
for (int i = 0; i <= edit.Start.Line; i++)
{
Expand Down Expand Up @@ -231,6 +231,21 @@ public void RemoveMemoizedRuleApplications(TextEdit edit)

line.MaxExaminedLength = maxReach;
}
var linesDelta = edit.NewText.Length - (edit.End.Line - edit.Start.Line + 1);
if (linesDelta > 0)
{
for (int i = 0; i < linesDelta; i++)
{
_memoTable.Insert(edit.Start.Line, new MemoLine());
}
}
else if (linesDelta < 0)
{
for (int i = 0; i > linesDelta; i--)
{
_memoTable.RemoveAt(edit.Start.Line);
}
}
}

private sealed class MemoLine
Expand Down
2 changes: 1 addition & 1 deletion AnyText/AnyText.Core/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public object Update(IEnumerable<TextEdit> edits)
foreach (TextEdit edit in edits)
{
input = edit.Apply(input);
_matcher.RemoveMemoizedRuleApplications(edit);
_matcher.Apply(edit);
_context.Errors.RemoveAll(e => !e.ApplyEdit(edit));
}
_context.Input = input;
Expand Down
17 changes: 13 additions & 4 deletions AnyText/AnyText.Core/TextEdit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public string[] Apply(string[] input)
{
return ApplyInlineChange(input);
}
if (input.Length == End.Line - Start.Line + NewText.Length - 1)
if (NewText.Length == End.Line - Start.Line + 1)
{
return ApplyInplaceChange(input);
}
Expand All @@ -70,15 +70,24 @@ public string[] Apply(string[] input)

private string[] ApplyReconstructArray(string[] input)
{
var newArray = new string[input.Length + End.Line - Start.Line + NewText.Length - 1];
var newArray = new string[input.Length - End.Line + Start.Line + NewText.Length - 1];
Array.Copy(input, 0, newArray, 0, Start.Line);
newArray[Start.Line] = input[Start.Line].Substring(0, Start.Col) + NewText[0];
if (NewText.Length > 2)
{
Array.Copy(NewText, 1, newArray, Start.Line + 1, NewText.Length - 2);
}
newArray[End.Line] = NewText[NewText.Length - 1] + input[End.Line].Substring(End.Col);
Array.Copy(input, End.Line + 1, newArray, Start.Line + NewText.Length, input.Length - End.Line);
var offset = NewText.Length - (End.Line - Start.Line + 1);
var endline = input[End.Line].Substring(End.Col);
if (End.Line + offset == Start.Line)
{
newArray[Start.Line] += endline;
}
else
{
newArray[End.Line + offset] = NewText[NewText.Length - 1] + endline;
}
Array.Copy(input, End.Line + 1, newArray, End.Line + offset + 1, input.Length - End.Line - 1);
return newArray;
}

Expand Down
32 changes: 32 additions & 0 deletions AnyText/Tests/AnyText.Tests/ExpressionGrammarTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,38 @@ public void Parser_ProcessesDeleteCorrectly()
Assert.That(bin1.Right, Is.InstanceOf<BinExpr>());
}

[Test]
public void Parser_ProcessesLineInsertionCorrectly()
{
var parser = new Parser(CreateParseGrammar());
var expr1 = parser.Initialize(new string[] { "1 + 2 * (3 + 4)" });
var expr2 = parser.Update(new[]
{
new TextEdit(new ParsePosition(0, 1), new ParsePosition(0,2), new string[] { string.Empty, string.Empty, string.Empty })
});
Assert.That(expr1, Is.EqualTo(expr2));
var updatedInput = parser.Context.Input;
Assert.That(updatedInput.Length, Is.EqualTo(3));
Assert.That(updatedInput[0], Is.EqualTo("1"));
Assert.That(updatedInput[1], Is.EqualTo(string.Empty));
Assert.That(updatedInput[2], Is.EqualTo("+ 2 * (3 + 4)"));
}

[Test]
public void Parser_ProcessesLineDeletionCorrectly()
{
var parser = new Parser(CreateParseGrammar());
var expr1 = parser.Initialize(new string[] { "1", string.Empty, "+ 2 * (3 + 4)" });
var expr2 = parser.Update(new[]
{
new TextEdit(new ParsePosition(0, 1), new ParsePosition(2,0), new string[] { " " })
});
Assert.That(expr1, Is.EqualTo(expr2));
var updatedInput = parser.Context.Input;
Assert.That(updatedInput.Length, Is.EqualTo(1));
Assert.That(updatedInput[0], Is.EqualTo("1 + 2 * (3 + 4)"));
}

[Test]
public void Parser_ReusesElements()
{
Expand Down

0 comments on commit 2013c83

Please sign in to comment.