func (i *InteractiveSession) AskPasswordPrompt(prompt string, validators ...ValidationFunc) string {
	return askPassword(i, prompt, validators...)
}
AskPasswordPrompt is a terminator that asks for a password with a custom prompt
package clt
import (
	"bufio"
	"fmt"
	"io"
	"sort"
	"os"
	"strings"
	"golang.org/x/crypto/ssh/terminal"
)
type getOpt int
const (
	noColon getOpt = iota
)
type InteractiveSession struct {
	Prompt  string
	Default string
	ValHint string
	response string
	input    *bufio.Reader
	output   io.Writer
}
func NewInteractiveSession(opts ...SessionOption) *InteractiveSession {
	i := &InteractiveSession{
		input:  bufio.NewReader(os.Stdin),
		output: os.Stdout,
	}
	for _, opt := range opts {
		opt(i)
	}
	return i
}
type SessionOption func(i *InteractiveSession)
func WithInput(r io.Reader) SessionOption {
	return func(i *InteractiveSession) {
		i.input = bufio.NewReader(r)
	}
}
func WithOutput(w io.Writer) SessionOption {
	return func(i *InteractiveSession) {
		i.output = w
	}
}
func (i *InteractiveSession) Reset() {
	i.Prompt = ""
	i.Default = ""
	i.ValHint = ""
	i.response = ""
}
func (i *InteractiveSession) Say(format string, args ...interface{}) *InteractiveSession {
	fmt.Fprintf(i.output, fmt.Sprintf("\n%s\n", format), args...)
	return i
}
func (i *InteractiveSession) Pause() {
	i.Prompt = "\nPress [Enter] to continue."
	i.get(noColon)
}
func (i *InteractiveSession) PauseWithPrompt(format string, args ...interface{}) {
	i.Prompt = fmt.Sprintf(format, args...)
	i.get(noColon)
}
func (i *InteractiveSession) get(opts ...getOpt) (err error) {
	contains := func(wanted getOpt) bool {
		for _, opt := range opts {
			if opt == wanted {
				return true
			}
		}
		return false
	}
	if i.output == nil {
		i.output = bufio.NewWriter(os.Stdout)
	}
	if i.input == nil {
		i.input = bufio.NewReader(os.Stdin)
	}
	switch {
	case len(i.Default) > 0:
		fmt.Fprintf(i.output, "%s  [%s]: ", i.Prompt, i.Default)
	case len(i.ValHint) > 0:
		fmt.Fprintf(i.output, "%s (%s): ", i.Prompt, i.ValHint)
	case contains(noColon):
		fmt.Fprintf(i.output, "%s", i.Prompt)
	case len(i.Prompt) > 0:
		fmt.Fprintf(i.output, "%s: ", i.Prompt)
	default:
	}
	i.response, err = i.input.ReadString('\n')
	if err != nil {
		return err
	}
	i.response = strings.TrimRight(i.response, " \n\r")
	if len(i.Default) > 0 && len(i.response) == 0 {
		switch i.Default {
		case "y/N":
			i.response = "n"
		case "Y/n":
			i.response = "y"
		default:
			i.response = i.Default
		}
	}
	return nil
}
func (i *InteractiveSession) Warn(format string, args ...interface{}) *InteractiveSession {
	fmt.Fprintf(i.output, "\n%s: %s\n", Styled(Yellow).ApplyTo("Warning"), fmt.Sprintf(format, args...))
	return i
}
func (i *InteractiveSession) Error(format string, args ...interface{}) {
	fmt.Fprintf(i.output, "\n\n%s: %s\n", Styled(Red).ApplyTo("Error:"), fmt.Sprintf(format, args...))
	os.Exit(1)
}
func (i *InteractiveSession) Ask(prompt string, validators ...ValidationFunc) string {
	return i.ask(prompt, "", "", validators...)
}
func (i *InteractiveSession) AskWithDefault(prompt string, defaultChoice string, validators ...ValidationFunc) string {
	return i.ask(prompt, defaultChoice, "", validators...)
}
func (i *InteractiveSession) AskWithHint(prompt string, hint string, validators ...ValidationFunc) string {
	return i.ask(prompt, "", hint, validators...)
}
func (i *InteractiveSession) ask(prompt string, def string, hint string, validators ...ValidationFunc) string {
	i.Prompt = prompt
	i.Default = def
	i.ValHint = hint
	i.get()
	for _, validator := range validators {
		if ok, err := validator(i.response); !ok {
			i.Say("\nError: %s\n\n", err)
			i.ask(prompt, def, hint, validators...)
		}
	}
	return i.response
}
func (i *InteractiveSession) AskPassword(validators ...ValidationFunc) string {
	return askPassword(i, "Password: ", validators...)
}