2021-03-30 16:05:33 -04:00
|
|
|
package editor
|
|
|
|
|
2021-04-01 16:17:13 -04:00
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
)
|
2021-03-31 14:32:43 -04:00
|
|
|
|
2021-03-30 16:05:33 -04:00
|
|
|
type row struct {
|
|
|
|
chars []rune
|
2021-03-31 14:32:43 -04:00
|
|
|
render []rune
|
2021-03-30 16:05:33 -04:00
|
|
|
}
|
|
|
|
|
2021-03-31 14:32:43 -04:00
|
|
|
func newRow(s string) *row {
|
2021-03-30 18:00:06 -04:00
|
|
|
var chars []rune
|
2021-03-31 14:32:43 -04:00
|
|
|
var render []rune
|
2021-03-30 18:00:06 -04:00
|
|
|
|
|
|
|
for _, ch := range s {
|
|
|
|
chars = append(chars, ch)
|
2021-03-31 14:32:43 -04:00
|
|
|
render = append(render, ch)
|
2021-03-30 18:00:06 -04:00
|
|
|
}
|
|
|
|
|
2021-04-01 16:17:13 -04:00
|
|
|
return &row{chars, render}
|
2021-03-30 16:05:33 -04:00
|
|
|
}
|
|
|
|
|
2021-03-31 14:32:43 -04:00
|
|
|
func (r *row) size() int {
|
2021-03-30 16:05:33 -04:00
|
|
|
return len(r.chars)
|
|
|
|
}
|
|
|
|
|
2021-03-31 14:32:43 -04:00
|
|
|
func (r *row) rSize() int {
|
|
|
|
return len(r.render)
|
|
|
|
}
|
|
|
|
|
2021-04-01 16:17:13 -04:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2021-03-31 14:32:43 -04:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2021-03-30 16:05:33 -04:00
|
|
|
|
2021-04-01 16:17:13 -04:00
|
|
|
func (r *row) toString() string {
|
|
|
|
return string(r.chars)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *row) cursorXToRenderX(cursorX int) int {
|
2021-03-31 14:56:46 -04:00
|
|
|
renderX := 0
|
|
|
|
i := 0
|
|
|
|
|
|
|
|
for ; i < cursorX; i++ {
|
|
|
|
if r.chars[i] == '\t' {
|
|
|
|
renderX += (KiloTabStop - 1) - (renderX % KiloTabStop)
|
|
|
|
}
|
|
|
|
|
|
|
|
renderX += 1
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderX
|
2021-04-01 16:17:13 -04:00
|
|
|
}
|