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: kill the program and restore terminal state #219

Merged
merged 1 commit into from Feb 8, 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
9 changes: 7 additions & 2 deletions standard_renderer.go
Expand Up @@ -32,6 +32,7 @@ type standardRenderer struct {
lastRender string
linesRendered int
useANSICompressor bool
once sync.Once

// essentially whether or not we're using the full size of the terminal
altScreenActive bool
Expand Down Expand Up @@ -72,7 +73,9 @@ func (r *standardRenderer) start() {
func (r *standardRenderer) stop() {
r.flush()
clearLine(r.out)
close(r.done)
r.once.Do(func() {
close(r.done)
})

if r.useANSICompressor {
if w, ok := r.out.(io.WriteCloser); ok {
Expand All @@ -84,7 +87,9 @@ func (r *standardRenderer) stop() {
// kill halts the renderer. The final frame will not be rendered.
func (r *standardRenderer) kill() {
clearLine(r.out)
close(r.done)
r.once.Do(func() {
close(r.done)
})
}

// listen waits for ticks on the ticker, or a signal to stop the renderer.
Expand Down
25 changes: 21 additions & 4 deletions tea.go
Expand Up @@ -97,6 +97,8 @@ type Program struct {
// is on by default.
CatchPanics bool

killc chan bool

console console.Console

// Stores the original reference to stdin for cases where input is not a
Expand Down Expand Up @@ -248,6 +250,7 @@ func NewProgram(model Model, opts ...ProgramOption) *Program {
input: os.Stdin,
msgs: make(chan Msg),
CatchPanics: true,
killc: make(chan bool, 1),
}

// Apply all options to the program.
Expand Down Expand Up @@ -486,6 +489,8 @@ func (p *Program) StartReturningModel() (Model, error) {
// Handle updates and draw.
for {
select {
case <-p.killc:
return nil, nil
case err := <-errs:
cancelContext()
waitForGoroutines(cancelReader.Cancel())
Expand Down Expand Up @@ -577,13 +582,25 @@ func (p *Program) Quit() {
p.Send(Quit())
}

// Kill stops the program immediately and restores the former terminal state.
// The final render that you would normally see when quitting will be skipped.
//
// This method is currently provisional. The method signature may alter
// slightly, or it may be removed in a future version of this package.
func (p *Program) Kill() {
p.killc <- true
p.shutdown(true)
}

// shutdown performs operations to free up resources and restore the terminal
// to its original state.
func (p *Program) shutdown(kill bool) {
if kill {
p.renderer.kill()
} else {
p.renderer.stop()
if p.renderer != nil {
if kill {
p.renderer.kill()
} else {
p.renderer.stop()
}
}
p.ExitAltScreen()
p.DisableMouseCellMotion()
Expand Down