input.go 2.3 KB

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