File: multiline.go

package info (click to toggle)
golang-github-alecaivazis-survey 2.2.7%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 624 kB
  • sloc: makefile: 6
file content (110 lines) | stat: -rw-r--r-- 2,491 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package survey

import (
	"strings"

	"github.com/AlecAivazis/survey/v2/terminal"
)

type Multiline struct {
	Renderer
	Message string
	Default string
	Help    string
}

// data available to the templates when processing
type MultilineTemplateData struct {
	Multiline
	Answer     string
	ShowAnswer bool
	ShowHelp   bool
	Config     *PromptConfig
}

// Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
var MultilineQuestionTemplate = `
{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
{{- color "default+hb"}}{{ .Message }} {{color "reset"}}
{{- if .ShowAnswer}}
  {{- "\n"}}{{color "cyan"}}{{.Answer}}{{color "reset"}}
  {{- if .Answer }}{{ "\n" }}{{ end }}
{{- else }}
  {{- if .Default}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
  {{- color "cyan"}}[Enter 2 empty lines to finish]{{color "reset"}}
{{- end}}`

func (i *Multiline) Prompt(config *PromptConfig) (interface{}, error) {
	// render the template
	err := i.Render(
		MultilineQuestionTemplate,
		MultilineTemplateData{
			Multiline: *i,
			Config:    config,
		},
	)
	if err != nil {
		return "", err
	}

	// start reading runes from the standard in
	rr := i.NewRuneReader()
	rr.SetTermMode()
	defer rr.RestoreTermMode()

	cursor := i.NewCursor()

	multiline := make([]string, 0)

	emptyOnce := false
	// get the next line
	for {
		line := []rune{}
		line, err = rr.ReadLine(0)
		if err != nil {
			return string(line), err
		}

		if string(line) == "" {
			if emptyOnce {
				numLines := len(multiline) + 2
				cursor.PreviousLine(numLines)
				for j := 0; j < numLines; j++ {
					terminal.EraseLine(i.Stdio().Out, terminal.ERASE_LINE_ALL)
					cursor.NextLine(1)
				}
				cursor.PreviousLine(numLines)
				break
			}
			emptyOnce = true
		} else {
			emptyOnce = false
		}
		multiline = append(multiline, string(line))
	}

	val := strings.Join(multiline, "\n")
	val = strings.TrimSpace(val)

	// if the line is empty
	if len(val) == 0 {
		// use the default value
		return i.Default, err
	}

	i.AppendRenderedText(val)
	return val, err
}

func (i *Multiline) Cleanup(config *PromptConfig, val interface{}) error {
	return i.Render(
		MultilineQuestionTemplate,
		MultilineTemplateData{
			Multiline:  *i,
			Answer:     val.(string),
			ShowAnswer: true,
			Config:     config,
		},
	)
}