Skip to content

Commit

Permalink
Merge branch 'johan/quit-if-one-screen'
Browse files Browse the repository at this point in the history
Fixes #113
  • Loading branch information
walles committed May 18, 2023
2 parents 62aa81a + 0427d26 commit 687aba6
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 68 deletions.
29 changes: 26 additions & 3 deletions m/pager.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ type Pager struct {

WrapLongLines bool

// Ref: https://github.com/walles/moar/issues/113
QuitIfOneScreen bool

// Ref: https://github.com/walles/moar/issues/94
ScrollLeftHint twin.Cell
ScrollRightHint twin.Cell
Expand Down Expand Up @@ -207,6 +210,7 @@ func (p *Pager) Quit() {
p.preHelpState = nil
}

// Negative deltas move left instead
func (p *Pager) moveRight(delta int) {
if p.ShowLineNumbers && delta > 0 {
p.ShowLineNumbers = false
Expand Down Expand Up @@ -460,8 +464,27 @@ func (p *Pager) StartPaging(screen twin.Screen) {
spinner := ""
for !p.quit {
if len(screen.Events()) == 0 {
// Nothing more to process for now, redraw the screen!
p.redraw(spinner)
// Nothing more to process for now, redraw the screen
overflow := p.redraw(spinner)

// Ref:
// https://github.com/gwsw/less/blob/ff8869aa0485f7188d942723c9fb50afb1892e62/command.c#L828-L831
if p.QuitIfOneScreen && overflow == didFit && !p.isShowingHelp {
// Do the slow (atomic) checks only if the fast ones (no locking
// required) passed
if p.reader.done.Load() && p.reader.highlightingDone.Load() {
// Ref:
// https://github.com/walles/moar/issues/113#issuecomment-1368294132
p.ShowLineNumbers = false // Requires a redraw to take effect, see below
p.DeInit = false
p.quit = true

// Without this the line numbers setting ^ won't take effect
p.redraw(spinner)

break
}
}
}

event := <-screen.Events()
Expand Down Expand Up @@ -519,7 +542,7 @@ func (p *Pager) StartPaging(screen twin.Screen) {
func (p *Pager) ReprintAfterExit() error {
// Figure out how many screen lines are used by pager contents

renderedScreenLines, _ := p.renderScreenLines()
renderedScreenLines, _, _ := p.renderScreenLines()
screenLinesCount := len(renderedScreenLines)

_, screenHeight := p.screen.Size()
Expand Down
35 changes: 23 additions & 12 deletions m/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Reader struct {
replaced bool

done *atomic.Bool
highlightingDone *atomic.Bool // Used by tests
highlightingDone *atomic.Bool
moreLinesAdded chan bool
}

Expand Down Expand Up @@ -489,26 +489,30 @@ func (r *Reader) GetLine(lineNumberOneBased int) *Line {
}

// GetLines gets the indicated lines from the input
func (r *Reader) GetLines(firstLineOneBased int, wantedLineCount int) *InputLines {
//
// Overflow state will be didFit if we returned all lines we currently have, or
// didOverflow otherwise.
func (r *Reader) GetLines(firstLineOneBased int, wantedLineCount int) (*InputLines, overflowState) {
r.lock.Lock()
defer r.lock.Unlock()
return r.getLinesUnlocked(firstLineOneBased, wantedLineCount)
}

func (r *Reader) getLinesUnlocked(firstLineOneBased int, wantedLineCount int) *InputLines {
func (r *Reader) getLinesUnlocked(firstLineOneBased int, wantedLineCount int) (*InputLines, overflowState) {
if firstLineOneBased < 1 {
firstLineOneBased = 1
}

if len(r.lines) == 0 {
return &InputLines{
lines: nil,
lines: nil,

// The line number set here won't matter, we'll clip it anyway when we get it back
firstLineOneBased: 0,
// The line number set here won't matter, we'll clip it anyway when we get it back
firstLineOneBased: 0,

statusText: r.createStatusUnlocked(0),
}
statusText: r.createStatusUnlocked(0),
},
didFit // Empty files always fit
}

firstLineZeroBased := firstLineOneBased - 1
Expand All @@ -530,11 +534,18 @@ func (r *Reader) getLinesUnlocked(firstLineOneBased int, wantedLineCount int) *I
return r.getLinesUnlocked(firstLineOneBased, wantedLineCount)
}

return &InputLines{
lines: r.lines[firstLineZeroBased : lastLineZeroBased+1],
firstLineOneBased: firstLineOneBased,
statusText: r.createStatusUnlocked(lastLineZeroBased + 1),
returnLines := r.lines[firstLineZeroBased : lastLineZeroBased+1]
overflow := didFit
if len(returnLines) != len(r.lines) {
overflow = didOverflow // We're not returning all available lines
}

return &InputLines{
lines: returnLines,
firstLineOneBased: firstLineOneBased,
statusText: r.createStatusUnlocked(lastLineZeroBased + 1),
},
overflow
}

// Replace reader contents with the given text and mark as done
Expand Down
28 changes: 18 additions & 10 deletions m/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func testGetLineCount(t *testing.T, reader *Reader) {
func testGetLines(t *testing.T, reader *Reader) {
t.Logf("Testing file: %s...", *reader.name)

lines := reader.GetLines(1, 10)
lines, _ := reader.GetLines(1, 10)
if len(lines.lines) > 10 {
t.Errorf("Asked for 10 lines, got too many: %d", len(lines.lines))
}
Expand All @@ -70,14 +70,14 @@ func testGetLines(t *testing.T, reader *Reader) {
}

// Test clipping at the end
lines = reader.GetLines(math.MaxInt32, 10)
lines, _ = reader.GetLines(math.MaxInt32, 10)
if len(lines.lines) != 10 {
t.Errorf("Asked for 10 lines but got %d", len(lines.lines))
return
}

startOfLastSection := lines.firstLineOneBased
lines = reader.GetLines(startOfLastSection, 10)
lines, _ = reader.GetLines(startOfLastSection, 10)
if lines.firstLineOneBased != startOfLastSection {
t.Errorf("Expected start line %d when asking for the last 10 lines, got %d",
startOfLastSection, lines.firstLineOneBased)
Expand All @@ -89,7 +89,7 @@ func testGetLines(t *testing.T, reader *Reader) {
return
}

lines = reader.GetLines(startOfLastSection+1, 10)
lines, _ = reader.GetLines(startOfLastSection+1, 10)
if lines.firstLineOneBased != startOfLastSection {
t.Errorf("Expected start line %d when asking for the last+1 10 lines, got %d",
startOfLastSection, lines.firstLineOneBased)
Expand All @@ -101,7 +101,7 @@ func testGetLines(t *testing.T, reader *Reader) {
return
}

lines = reader.GetLines(startOfLastSection-1, 10)
lines, _ = reader.GetLines(startOfLastSection-1, 10)
if lines.firstLineOneBased != startOfLastSection-1 {
t.Errorf("Expected start line %d when asking for the last-1 10 lines, got %d",
startOfLastSection, lines.firstLineOneBased)
Expand Down Expand Up @@ -232,10 +232,15 @@ func TestGetLongLine(t *testing.T) {
panic(err)
}

lines := reader.GetLines(1, 5)
lines, overflow := reader.GetLines(1, 5)
assert.Equal(t, lines.firstLineOneBased, 1)
assert.Equal(t, len(lines.lines), 1)

// This fits because we got all (one) input lines. Given the line length the
// line is unlikely to fit on screen, but that's not what this didFit is
// about.
assert.Equal(t, overflow, didFit)

line := lines.lines[0]
assert.Assert(t, strings.HasPrefix(line.Plain(), "1 2 3 4"), "<%s>", line)
assert.Assert(t, strings.HasSuffix(line.Plain(), "0123456789"), line)
Expand All @@ -255,7 +260,8 @@ func getReaderWithLineCount(totalLines int) *Reader {
func testStatusText(t *testing.T, fromLine int, toLine int, totalLines int, expected string) {
testMe := getReaderWithLineCount(totalLines)
linesRequested := toLine - fromLine + 1
statusText := testMe.GetLines(fromLine, linesRequested).statusText
lines, _ := testMe.GetLines(fromLine, linesRequested)
statusText := lines.statusText
assert.Equal(t, statusText, expected)
}

Expand All @@ -276,8 +282,9 @@ func TestStatusText(t *testing.T) {
panic(err)
}

statusText := testMe.GetLines(0, 0).statusText
assert.Equal(t, statusText, "empty: <empty>")
line, overflow := testMe.GetLines(0, 0)
assert.Equal(t, line.statusText, "empty: <empty>")
assert.Equal(t, overflow, didFit) // Empty always fits
}

func testCompressedFile(t *testing.T, filename string) {
Expand All @@ -291,7 +298,8 @@ func testCompressedFile(t *testing.T, filename string) {
panic(err)
}

assert.Equal(t, reader.GetLines(1, 5).lines[0].Plain(), "This is a compressed file", "%s", filename)
lines, _ := reader.GetLines(1, 5)
assert.Equal(t, lines.lines[0].Plain(), "This is a compressed file", "%s", filename)
}

func TestCompressedFiles(t *testing.T) {
Expand Down
Loading

0 comments on commit 687aba6

Please sign in to comment.