input.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package survey
  2. import (
  3. "gopkg.in/AlecAivazis/survey.v1/core"
  4. )
  5. /*
  6. Input is a regular text input that prints each character the user types on the screen
  7. and accepts the input with the enter key. Response type is a string.
  8. name := ""
  9. prompt := &survey.Input{ Message: "What is your name?" }
  10. survey.AskOne(prompt, &name, nil)
  11. */
  12. type Input struct {
  13. core.Renderer
  14. Message string
  15. Default string
  16. Help string
  17. }
  18. // data available to the templates when processing
  19. type InputTemplateData struct {
  20. Input
  21. Answer string
  22. ShowAnswer bool
  23. ShowHelp bool
  24. }
  25. // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
  26. var InputQuestionTemplate = `
  27. {{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
  28. {{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
  29. {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
  30. {{- if .ShowAnswer}}
  31. {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
  32. {{- else }}
  33. {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ HelpInputRune }} for help]{{color "reset"}} {{end}}
  34. {{- if .Default}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
  35. {{- end}}`
  36. func (i *Input) Prompt() (interface{}, error) {
  37. // render the template
  38. err := i.Render(
  39. InputQuestionTemplate,
  40. InputTemplateData{Input: *i},
  41. )
  42. if err != nil {
  43. return "", err
  44. }
  45. // start reading runes from the standard in
  46. rr := i.NewRuneReader()
  47. rr.SetTermMode()
  48. defer rr.RestoreTermMode()
  49. cursor := i.NewCursor()
  50. line := []rune{}
  51. // get the next line
  52. for {
  53. line, err = rr.ReadLine(0)
  54. if err != nil {
  55. return string(line), err
  56. }
  57. // terminal will echo the \n so we need to jump back up one row
  58. cursor.PreviousLine(1)
  59. if string(line) == string(core.HelpInputRune) && i.Help != "" {
  60. err = i.Render(
  61. InputQuestionTemplate,
  62. InputTemplateData{Input: *i, ShowHelp: true},
  63. )
  64. if err != nil {
  65. return "", err
  66. }
  67. continue
  68. }
  69. break
  70. }
  71. // if the line is empty
  72. if line == nil || len(line) == 0 {
  73. // use the default value
  74. return i.Default, err
  75. }
  76. // we're done
  77. return string(line), err
  78. }
  79. func (i *Input) Cleanup(val interface{}) error {
  80. return i.Render(
  81. InputQuestionTemplate,
  82. InputTemplateData{Input: *i, Answer: val.(string), ShowAnswer: true},
  83. )
  84. }