Rope buffer: Fix bug in PosToLineCol and add test case

This commit is contained in:
Luke I. Wilson 2021-03-30 22:14:02 -05:00
parent a90a367122
commit a79227e97c
2 changed files with 59 additions and 11 deletions

View File

@ -290,28 +290,33 @@ func (b *RopeBuffer) PosToLineCol(pos int) (int, int) {
var line, col int var line, col int
var wasAtNewline bool var wasAtNewline bool
_rope := (*rope.Node)(b) if pos <= 0 {
_rope.EachLeaf(func(n *rope.Node) bool { return line, col
}
(*rope.Node)(b).EachLeaf(func(n *rope.Node) bool {
data := n.Value() data := n.Value()
var i int var i int
for i < len(data) { for i < len(data) {
if pos <= 0 { if wasAtNewline { // Start of line
return true if data[i] != '\n' { // If the start of this line does not happen to be a delim...
} wasAtNewline = false // Say we weren't previously at a delimiter
}
if data[i] == '\n' { // End of line line, col = line+1, 0
} else if data[i] == '\n' { // End of line
wasAtNewline = true wasAtNewline = true
col++ col++
} else if wasAtNewline { // Start of line
wasAtNewline = false
line, col = line+1, 0
} else { } else {
col++ // Normal byte col++
} }
_, size := utf8.DecodeRune(data[i:]) _, size := utf8.DecodeRune(data[i:])
i += size i += size
pos -= size pos -= size
if pos < 0 {
return true
}
} }
return false return false
}) })

View File

@ -2,6 +2,49 @@ package buffer
import "testing" import "testing"
func TestRopePosToLineCol(t *testing.T) {
var buf Buffer = NewRopeBuffer([]byte("line0\nline1\n\nline3\n"))
//line0
//line1
//
//line3
//
startLine, startCol := buf.PosToLineCol(0)
if startLine != 0 {
t.Errorf("Expected startLine == 0, got %v", startLine)
t.Fail()
}
if startCol != 0 {
t.Errorf("Expected startCol == 0, got %v", startCol)
t.Fail()
}
endPos := buf.Len()-1
endLine, endCol := buf.PosToLineCol(endPos)
t.Logf("endPos = %v", endPos)
if endLine != 3 {
t.Errorf("Expected endLine == 3, got %v", endLine)
}
if endCol != 5 {
t.Errorf("Expected endCol == 5, got %v", endCol)
}
line1Pos := 11 // Byte index of the delim separating line1 and line 2
line1Line, line1Col := buf.PosToLineCol(line1Pos)
if line1Line != 1 {
t.Errorf("Expected line1Line == 1, got %v", line1Line)
t.Fail()
}
if line1Col != 5 {
t.Errorf("Expected line1Col == 5, got %v", line1Col)
t.Fail()
}
}
func TestRopeInserting(t *testing.T) { func TestRopeInserting(t *testing.T) {
var buf Buffer = NewRopeBuffer([]byte("some")) var buf Buffer = NewRopeBuffer([]byte("some"))
buf.Insert(0, 4, []byte(" text\n")) // Insert " text" after "some" buf.Insert(0, 4, []byte(" text\n")) // Insert " text" after "some"