prompt.go
func (p *Prompt) Run() (string, error) {
	var err error

	err = p.prepareTemplates()
	if err != nil {
		return "", err
	}

	c := &readline.Config{
		Stdin:          p.stdin,
		Stdout:         p.stdout,
		EnableMask:     p.Mask != 0,
		MaskRune:       p.Mask,
		HistoryLimit:   -1,
		VimMode:        p.IsVimMode,
		UniqueEditLine: true,
	}

	err = c.Init()
	if err != nil {
		return "", err
	}

	rl, err := readline.NewEx(c)
	if err != nil {
		return "", err
	}
	// we're taking over the cursor,  so stop showing it.
	rl.Write([]byte(hideCursor))
	sb := screenbuf.New(rl)

	validFn := func(x string) error {
		return nil
	}
	if p.Validate != nil {
		validFn = p.Validate
	}

	var inputErr error
	input := p.Default
	if p.IsConfirm {
		input = ""
	}
	eraseDefault := input != "" && !p.AllowEdit
	cur := NewCursor(input, p.Pointer, eraseDefault)

	listen := func(input []rune, pos int, key rune) ([]rune, int, bool) {
		_, _, keepOn := cur.Listen(input, pos, key)
		err := validFn(cur.Get())
		var prompt []byte

		if err != nil {
			prompt = render(p.Templates.invalid, p.Label)
		} else {
			prompt = render(p.Templates.valid, p.Label)
			if p.IsConfirm {
				prompt = render(p.Templates.prompt, p.Label)
			}
		}

		echo := cur.Format()
		if p.Mask != 0 {
			echo = cur.FormatMask(p.Mask)
		}

		prompt = append(prompt, []byte(echo)...)
		sb.Reset()
		sb.Write(prompt)
		if inputErr != nil {
			validation := render(p.Templates.validation, inputErr)
			sb.Write(validation)
			inputErr = nil
		}
		sb.Flush()
		return nil, 0, keepOn
	}

	c.SetListener(listen)

	for {
		_, err = rl.Readline()
		inputErr = validFn(cur.Get())
		if inputErr == nil {
			break
		}

		if err != nil {
			break
		}
	}

	if err != nil {
		switch err {
		case readline.ErrInterrupt:
			err = ErrInterrupt
		case io.EOF:
			err = ErrEOF
		}
		if err.Error() == "Interrupt" {
			err = ErrInterrupt
		}
		sb.Reset()
		sb.WriteString("")
		sb.Flush()
		rl.Write([]byte(showCursor))
		rl.Close()
		return "", err
	}

	echo := cur.Format()
	if p.Mask != 0 {
		echo = cur.FormatMask(p.Mask)
	}

	prompt := render(p.Templates.success, p.Label)
	prompt = append(prompt, []byte(echo)...)

	if p.IsConfirm {
		lowerDefault := strings.ToLower(p.Default)
		if strings.ToLower(cur.Get()) != "y" && (lowerDefault != "y" || (lowerDefault == "y" && cur.Get() != "")) {
			prompt = render(p.Templates.invalid, p.Label)
			err = ErrAbort
		}
	}

	sb.Reset()
	sb.Write(prompt)
	sb.Flush()
	rl.Write([]byte(showCursor))
	rl.Close()

	return cur.Get(), err
}
func (p *Prompt) Run() (string, error) {
	var err error

	err = p.prepareTemplates()
	if err != nil {
		return "", err
	}

	c := &readline.Config{
		Stdin:          p.stdin,
		Stdout:         p.stdout,
		EnableMask:     p.Mask != 0,
		MaskRune:       p.Mask,
		HistoryLimit:   -1,
		VimMode:        p.IsVimMode,
		UniqueEditLine: true,
	}

	err = c.Init()
	if err != nil {
		return "", err
	}

	rl, err := readline.NewEx(c)
	if err != nil {
		return "", err
	}
	// we're taking over the cursor,  so stop showing it.
	rl.Write([]byte(hideCursor))
	sb := screenbuf.New(rl)

	validFn := func(x string) error {
		return nil
	}
	if p.Validate != nil {
		validFn = p.Validate
	}

	var inputErr error
	input := p.Default
	if p.IsConfirm {
		input = ""
	}
	eraseDefault := input != "" && !p.AllowEdit
	cur := NewCursor(input, p.Pointer, eraseDefault)

	listen := func(input []rune, pos int, key rune) ([]rune, int, bool) {
		_, _, keepOn := cur.Listen(input, pos, key)
		err := validFn(cur.Get())
		var prompt []byte

		if err != nil {
			prompt = render(p.Templates.invalid, p.Label)
		} else {
			prompt = render(p.Templates.valid, p.Label)
			if p.IsConfirm {
				prompt = render(p.Templates.prompt, p.Label)
			}
		}

		echo := cur.Format()
		if p.Mask != 0 {
			echo = cur.FormatMask(p.Mask)
		}

		prompt = append(prompt, []byte(echo)...)
		sb.Reset()
		sb.Write(prompt)
		if inputErr != nil {
			validation := render(p.Templates.validation, inputErr)
			sb.Write(validation)
			inputErr = nil
		}
		sb.Flush()
		return nil, 0, keepOn
	}

	c.SetListener(listen)

	for {
		_, err = rl.Readline()
		inputErr = validFn(cur.Get())
		if inputErr == nil {
			break
		}

		if err != nil {
			break
		}
	}

	if err != nil {
		switch err {
		case readline.ErrInterrupt:
			err = ErrInterrupt
		case io.EOF:
			err = ErrEOF
		}
		if err.Error() == "Interrupt" {
			err = ErrInterrupt
		}
		sb.Reset()
		sb.WriteString("")
		sb.Flush()
		rl.Write([]byte(showCursor))
		rl.Close()
		return "", err
	}

	echo := cur.Format()
	if p.Mask != 0 {
		echo = cur.FormatMask(p.Mask)
	}

	prompt := render(p.Templates.success, p.Label)
	prompt = append(prompt, []byte(echo)...)

	if p.IsConfirm {
		lowerDefault := strings.ToLower(p.Default)
		if strings.ToLower(cur.Get()) != "y" && (lowerDefault != "y" || (lowerDefault == "y" && cur.Get() != "")) {
			prompt = render(p.Templates.invalid, p.Label)
			err = ErrAbort
		}
	}

	sb.Reset()
	sb.Write(prompt)
	sb.Flush()
	rl.Write([]byte(showCursor))
	rl.Close()

	return cur.Get(), err
}
// Run executes the prompt. Its displays the label and default value if any, asking the user to enter a value.
// Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid
// value. It will return the value and an error if any occurred during the prompt's execution.