Skip to content

Commit

Permalink
feat: allow to suspend bubbletea programs
Browse files Browse the repository at this point in the history
closes #497
closes #1053
  • Loading branch information
caarlos0 committed Jul 11, 2024
1 parent 0208ac5 commit 7cac56c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
11 changes: 11 additions & 0 deletions exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ func (c *osExecCommand) SetStderr(w io.Writer) {
}
}

func (p *Program) suspend() {
if err := p.ReleaseTerminal(); err != nil {
// If we can't release input, abort.
return
}

suspendProcess()

_ = p.RestoreTerminal()
}

// exec runs an ExecCommand and delivers the results to the program as a Msg.
func (p *Program) exec(c ExecCommand, fn ExecCallback) {
if err := p.ReleaseTerminal(); err != nil {
Expand Down
17 changes: 17 additions & 0 deletions tea.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,22 @@ func Quit() Msg {
return QuitMsg{}
}

// Quit is a special command that tells the Bubble Tea program to suspend.
func Suspend() Msg {
return SuspendMsg{}
}

// QuitMsg signals that the program should quit. You can send a QuitMsg with
// Quit.
type QuitMsg struct{}

// SuspendMsg signals the program should suspend.
// This usually happens when ctrl+z is pressed on common programs, but since
// bubbletea puts the terminal in raw mode, we need to handle it in a
// per-program basis.
// You can send this message with Suspend.
type SuspendMsg struct{}

// NewProgram creates a new Program.
func NewProgram(model Model, opts ...ProgramOption) *Program {
p := &Program{
Expand Down Expand Up @@ -327,6 +339,11 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
case QuitMsg:
return model, nil

case SuspendMsg:
if suspendSupported {
p.suspend()
}

case clearScreenMsg:
p.renderer.clearScreen()

Expand Down
8 changes: 8 additions & 0 deletions tty_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package tea
import (
"fmt"
"os"
"syscall"

"github.com/charmbracelet/x/term"
)
Expand Down Expand Up @@ -34,3 +35,10 @@ func openInputTTY() (*os.File, error) {
}
return f, nil
}

var suspendSupported = true

// Send SIGTSTP to the entire process group.
func suspendProcess() {
_ = syscall.Kill(0, syscall.SIGTSTP)
}
4 changes: 4 additions & 0 deletions tty_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,7 @@ func openInputTTY() (*os.File, error) {
}
return f, nil
}

var suspendSupported = false

func suspendProcess() {}

0 comments on commit 7cac56c

Please sign in to comment.