mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 14:38:19 +00:00
Fix bug in ViewsFromTo where from might clip first value
This commit is contained in:
@ -17,7 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultGlyphsPerBatch = 16384
|
DefaultGlyphsPerBatch = 4 * 1024
|
||||||
|
|
||||||
floatsPerGlyph = 13
|
floatsPerGlyph = 13
|
||||||
invalidRune = unicode.ReplacementChar
|
invalidRune = unicode.ReplacementChar
|
||||||
|
|||||||
26
main.go
26
main.go
@ -294,18 +294,19 @@ func (p *program) MainUpdate() {
|
|||||||
p.cursorCharIndex = p.cmdBufLen
|
p.cursorCharIndex = p.cmdBufLen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// var a, b uint64
|
||||||
if mouseWheelYNorm := -int64(input.GetMouseWheelYNorm()); mouseWheelYNorm != 0 {
|
if mouseWheelYNorm := -int64(input.GetMouseWheelYNorm()); mouseWheelYNorm != 0 {
|
||||||
|
|
||||||
var newPosNewLines int64
|
var newPosNewLines int64
|
||||||
if mouseWheelYNorm < 0 {
|
if mouseWheelYNorm < 0 {
|
||||||
newPosNewLines, _ = find_n_lines_index_iterator(p.textBuf.Iterator(), p.scrollPos, p.scrollSpd*mouseWheelYNorm-1, p.CellCountX)
|
newPosNewLines, _ = findNLinesIndexIterator(p.textBuf.Iterator(), p.scrollPos, p.scrollSpd*mouseWheelYNorm-1, p.CellCountX)
|
||||||
} else {
|
} else {
|
||||||
newPosNewLines, _ = find_n_lines_index_iterator(p.textBuf.Iterator(), p.scrollPos, p.scrollSpd*mouseWheelYNorm, p.CellCountX)
|
newPosNewLines, _ = findNLinesIndexIterator(p.textBuf.Iterator(), p.scrollPos, p.scrollSpd*mouseWheelYNorm, p.CellCountX)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := p.textBuf.AbsIndex(uint64(p.scrollPos))
|
// a = p.textBuf.AbsIndex(uint64(p.scrollPos))
|
||||||
b := p.textBuf.AbsIndex(uint64(newPosNewLines))
|
// b = p.textBuf.AbsIndex(uint64(newPosNewLines))
|
||||||
println("was at:", a, "; Now at:", b)
|
// fmt.Printf("was at absIndex %d (char=%d); Now at absIndex %d (char=%d)\n", a, p.textBuf.Get(a), b, p.textBuf.Get(b))
|
||||||
// assert.T(p.textBuf.Get(uint64(newPosNewLines)) != '\n', fmt.Sprintf("Original AbsIndex %d; New line at AbsIndex %d\n", a, b))
|
// assert.T(p.textBuf.Get(uint64(newPosNewLines)) != '\n', fmt.Sprintf("Original AbsIndex %d; New line at AbsIndex %d\n", a, b))
|
||||||
p.scrollPos = clamp(newPosNewLines, 0, p.textBuf.Len)
|
p.scrollPos = clamp(newPosNewLines, 0, p.textBuf.Len)
|
||||||
}
|
}
|
||||||
@ -322,14 +323,14 @@ func (p *program) MainUpdate() {
|
|||||||
|
|
||||||
// Draw textBuf
|
// Draw textBuf
|
||||||
from := p.scrollPos
|
from := p.scrollPos
|
||||||
to, _ := find_n_lines_index_iterator(p.textBuf.Iterator(), p.scrollPos, p.CellCountY-2, p.CellCountX)
|
to, _ := findNLinesIndexIterator(p.textBuf.Iterator(), p.scrollPos, p.CellCountY-2, p.CellCountX)
|
||||||
|
assert.T(to >= 0, "'to' was less than zero")
|
||||||
|
|
||||||
// to is the first character after the nth line. Passing this index to ViewsFromTo will show 1 more char than we want,
|
// to is the first character after the nth line. Passing this index to ViewsFromTo will show 1 more char than we want,
|
||||||
// so we decrement if needed
|
// so we decrement if needed
|
||||||
if to > 0 {
|
if to > 0 {
|
||||||
to--
|
to--
|
||||||
}
|
}
|
||||||
assert.T(to >= 0, "'to' was less than zero")
|
|
||||||
v1, v2 := p.textBuf.ViewsFromTo(uint64(from), uint64(to))
|
v1, v2 := p.textBuf.ViewsFromTo(uint64(from), uint64(to))
|
||||||
|
|
||||||
p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(v1, *gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0)).Data
|
p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(v1, *gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0)).Data
|
||||||
@ -599,7 +600,7 @@ func (p *program) HandleReturn() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer p.ClearActiveCmd()
|
defer p.ClearActiveCmd()
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 4*1024)
|
||||||
for p.activeCmd != nil {
|
for p.activeCmd != nil {
|
||||||
|
|
||||||
readBytes, err := p.activeCmd.Stdout.Read(buf)
|
readBytes, err := p.activeCmd.Stdout.Read(buf)
|
||||||
@ -617,6 +618,7 @@ func (p *program) HandleReturn() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Todo We need to parse ansi codes as data is coming in to update the drawing settings (e.g. color)
|
||||||
p.WriteToTextBuf(buf[:readBytes])
|
p.WriteToTextBuf(buf[:readBytes])
|
||||||
// println("Read:", string(buf[:readBytes]))
|
// println("Read:", string(buf[:readBytes]))
|
||||||
}
|
}
|
||||||
@ -862,14 +864,14 @@ func FindNthOrLastIndex[T comparable](arr []T, x T, startIndex, n int64) (lastIn
|
|||||||
return lastIndex
|
return lastIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_n_lines_index starts at startIndex and moves n lines forward/backward, depending on whether 'n' is negative or positive,
|
// findNLinesIndexIterator starts at startIndex and moves n lines forward/backward, depending on whether 'n' is negative or positive,
|
||||||
// then returns the index of the nth line and the size of char in bytes that preceeds the line.
|
// then returns the index of the nth line and the size of char in bytes that preceeds the line.
|
||||||
//
|
//
|
||||||
// A line is counted when either a '\n' is seen or by seeing enough chars that a wrap is required.
|
// A line is counted when either a '\n' is seen or by seeing enough chars that a wrap is required.
|
||||||
//
|
//
|
||||||
// Note: When moving backwards from the start of the line, the first char will be a new line (e.g. \n), so the first counted line is not a full line
|
// Note: When moving backwards from the start of the line, the first char will be a new line (e.g. \n), so the first counted line is not a full line
|
||||||
// but only a single rune. So in most cases to get '-n' lines backwards you should request '-n-1' lines.
|
// but only a single rune. So in most cases to get '-n' lines backwards you should request '-n-1' lines.
|
||||||
func find_n_lines_index_iterator(it ring.Iterator[byte], startIndex, n, charsPerLine int64) (newIndex, newSize int64) {
|
func findNLinesIndexIterator(it ring.Iterator[byte], startIndex, n, charsPerLine int64) (newIndex, newSize int64) {
|
||||||
|
|
||||||
// If nothing changes (e.g. already at end of iterator) then we will stay at the same place
|
// If nothing changes (e.g. already at end of iterator) then we will stay at the same place
|
||||||
|
|
||||||
@ -938,6 +940,10 @@ func find_n_lines_index_iterator(it ring.Iterator[byte], startIndex, n, charsPer
|
|||||||
// If this is true we covered one line
|
// If this is true we covered one line
|
||||||
if charsSeenThisLine == charsPerLine || r == '\n' {
|
if charsSeenThisLine == charsPerLine || r == '\n' {
|
||||||
|
|
||||||
|
if r == '\n' {
|
||||||
|
fmt.Printf("Found \\n at index %d\n", it.Curr)
|
||||||
|
}
|
||||||
|
|
||||||
charsSeenThisLine = 0
|
charsSeenThisLine = 0
|
||||||
newSize = int64(size)
|
newSize = int64(size)
|
||||||
newIndex = startIndex - bytesSeen + newSize
|
newIndex = startIndex - bytesSeen + newSize
|
||||||
|
|||||||
@ -154,7 +154,7 @@ func (b *Buffer[T]) ViewsFromTo(fromIndex, toIndex uint64) (v1, v2 []T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fromIndex -= v1Len - 1
|
fromIndex -= v1Len
|
||||||
toIndex -= v1Len
|
toIndex -= v1Len
|
||||||
if toIndex >= v2Len {
|
if toIndex >= v2Len {
|
||||||
toIndex = v2Len
|
toIndex = v2Len
|
||||||
@ -187,7 +187,9 @@ type Iterator[T any] struct {
|
|||||||
V1 []T
|
V1 []T
|
||||||
V2 []T
|
V2 []T
|
||||||
|
|
||||||
// Curr is the index of the element that will be returned on Next()
|
// Curr is the index of the element that will be returned on Next(),
|
||||||
|
// which means it is an index into V1 or V2 and so is relative to Buffer.Start value at the time
|
||||||
|
// of creating this iterator instance
|
||||||
Curr int64
|
Curr int64
|
||||||
InV1 bool
|
InV1 bool
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package ring_test
|
package ring_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/bloeys/nterm/ring"
|
"github.com/bloeys/nterm/ring"
|
||||||
@ -135,7 +136,8 @@ func TestRing(t *testing.T) {
|
|||||||
|
|
||||||
v11, v22 = b2.ViewsFromTo(3, 40)
|
v11, v22 = b2.ViewsFromTo(3, 40)
|
||||||
Check(t, 0, len(v11))
|
Check(t, 0, len(v11))
|
||||||
Check(t, 0, len(v22))
|
Check(t, 1, len(v22))
|
||||||
|
CheckArr(t, []int{6}, v22)
|
||||||
|
|
||||||
v11, v22 = b2.ViewsFromTo(1, 2)
|
v11, v22 = b2.ViewsFromTo(1, 2)
|
||||||
Check(t, 1, len(v11))
|
Check(t, 1, len(v11))
|
||||||
@ -159,6 +161,11 @@ func TestRing(t *testing.T) {
|
|||||||
Check(t, 2, len(v22))
|
Check(t, 2, len(v22))
|
||||||
CheckArr(t, []int{3, 4}, v11)
|
CheckArr(t, []int{3, 4}, v11)
|
||||||
CheckArr(t, []int{5, 6}, v22)
|
CheckArr(t, []int{5, 6}, v22)
|
||||||
|
|
||||||
|
v11, v22 = b2.ViewsFromTo(2, 3)
|
||||||
|
Check(t, 0, len(v11))
|
||||||
|
Check(t, 2, len(v22))
|
||||||
|
CheckArr(t, []int{5, 6}, v22)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIterator(t *testing.T) {
|
func TestIterator(t *testing.T) {
|
||||||
@ -291,21 +298,23 @@ func TestIterator(t *testing.T) {
|
|||||||
|
|
||||||
func Check[T comparable](t *testing.T, expected, got T) {
|
func Check[T comparable](t *testing.T, expected, got T) {
|
||||||
if got != expected {
|
if got != expected {
|
||||||
t.Fatalf("Expected %v but got %v\n", expected, got)
|
_, _, line, _ := runtime.Caller(1)
|
||||||
|
t.Fatalf("Expected %v but got %v by test at line %d\n", expected, got, line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckArr[T comparable](t *testing.T, expected, got []T) {
|
func CheckArr[T comparable](t *testing.T, expected, got []T) {
|
||||||
|
|
||||||
|
_, _, line, _ := runtime.Caller(1)
|
||||||
if len(expected) != len(got) {
|
if len(expected) != len(got) {
|
||||||
t.Fatalf("Expected %v but got %v\n", expected, got)
|
t.Fatalf("Expected %v but got %v by test at line %d\n", expected, got, line)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expected); i++ {
|
for i := 0; i < len(expected); i++ {
|
||||||
|
|
||||||
if expected[i] != got[i] {
|
if expected[i] != got[i] {
|
||||||
t.Fatalf("Expected %v but got %v\n", expected, got)
|
t.Fatalf("Expected %v but got %v by test at line %d\n", expected, got, line)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user