charmbracelet / bubbletea

A powerful little TUI framework 🏗
MIT License
28.05k stars 808 forks source link

Automatic command chaining: Cmd -> Cmd -> Msg #984

Open antonmedv opened 7 months ago

antonmedv commented 7 months ago

Is your feature request related to a problem? Please describe. No.

Describe the solution you'd like

    switch msg := msg.(type) {
    case tea.Cmd:
        return m, msg
    }

Describe alternatives you've considered N/A

Additional context I have a Cmd which produces other Cmds:


func (m *Model) Create(name string) tea.Cmd {
    return func() tea.Msg {
        if !isAlphaNumeric(name) {
            return tea.Println("Only alphanumeric characters are allowed.")
        }

        var game db.Game
        m.app.db.Where("name = ?", name).First(&game)
        if game.ID != 0 {
            return tea.Printf("Game %q already exists. Please choose another name.", name)
        }

        game = db.Game{
            Name:       name,
        }
        if err := m.app.db.Create(&game).Error; err != nil {
            slog.Error("Failed to create game", "err", err.Error())
        }
        return tea.Printf("Game created!")
    }
}

It will be cool it cmds can produce other cmds.

This is easily solvable via:

    switch msg := msg.(type) {
    case tea.Cmd:
        return m, msg
    }

But as Msg == any it took me some time to understand why nothing is printed. What about adding this as default behavior?

KevM commented 7 months ago

When I run into this concern. I return a message type that when handled in the Update creates the desired tea.Cmd