github.com/igggame/nebulas-go@v2.1.0+incompatible/cmd/console/prompter.go (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package console
    20  
    21  import (
    22  	"fmt"
    23  
    24  	"strings"
    25  
    26  	"github.com/peterh/liner"
    27  )
    28  
    29  // Stdin holds the stdin line reader (also using stdout for printing prompts).
    30  var Stdin = NewTerminalPrompter()
    31  
    32  // UserPrompter handle console user input interactive
    33  type UserPrompter interface {
    34  	Prompt(prompt string) (string, error)
    35  	PromptPassphrase(prompt string) (passwd string, err error)
    36  	PromptConfirm(prompt string) (bool, error)
    37  	SetHistory(history []string)
    38  	AppendHistory(command string)
    39  	SetWordCompleter(completer liner.WordCompleter)
    40  }
    41  
    42  // TerminalPrompter terminal prompter
    43  type TerminalPrompter struct {
    44  	liner     *liner.State
    45  	supported bool
    46  	origMode  liner.ModeApplier
    47  	rawMode   liner.ModeApplier
    48  }
    49  
    50  // NewTerminalPrompter create a terminal prompter
    51  func NewTerminalPrompter() *TerminalPrompter {
    52  	p := new(TerminalPrompter)
    53  	// Get the original mode before calling NewLiner.
    54  	origMode, _ := liner.TerminalMode()
    55  	// Turn on liner.
    56  	p.liner = liner.NewLiner()
    57  	rawMode, err := liner.TerminalMode()
    58  	if err != nil || !liner.TerminalSupported() {
    59  		p.supported = false
    60  	} else {
    61  		p.supported = true
    62  		p.origMode = origMode
    63  		p.rawMode = rawMode
    64  		// Switch back to normal mode while we're not prompting.
    65  		origMode.ApplyMode()
    66  	}
    67  	p.liner.SetCtrlCAborts(true)
    68  	p.liner.SetTabCompletionStyle(liner.TabPrints)
    69  	p.liner.SetMultiLineMode(true)
    70  	return p
    71  }
    72  
    73  // Prompt shows the prompt and requests text input
    74  // returning the input.
    75  func (p *TerminalPrompter) Prompt(prompt string) (string, error) {
    76  	if p.supported {
    77  		p.rawMode.ApplyMode()
    78  		defer p.origMode.ApplyMode()
    79  	} else {
    80  		fmt.Print(prompt)
    81  		defer fmt.Println()
    82  	}
    83  	return p.liner.Prompt(prompt)
    84  }
    85  
    86  // PromptPassphrase shows the prompt and request passphrase text input, the passphrase
    87  // not show, returns the passphrase
    88  func (p *TerminalPrompter) PromptPassphrase(prompt string) (passwd string, err error) {
    89  	if p.supported {
    90  		p.rawMode.ApplyMode()
    91  		defer p.origMode.ApplyMode()
    92  		return p.liner.PasswordPrompt(prompt)
    93  	}
    94  
    95  	fmt.Print(prompt)
    96  	passwd, err = p.liner.Prompt("")
    97  	fmt.Println()
    98  	return passwd, err
    99  }
   100  
   101  // PromptConfirm shows the prompt to the user and requests a boolean
   102  // choice to be made, returning that choice.
   103  func (p *TerminalPrompter) PromptConfirm(prompt string) (bool, error) {
   104  	input, err := p.Prompt(prompt + " [y/N] ")
   105  	if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" {
   106  		return true, nil
   107  	}
   108  	return false, err
   109  }
   110  
   111  // SetHistory sets the history that the prompter will allow
   112  // the user to scroll back to.
   113  func (p *TerminalPrompter) SetHistory(history []string) {
   114  	p.liner.ReadHistory(strings.NewReader(strings.Join(history, "\n")))
   115  }
   116  
   117  // AppendHistory appends an entry to the scrollback history.
   118  func (p *TerminalPrompter) AppendHistory(command string) {
   119  	p.liner.AppendHistory(command)
   120  }
   121  
   122  // SetWordCompleter sets the completion function that the prompter will call to
   123  // fetch completion candidates when the user presses tab.
   124  func (p *TerminalPrompter) SetWordCompleter(completer liner.WordCompleter) {
   125  	p.liner.SetWordCompleter(completer)
   126  }