TextView: Add SetMaxLines()

This commit is contained in:
Javier Peletier 2020-05-15 18:52:20 +02:00
parent 5c2dfbf231
commit 9f88a788e4
2 changed files with 66 additions and 0 deletions

View File

@ -136,6 +136,9 @@ type TextView struct {
// The index of the first line shown in the text view.
lineOffset int
// The maximum number of liens the text view will hold (set to 0 for no limit)
maxLines int
// If set to true, the text view will always remain at the end of the content.
trackEnd bool
@ -203,6 +206,7 @@ func NewTextView() *TextView {
textColor: Styles.PrimaryTextColor,
regions: false,
dynamicColors: false,
maxLines: 0,
}
}
@ -389,6 +393,23 @@ func (t *TextView) SetHighlightedFunc(handler func(added, removed, remaining []s
return t
}
func (t *TextView) clipBuffer() {
if t.maxLines > 0 {
lenbuf := len(t.buffer)
if lenbuf > t.maxLines {
t.buffer = t.buffer[lenbuf-t.maxLines:]
}
}
}
// SetMaxLines establishes the maximum amount of lines the text view will hold
// before discarding older data from the buffer
func (t *TextView) SetMaxLines(maxLines int) *TextView {
t.maxLines = maxLines
t.clipBuffer()
return t
}
// ScrollTo scrolls to the specified row and column (both starting with 0).
func (t *TextView) ScrollTo(row, column int) *TextView {
t.Lock()
@ -722,6 +743,8 @@ func (t *TextView) write(p []byte) (n int, err error) {
}
}
t.clipBuffer()
// Reset the index.
t.index = nil

View File

@ -3,6 +3,7 @@ package cview
import (
"bytes"
"fmt"
"strings"
"testing"
)
@ -195,6 +196,48 @@ func BenchmarkTextViewDraw(b *testing.B) {
}
}
func TestTextViewMaxLines(t *testing.T) {
tv := NewTextView()
// append 100 lines with no limit set:
for i := 0; i < 100; i++ {
tv.Write([]byte(fmt.Sprintf("L%d\n", i)))
}
// retrieve the total text and see we have the 100 lines:
count := strings.Count(tv.GetText(true), "\n")
if count != 100 {
t.Fatalf("Expected 100 lines, got %d", count)
}
// now set the maximum lines to 20, this should clip the buffer:
tv.SetMaxLines(20)
// verify buffer was clipped:
count = len(strings.Split(tv.GetText(true), "\n"))
if count != 20 {
t.Fatalf("Expected 20 lines, got %d", count)
}
// append 100 more lines:
for i := 100; i < 200; i++ {
tv.Write([]byte(fmt.Sprintf("L%d\n", i)))
}
// Sice max lines is set to 20, we should still get 20 lines:
txt := tv.GetText(true)
lines := strings.Split(txt, "\n")
count = len(lines)
if count != 20 {
t.Fatalf("Expected 20 lines, got %d", count)
}
// and those 20 lines should be the last ones:
if lines[0] != "L181" {
t.Fatalf("Expected to get L181, got %s", lines[0])
}
}
func generateTestCases() []*textViewTestCase {
var cases []*textViewTestCase
for i := 0; i < 2; i++ {