Use huh? to create multi-field interactive forms in the terminal. Forms are composed of Groups (which act as pages), and each group contains Fields (like Select, Input, or Confirm). You can store user answers by passing pointers to variables into the .Value() method of each field. To execute the form, call form.Run().
package main
import (
"fmt"
"log"
"errors"
"charm.land/huh/v2"
)
var (
burger string
toppings []string
sauceLevel int
name string
instructions string
discount bool
)
func main() {
form := huh.NewForm(
huh.NewGroup(
huh.NewSelect[string]().
Title("Choose your burger").
Options(
huh.NewOption("Charmburger Classic", "classic"),
huh.NewOption("Chickwich", "chickwich"),
).
Value(&burger),
huh.NewMultiSelect[string]().
Title("Toppings").
Options(
huh.NewOption("Lettuce", "lettuce").Selected(true),
huh.NewOption("Cheese", "cheese"),
).
Limit(4).
Value(&toppings),
huh.NewSelect[int]().
Title("How much Charm Sauce?").
Options(
huh.NewOption("None", 0),
huh.NewOption("A little", 1),
).
Value(&sauceLevel),
),
huh.NewGroup(
huh.NewInput().
Title("What’s your name?").
Value(&name).
Validate(func(str string) error {
if str == "Frank" {
return errors.New("Sorry, we don’t serve customers named Frank.")
}
return nil
}),
huh.NewText().
Title("Special Instructions").
CharLimit(400).
Value(&instructions),
huh.NewConfirm().
Title("Would you like 15% off?").
Value(&discount),
),
)
err := form.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Order: %s with %v sauce level\n", burger, sauceLevel)
}