diff --git a/commands.go b/commands.go index 9111638..dd3305e 100644 --- a/commands.go +++ b/commands.go @@ -119,6 +119,8 @@ func Tick(d time.Duration, fn func(time.Time) Msg) Cmd { // } // // cmd := Sequentially(saveStateCmd, Quit) +// +// Deprecated: use Sequence instead. func Sequentially(cmds ...Cmd) Cmd { return func() Msg { for _, cmd := range cmds { diff --git a/examples/sequence/main.go b/examples/sequence/main.go new file mode 100644 index 0000000..79f7e23 --- /dev/null +++ b/examples/sequence/main.go @@ -0,0 +1,40 @@ +package main + +// A simple example illustrating how to run a series of commands in order. + +import ( + "fmt" + "os" + + tea "github.com/charmbracelet/bubbletea" +) + +type model struct{} + +func (m model) Init() tea.Cmd { + return tea.Sequence( + tea.Println("A"), + tea.Println("B"), + tea.Println("C"), + tea.Quit, + ) +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg.(type) { + case tea.KeyMsg: + return m, tea.Quit + } + return m, nil +} + +func (m model) View() string { + return "" +} + +func main() { + if err := tea.NewProgram(model{}).Start(); err != nil { + fmt.Println("Uh oh:", err) + os.Exit(1) + } +} diff --git a/tea.go b/tea.go index 446a2bc..547e011 100644 --- a/tea.go +++ b/tea.go @@ -532,6 +532,17 @@ func (p *Program) StartReturningModel() (Model, error) { case execMsg: // NB: this blocks. p.exec(msg.cmd, msg.fn) + + case sequenceMsg: + go func() { + // Execute commands one at a time, in order. + for _, cmd := range msg { + select { + case p.msgs <- cmd(): + case <-p.ctx.Done(): + } + } + }() } // Process internal messages for the renderer. @@ -736,3 +747,14 @@ func (p *Program) Printf(template string, args ...interface{}) { messageBody: fmt.Sprintf(template, args...), } } + +// sequenceMsg is used interally to run the the given commands in order. +type sequenceMsg []Cmd + +// Sequence runs the given commands one at a time, in order. Contrast this with +// Batch, which runs commands concurrently. +func Sequence(cmds ...Cmd) Cmd { + return func() Msg { + return sequenceMsg(cmds) + } +}