diff --git a/src/Parlot/Cursor.cs b/src/Parlot/Cursor.cs index b66e361..2a296ce 100644 --- a/src/Parlot/Cursor.cs +++ b/src/Parlot/Cursor.cs @@ -118,11 +118,13 @@ public void Advance(int count) public void AdvanceNoNewLines(int offset) { var newOffset = _offset + offset; + var length = _textLength - 1; // Detect if the cursor will be over Eof - if (newOffset > _textLength - 1) + if (newOffset > length) { Eof = true; + _column += newOffset - length; _offset = _textLength; _current = NullChar; return; @@ -130,6 +132,7 @@ public void AdvanceNoNewLines(int offset) _current = _buffer[newOffset]; _offset = newOffset; + _column += offset; } /// diff --git a/test/Parlot.Tests/CursorTests.cs b/test/Parlot.Tests/CursorTests.cs index 7111abb..99d08cb 100644 --- a/test/Parlot.Tests/CursorTests.cs +++ b/test/Parlot.Tests/CursorTests.cs @@ -165,6 +165,63 @@ public void AdvanceShouldStopAtEof() Assert.Equal(1, c.Position.Line); } + [Fact] + public void AdvanceNoNewLinesShouldCountColumns() + { + var c = new Cursor("123456789"); + + Assert.Equal('1', c.Current); + Assert.Equal(0, c.Position.Offset); + Assert.Equal(1, c.Position.Column); + Assert.Equal(1, c.Position.Line); + + c.AdvanceNoNewLines(4); + + Assert.Equal('5', c.Current); + Assert.Equal(4, c.Position.Offset); + Assert.Equal(5, c.Position.Column); + Assert.Equal(1, c.Position.Line); + + c.AdvanceNoNewLines(4); + + Assert.Equal('9', c.Current); + Assert.Equal(8, c.Position.Offset); + Assert.Equal(9, c.Position.Column); + Assert.Equal(1, c.Position.Line); + + c.AdvanceNoNewLines(1); + + Assert.Equal(Cursor.NullChar, c.Current); + Assert.Equal(9, c.Position.Offset); + Assert.Equal(10, c.Position.Column); + Assert.Equal(1, c.Position.Line); + } + + [Fact] + public void AdvanceNoNewLinesShouldStopAtEof() + { + var c = new Cursor("1234\n5678"); + + Assert.Equal('1', c.Current); + Assert.Equal(0, c.Position.Offset); + Assert.Equal(1, c.Position.Column); + Assert.Equal(1, c.Position.Line); + + c.Advance(5); + + Assert.Equal('5', c.Current); + Assert.Equal(5, c.Position.Offset); + Assert.Equal(1, c.Position.Column); + Assert.Equal(2, c.Position.Line); + + c.AdvanceNoNewLines(6); + + Assert.Equal(Cursor.NullChar, c.Current); + Assert.Equal(9, c.Position.Offset); + Assert.Equal(4, c.Position.Column); + Assert.Equal(2, c.Position.Line); + } + [Fact] public void ResetPositionShouldMoveToEof() {