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
}
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 ( ) == " " { 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 ( ) ) != " " && ( lowerDefault != " " || ( lowerDefault == " " && 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.
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 .