gilo/editor/row.go

104 lines
1.8 KiB
Go

package editor
import (
"strings"
)
type Row struct {
chars []rune
render []rune
}
func newRow(s string) *Row {
var chars []rune
var render []rune
for _, ch := range s {
chars = append(chars, ch)
render = append(render, ch)
}
return &Row{chars, render}
}
func (r *Row) Size() int {
return len(r.chars)
}
func (r *Row) RenderSize() int {
return len(r.render)
}
func (r *Row) insertRune(ch rune, at int) {
// If insertion index is invalid, just
// append the rune to the end of the array
if at < 0 || at >= r.Size() {
r.chars = append(r.chars, ch)
r.update()
return
}
var newSlice []rune
// Split the character array at the insertion point
start := r.chars[0:at]
end := r.chars[at:r.Size()]
// Splice it back together
newSlice = append(newSlice, start...)
newSlice = append(newSlice, ch)
newSlice = append(newSlice, end...)
r.chars = newSlice
r.update()
}
func (r *Row) deleteRune(at int) {
if at < 0 || at >= r.Size() {
return
}
var newSlice []rune
// Split the character array at the insertion point
start := r.chars[0:at]
end := r.chars[at+1 : r.Size()] // Skip the index in question
// Splice it back together
newSlice = append(newSlice, start...)
newSlice = append(newSlice, end...)
r.chars = newSlice
r.update()
}
func (r *Row) update() {
r.render = r.render[:0]
replacement := strings.Repeat(" ", KiloTabStop)
str := strings.ReplaceAll(string(r.chars), "\t", replacement)
for _, ch := range str {
r.render = append(r.render, ch)
}
}
func (r *Row) toString() string {
return string(r.chars)
}
func (r *Row) cursorXToRenderX(cursorX int) int {
renderX := 0
i := 0
for ; i < cursorX; i++ {
if r.chars[i] == '\t' {
renderX += (KiloTabStop - 1) - (renderX % KiloTabStop)
}
renderX += 1
}
return renderX
}