Skip to content

Commit

Permalink
fix: renderer: keep a separate count of lines rendered in the alt screen
Browse files Browse the repository at this point in the history
We need to keep a separate count of lines rendered in the alt screen and
inline mode. This is because when we enter alt screen mode, the cursor
position is saved and the alt screen is cleared. Now when we exit the
alt screen mode, the cursor position is restored so we don't need to
move the cursor to the beginning of the section that we rendered.

To fix this, we keep a separate count of lines rendered in the alt screen
mode and inline mode.

Related: #1013
Fixes: #1241
Fixes: #1248
  • Loading branch information
aymanbagabas committed Nov 22, 2024
1 parent 2314d4c commit 6dc00b5
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions standard_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type standardRenderer struct {
lastRender string
lastRenderedLines []string
linesRendered int
altLinesRendered int
useANSICompressor bool
once sync.Once

Expand Down Expand Up @@ -170,7 +171,9 @@ func (r *standardRenderer) flush() {
buf := &bytes.Buffer{}

// Moving to the beginning of the section, that we rendered.
if r.linesRendered > 1 {
if r.altScreenActive {
buf.WriteString(ansi.HomeCursorPosition)
} else if r.linesRendered > 1 {
buf.WriteString(ansi.CursorUp(r.linesRendered - 1))
}

Expand Down Expand Up @@ -255,20 +258,29 @@ func (r *standardRenderer) flush() {
}
}

lastLinesRendered := r.linesRendered
if r.altScreenActive {
lastLinesRendered = r.altLinesRendered
}

// Clearing left over content from last render.
if r.linesRendered > len(newLines) {
if lastLinesRendered > len(newLines) {
buf.WriteString(ansi.EraseScreenBelow)
}

r.linesRendered = len(newLines)
if r.altScreenActive {
r.altLinesRendered = len(newLines)
} else {
r.linesRendered = len(newLines)
}

// Make sure the cursor is at the start of the last line to keep rendering
// behavior consistent.
if r.altScreenActive {
// This case fixes a bug in macOS terminal. In other terminals the
// other case seems to do the job regardless of whether or not we're
// using the full terminal window.
buf.WriteString(ansi.SetCursorPosition(0, r.linesRendered))
buf.WriteString(ansi.SetCursorPosition(0, len(newLines)))
} else {
buf.WriteString(ansi.CursorLeft(r.width))
}
Expand Down Expand Up @@ -352,6 +364,9 @@ func (r *standardRenderer) enterAltScreen() {
r.execute(ansi.ShowCursor)
}

// Entering the alt screen resets the lines rendered count.
r.altLinesRendered = 0

r.repaint()
}

Expand Down

0 comments on commit 6dc00b5

Please sign in to comment.