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: add Sequence command for running commands in order #415

Merged
merged 1 commit into from
Aug 30, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
40 changes: 40 additions & 0 deletions examples/sequence/main.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
22 changes: 22 additions & 0 deletions tea.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,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.
Expand Down Expand Up @@ -732,3 +743,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)
}
}