mirror of
https://github.com/walles/moar.git
synced 2024-09-11 12:15:43 +03:00
parent
2a435c091b
commit
fec9ad8149
@ -31,6 +31,15 @@ type RenderedLine struct {
|
|||||||
cells []twin.Cell
|
cells []twin.Cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sl *ScreenLines) lastInputLineOneBased() int {
|
||||||
|
if sl.inputLines.lines == nil {
|
||||||
|
panic("nil input lines, cannot make up a last input line number")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offsets figured out through trial-and-error...
|
||||||
|
return sl.inputLines.firstLineOneBased + len(sl.inputLines.lines) - 1
|
||||||
|
}
|
||||||
|
|
||||||
// Render screen lines into an array of lines consisting of Cells.
|
// Render screen lines into an array of lines consisting of Cells.
|
||||||
//
|
//
|
||||||
// The second return value is the same as firstInputLineOneBased, but decreased
|
// The second return value is the same as firstInputLineOneBased, but decreased
|
||||||
@ -45,6 +54,10 @@ func (sl *ScreenLines) renderScreenLines() ([][]twin.Cell, int) {
|
|||||||
sl.firstInputLineOneBased = 1
|
sl.firstInputLineOneBased = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sl.firstInputLineOneBased > sl.lastInputLineOneBased() {
|
||||||
|
sl.firstInputLineOneBased = sl.lastInputLineOneBased()
|
||||||
|
}
|
||||||
|
|
||||||
allPossibleLines := sl.renderAllLines()
|
allPossibleLines := sl.renderAllLines()
|
||||||
|
|
||||||
// Find which index in allPossibleLines the user wants to see at the top of
|
// Find which index in allPossibleLines the user wants to see at the top of
|
||||||
@ -111,10 +124,7 @@ func (sl *ScreenLines) toScreenLinesArray(allPossibleLines []RenderedLine, first
|
|||||||
|
|
||||||
func (sl *ScreenLines) renderAllLines() []RenderedLine {
|
func (sl *ScreenLines) renderAllLines() []RenderedLine {
|
||||||
// Count the length of the last line number
|
// Count the length of the last line number
|
||||||
//
|
numberPrefixLength := len(formatNumber(uint(sl.lastInputLineOneBased()))) + 1
|
||||||
// Offsets figured out through trial-and-error...
|
|
||||||
lastLineOneBased := sl.inputLines.firstLineOneBased + len(sl.inputLines.lines) - 1
|
|
||||||
numberPrefixLength := len(formatNumber(uint(lastLineOneBased))) + 1
|
|
||||||
if numberPrefixLength < 4 {
|
if numberPrefixLength < 4 {
|
||||||
// 4 = space for 3 digits followed by one whitespace
|
// 4 = space for 3 digits followed by one whitespace
|
||||||
//
|
//
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testCropping(t *testing.T, contents string, firstIndex int, lastIndex int, expected string) {
|
func testHorizontalCropping(t *testing.T, contents string, firstIndex int, lastIndex int, expected string) {
|
||||||
screenLines := ScreenLines{width: 1 + lastIndex - firstIndex, leftColumnZeroBased: firstIndex}
|
screenLines := ScreenLines{width: 1 + lastIndex - firstIndex, leftColumnZeroBased: firstIndex}
|
||||||
lineContents := NewLine(contents).HighlightedTokens(nil)
|
lineContents := NewLine(contents).HighlightedTokens(nil)
|
||||||
screenLine := screenLines.createScreenLine(nil, 0, lineContents)
|
screenLine := screenLines.createScreenLine(nil, 0, lineContents)
|
||||||
@ -14,27 +14,27 @@ func testCropping(t *testing.T, contents string, firstIndex int, lastIndex int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLine(t *testing.T) {
|
func TestCreateScreenLine(t *testing.T) {
|
||||||
testCropping(t, "abc", 0, 10, "abc")
|
testHorizontalCropping(t, "abc", 0, 10, "abc")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLineCanScrollLeft(t *testing.T) {
|
func TestCreateScreenLineCanScrollLeft(t *testing.T) {
|
||||||
testCropping(t, "abc", 1, 10, "<c")
|
testHorizontalCropping(t, "abc", 1, 10, "<c")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLineCanScrollRight(t *testing.T) {
|
func TestCreateScreenLineCanScrollRight(t *testing.T) {
|
||||||
testCropping(t, "abc", 0, 1, "a>")
|
testHorizontalCropping(t, "abc", 0, 1, "a>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLineCanAlmostScrollRight(t *testing.T) {
|
func TestCreateScreenLineCanAlmostScrollRight(t *testing.T) {
|
||||||
testCropping(t, "abc", 0, 2, "abc")
|
testHorizontalCropping(t, "abc", 0, 2, "abc")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLineCanScrollBoth(t *testing.T) {
|
func TestCreateScreenLineCanScrollBoth(t *testing.T) {
|
||||||
testCropping(t, "abcde", 1, 3, "<c>")
|
testHorizontalCropping(t, "abcde", 1, 3, "<c>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateScreenLineCanAlmostScrollBoth(t *testing.T) {
|
func TestCreateScreenLineCanAlmostScrollBoth(t *testing.T) {
|
||||||
testCropping(t, "abcd", 1, 3, "<cd")
|
testHorizontalCropping(t, "abcd", 1, 3, "<cd")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmpty(t *testing.T) {
|
func TestEmpty(t *testing.T) {
|
||||||
@ -53,3 +53,55 @@ func TestEmpty(t *testing.T) {
|
|||||||
assert.Equal(t, len(rendered), 0)
|
assert.Equal(t, len(rendered), 0)
|
||||||
assert.Equal(t, firstScreenLine, 0)
|
assert.Equal(t, firstScreenLine, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOverflowDown(t *testing.T) {
|
||||||
|
// Set up a single line input
|
||||||
|
line := Line{
|
||||||
|
raw: "hej",
|
||||||
|
}
|
||||||
|
inputLines := InputLines{
|
||||||
|
lines: []*Line{&line},
|
||||||
|
firstLineOneBased: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a single line screen
|
||||||
|
screenLines := ScreenLines{
|
||||||
|
inputLines: &inputLines,
|
||||||
|
height: 1,
|
||||||
|
width: 10, // Longer than the raw line, we're testing vertical overflow, not horizontal
|
||||||
|
|
||||||
|
// This value can be anything and should be clipped, that's what we're testing
|
||||||
|
firstInputLineOneBased: 42,
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered, firstScreenLine := screenLines.renderScreenLines()
|
||||||
|
assert.Equal(t, len(rendered), 1)
|
||||||
|
assert.Equal(t, "hej", rowToString(rendered[0]))
|
||||||
|
assert.Equal(t, firstScreenLine, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOverflowUp(t *testing.T) {
|
||||||
|
// Set up a single line input
|
||||||
|
line := Line{
|
||||||
|
raw: "hej",
|
||||||
|
}
|
||||||
|
inputLines := InputLines{
|
||||||
|
lines: []*Line{&line},
|
||||||
|
firstLineOneBased: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a single line screen
|
||||||
|
screenLines := ScreenLines{
|
||||||
|
inputLines: &inputLines,
|
||||||
|
height: 1,
|
||||||
|
width: 10, // Longer than the raw line, we're testing vertical overflow, not horizontal
|
||||||
|
|
||||||
|
// This value can be anything and should be clipped, that's what we're testing
|
||||||
|
firstInputLineOneBased: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered, firstScreenLine := screenLines.renderScreenLines()
|
||||||
|
assert.Equal(t, len(rendered), 1)
|
||||||
|
assert.Equal(t, "hej", rowToString(rendered[0]))
|
||||||
|
assert.Equal(t, firstScreenLine, 1)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user