1
1
mirror of https://github.com/walles/moar.git synced 2024-08-17 07:50:35 +03:00

Fix crash on paging down

Fixes #65.
This commit is contained in:
Johan Walles 2021-06-04 13:20:28 +02:00
parent 2a435c091b
commit fec9ad8149
2 changed files with 73 additions and 11 deletions

View File

@ -31,6 +31,15 @@ type RenderedLine struct {
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.
//
// 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
}
if sl.firstInputLineOneBased > sl.lastInputLineOneBased() {
sl.firstInputLineOneBased = sl.lastInputLineOneBased()
}
allPossibleLines := sl.renderAllLines()
// 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 {
// Count the length of the last line number
//
// Offsets figured out through trial-and-error...
lastLineOneBased := sl.inputLines.firstLineOneBased + len(sl.inputLines.lines) - 1
numberPrefixLength := len(formatNumber(uint(lastLineOneBased))) + 1
numberPrefixLength := len(formatNumber(uint(sl.lastInputLineOneBased()))) + 1
if numberPrefixLength < 4 {
// 4 = space for 3 digits followed by one whitespace
//

View File

@ -6,7 +6,7 @@ import (
"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}
lineContents := NewLine(contents).HighlightedTokens(nil)
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) {
testCropping(t, "abc", 0, 10, "abc")
testHorizontalCropping(t, "abc", 0, 10, "abc")
}
func TestCreateScreenLineCanScrollLeft(t *testing.T) {
testCropping(t, "abc", 1, 10, "<c")
testHorizontalCropping(t, "abc", 1, 10, "<c")
}
func TestCreateScreenLineCanScrollRight(t *testing.T) {
testCropping(t, "abc", 0, 1, "a>")
testHorizontalCropping(t, "abc", 0, 1, "a>")
}
func TestCreateScreenLineCanAlmostScrollRight(t *testing.T) {
testCropping(t, "abc", 0, 2, "abc")
testHorizontalCropping(t, "abc", 0, 2, "abc")
}
func TestCreateScreenLineCanScrollBoth(t *testing.T) {
testCropping(t, "abcde", 1, 3, "<c>")
testHorizontalCropping(t, "abcde", 1, 3, "<c>")
}
func TestCreateScreenLineCanAlmostScrollBoth(t *testing.T) {
testCropping(t, "abcd", 1, 3, "<cd")
testHorizontalCropping(t, "abcd", 1, 3, "<cd")
}
func TestEmpty(t *testing.T) {
@ -53,3 +53,55 @@ func TestEmpty(t *testing.T) {
assert.Equal(t, len(rendered), 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)
}