Implemented anchors for rope buffer
This commit is contained in:
parent
8d775804cb
commit
3bf5e6dfd7
@ -115,6 +115,7 @@ func (b *RopeBuffer) Bytes() []byte {
|
||||
// Insert copies a byte slice (inserting it) into the position at line, col.
|
||||
func (b *RopeBuffer) Insert(line, col int, value []byte) {
|
||||
b.rope.Insert(b.LineColToPos(line, col), value)
|
||||
b.shiftAnchors(line, col, utf8.RuneCount(value))
|
||||
}
|
||||
|
||||
// Remove deletes any characters between startLine, startCol, and endLine,
|
||||
@ -126,11 +127,15 @@ func (b *RopeBuffer) Remove(startLine, startCol, endLine, endCol int) {
|
||||
if len := b.rope.Len(); end >= len {
|
||||
end = len
|
||||
if start > end {
|
||||
start = end
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
b.rope.Remove(start, end)
|
||||
// Shift anchors within the range
|
||||
b.shiftAnchorsRemovedRange(start, startLine, startCol, endLine, endCol)
|
||||
// Shift anchors after the range
|
||||
b.shiftAnchors(endLine, endCol+1, start-end-1)
|
||||
}
|
||||
|
||||
// Returns the number of occurrences of 'sequence' in the buffer, within the range
|
||||
@ -328,6 +333,31 @@ func (b *RopeBuffer) WriteTo(w io.Writer) (int64, error) {
|
||||
return b.rope.WriteTo(w)
|
||||
}
|
||||
|
||||
// Currently meant for the Remove function: imagine if the removed region passes through a Cursor position.
|
||||
// We want to shift the cursor to the start of the region, based upon where the cursor position is.
|
||||
func (b *RopeBuffer) shiftAnchorsRemovedRange(startPos, startLine, startCol, endLine, endCol int) {
|
||||
for _, v := range b.anchors {
|
||||
cursorLine, cursorCol := v.GetLineCol()
|
||||
if cursorLine >= startLine && cursorLine <= endLine {
|
||||
// If the anchor is not within the start or end columns
|
||||
if (cursorLine == startLine && cursorCol < startCol) || (cursorLine == endLine && cursorCol > endCol) {
|
||||
continue
|
||||
}
|
||||
cursorPos := b.LineColToPos(cursorLine, cursorCol)
|
||||
v.line, v.col = b.PosToLineCol(cursorPos + (startPos - cursorPos))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *RopeBuffer) shiftAnchors(insertLine, insertCol, runeCount int) {
|
||||
for _, v := range b.anchors {
|
||||
cursorLine, cursorCol := v.GetLineCol()
|
||||
if insertLine < cursorLine || (insertLine == cursorLine && insertCol <= cursorCol) {
|
||||
v.line, v.col = b.PosToLineCol(b.LineColToPos(cursorLine, cursorCol) + runeCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCursor adds the Cursor to a slice which the Buffer uses to update
|
||||
// each Cursor based on changes that occur in the Buffer. Various functions are
|
||||
// called on the Cursor depending upon where the edits occurred and how it should
|
||||
|
@ -77,6 +77,7 @@ loop:
|
||||
|
||||
t.Buffer = buffer.NewRopeBuffer(contents)
|
||||
t.cursor = buffer.NewCursor(&t.Buffer)
|
||||
t.Buffer.RegisterCursor(&t.cursor)
|
||||
t.selection = buffer.NewRegion(&t.Buffer)
|
||||
|
||||
// TODO: replace with automatic determination of language via filetype
|
||||
@ -173,6 +174,7 @@ func (t *TextEdit) Delete(forwards bool) {
|
||||
// If the cursor is not at the first column of the first line...
|
||||
if cursLine > 0 || cursCol > 0 {
|
||||
t.cursor = t.cursor.Left() // Back up to that character
|
||||
cursLine, cursCol = t.cursor.GetLineCol()
|
||||
|
||||
bytes := t.Buffer.Slice(cursLine, cursCol, cursLine, cursCol) // Get the char at cursor
|
||||
deletedLine = bytes[0] == '\n'
|
||||
@ -233,7 +235,6 @@ func (t *TextEdit) Insert(contents string) {
|
||||
default:
|
||||
// Insert character into line
|
||||
t.Buffer.Insert(cursLine, cursCol, []byte(string(ch)))
|
||||
// t.SetLineCol(t.cury, t.curx+1) // Advance the cursor
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user