Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support a Clear command #421

Merged
merged 2 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions nil_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ func (n nilRenderer) stop() {}
func (n nilRenderer) kill() {}
func (n nilRenderer) write(v string) {}
func (n nilRenderer) repaint() {}
func (n nilRenderer) clearScreen() {}
func (n nilRenderer) altScreen() bool { return false }
func (n nilRenderer) enterAltScreen() {}
func (n nilRenderer) exitAltScreen() {}
Expand Down
3 changes: 3 additions & 0 deletions renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type renderer interface {
// in succession.
repaint()

// Clears the terminal.
clearScreen()

// Whether or not the alternate screen buffer is enabled.
altScreen() bool
// Enable the alternate screen buffer.
Expand Down
14 changes: 14 additions & 0 deletions screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ type WindowSizeMsg struct {
Height int
}

// ClearScreen is a special command that tells the program to clear the screen
// before the next update. This can be used to move the cursor to the top left
// of the screen and clear visual clutter when the alt screen is not in use.
//
// Note that it should never be necessary to call ClearScreen() for regular
// redraws.
func ClearScreen() Msg {
return clearScreenMsg{}
}

// clearScreenMsg is an internal message that signals to clear the screen.
// You can send a clearScreenMsg with ClearScreen.
type clearScreenMsg struct{}

// EnterAltScreen is a special command that tells the Bubble Tea program to
// enter the alternate screen buffer.
//
Expand Down
20 changes: 18 additions & 2 deletions standard_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ func (r *standardRenderer) repaint() {
r.lastRender = ""
}

func (r *standardRenderer) clearScreen() {
r.mtx.Lock()
defer r.mtx.Unlock()

r.out.ClearScreen()
r.out.MoveCursor(1, 1)
}

func (r *standardRenderer) altScreen() bool {
return r.altScreenActive
}
Expand All @@ -254,9 +262,17 @@ func (r *standardRenderer) enterAltScreen() {
defer r.mtx.Unlock()

r.altScreenActive = true

r.out.AltScreen()

// 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).
//
// Note: we can't use r.clearScreen() here because the mutex is already
// locked.
r.out.ClearScreen()
r.out.MoveCursor(1, 1)

r.repaint()
}

Expand All @@ -265,8 +281,8 @@ func (r *standardRenderer) exitAltScreen() {
defer r.mtx.Unlock()

r.altScreenActive = false

r.out.ExitAltScreen()

r.repaint()
}

Expand Down
3 changes: 3 additions & 0 deletions tea.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ func (p *Program) StartReturningModel() (Model, error) {
p.shutdown(false)
return model, nil

case clearScreenMsg:
p.renderer.clearScreen()

case enterAltScreenMsg:
p.renderer.enterAltScreen()

Expand Down