Skip to content

Commit

Permalink
fix: cursor position adjustment after exiting alt screen (#1241)
Browse files Browse the repository at this point in the history
* fix cursor position handling after exiting alt screen mode

* avoid moving cursor when lines rendered before alt screen is zero
  • Loading branch information
semihbkgr authored Nov 19, 2024
1 parent 76b0f81 commit 4ad0792
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions standard_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ type standardRenderer struct {

// lines explicitly set not to render
ignoreLines map[int]struct{}

// lines rendered before entering alt screen mode
linesRenderedBeforeAltScreen int
}

// newRenderer creates a new renderer. Normally you'll want to initialize it
Expand Down Expand Up @@ -334,6 +337,10 @@ func (r *standardRenderer) enterAltScreen() {
r.altScreenActive = true
r.execute(ansi.EnableAltScreenBuffer)

// Save the current line count before entering the alternate screen mode.
// This allows us to compare and adjust the cursor position when exiting the alternate screen.
r.linesRenderedBeforeAltScreen = r.linesRendered

// Ensure that the terminal is cleared, even when it doesn't support
// alt screen (or alt screen support is disabled, like GNU screen by
// default).
Expand Down Expand Up @@ -366,6 +373,18 @@ func (r *standardRenderer) exitAltScreen() {
r.altScreenActive = false
r.execute(ansi.DisableAltScreenBuffer)

// Adjust cursor and screen
if r.linesRendered < r.linesRenderedBeforeAltScreen {
// If fewer lines were rendered in the alternate screen, move the cursor up
// to align with the previous normal screen position and clear any remaining lines.
r.execute(ansi.CursorUp(r.linesRenderedBeforeAltScreen - r.linesRendered))
r.execute(ansi.EraseScreenBelow)
} else if r.linesRendered > r.linesRenderedBeforeAltScreen && r.linesRenderedBeforeAltScreen > 0 {
// If more lines were rendered in the alternate screen, move the cursor down
// to align with the new position.
r.execute(ansi.CursorDown(r.linesRendered - r.linesRenderedBeforeAltScreen))
}

// cmd.exe and other terminals keep separate cursor states for the AltScreen
// and the main buffer. We have to explicitly reset the cursor visibility
// whenever we exit AltScreen.
Expand Down

0 comments on commit 4ad0792

Please sign in to comment.