package confirmation import ( "fmt" "strings" "golang.org/x/term" ) type InputData struct { Notice string Question string } func New(data InputData) (*bool, error) { if data.Notice != "" { fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Notice) } if data.Question != "" { fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m?\033[38;5;247m]\033[0m %s (\033[38;5;34my\033[0m/\033[38;5;167mn\033[0m) \033[38;5;247m>>\033[3m\033[38;5;214m\n", data.Question) } var input string var chosen bool inputLoop: for { if _, err := fmt.Scanln(&input); err != nil { return nil, err } width, _, err := term.GetSize(0) if err != nil { return nil, err } switch strings.ToLower(input) { case "y", "yes": chosen = true break inputLoop case "n", "no": chosen = false break inputLoop default: var lineNum int if width == 0 { if data.Notice != "" { lineNum++ } lineNum += 2 } else { if data.Notice == "" { lineNum = ((len(data.Question) + 5 + width - 1) / width) + 1 } else { lineNum = ((len(data.Notice) + 5 + width) / width) + ((len(data.Question) + 5 + width - 1) / width) + 1 } } for i := 0; i < lineNum; i++ { fmt.Printf("\033[A\033[K\033[0G") } fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;167m!\033[38;5;247m]\033[0m Invalid input, please try again!\n") if data.Notice != "" { fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Notice) } if data.Question != "" { fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m?\033[38;5;247m]\033[0m %s (\033[38;5;34my\033[0m/\033[38;5;167mn\033[0m) \033[38;5;247m>>\033[3m\033[38;5;214m\n", data.Question) } continue inputLoop } } fmt.Println("\033[0m") return &chosen, nil }