diff --git a/m/screenLines.go b/m/screenLines.go index e9356af..ab6fc80 100644 --- a/m/screenLines.go +++ b/m/screenLines.go @@ -96,8 +96,9 @@ func (p *Pager) renderScreenLines() (lines [][]twin.Cell, statusText string) { // The returned lines are display ready, meaning that they come with horizontal // scroll markers and line numbers as necessary. // -// The maximum number of lines returned by this method will be one less than the -// screen height, leaving space for the status line. +// The maximum number of lines returned by this method is limited by the screen +// height. If the status line is visible, you'll get at most one less than the +// screen height from this method. func (p *Pager) renderLines() ([]renderedLine, string) { _, height := p.screen.Size() wantedLineCount := height - 1 diff --git a/m/scrollPosition.go b/m/scrollPosition.go index b726010..6cdfa3f 100644 --- a/m/scrollPosition.go +++ b/m/scrollPosition.go @@ -268,11 +268,12 @@ func (p *Pager) scrollToEnd() { if inputLineCount == 0 { return } + lastInputLineNumberOneBased := inputLineCount - inputLine := p.reader.GetLine(inputLineCount) - screenLines := p.renderLine(inputLine, 0) + lastInputLine := p.reader.GetLine(lastInputLineNumberOneBased) + screenLines := p.renderLine(lastInputLine, lastInputLineNumberOneBased) - p.scrollPosition.internalDontTouch.lineNumberOneBased = inputLineCount + p.scrollPosition.internalDontTouch.lineNumberOneBased = lastInputLineNumberOneBased p.scrollPosition.internalDontTouch.deltaScreenLines = len(screenLines) - 1 } @@ -280,14 +281,26 @@ func (p *Pager) scrollToEnd() { // has pressed the down arrow enough times. func (p *Pager) isScrolledToEnd() bool { inputLineCount := p.reader.GetLineCount() - lastInputLineOneBased := inputLineCount - - lastVisiblePosition := p.getLastVisiblePosition() - if lastVisiblePosition == nil { + if inputLineCount == 0 { // No lines available, which means we can't scroll any further down return true } - return lastVisiblePosition.internalDontTouch.lineNumberOneBased == lastInputLineOneBased + lastInputLineNumberOneBased := inputLineCount + + visibleLines, _ := p.renderLines() + lastVisibleLine := visibleLines[len(visibleLines)-1] + if lastVisibleLine.inputLineOneBased != lastInputLineNumberOneBased { + // Last input line is not on the screen + return false + } + + lastInputLine := p.reader.GetLine(lastInputLineNumberOneBased) + lastInputLineRendered := p.renderLine(lastInputLine, lastInputLineNumberOneBased) + lastRenderedSubLine := lastInputLineRendered[len(lastInputLineRendered)-1] + + // If the last visible subline is the same as the last possible subline then + // we're at the bottom + return lastVisibleLine.wrapIndex == lastRenderedSubLine.wrapIndex } // Returns nil if there are no lines