Skip to content

Commit 5ca4703

Browse files
author
҈҈҈Luiz Branco
authored
Custom style/output for prompt and select (manifoldco#8)
1 parent 1b359d2 commit 5ca4703

File tree

13 files changed

+611
-103
lines changed

13 files changed

+611
-103
lines changed

_examples/confirm/main.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/manifoldco/promptui"
7+
)
8+
9+
func main() {
10+
prompt := promptui.Prompt{
11+
Label: "Delete Resource",
12+
IsConfirm: true,
13+
}
14+
15+
result, err := prompt.Run()
16+
17+
if err != nil {
18+
fmt.Printf("Prompt failed %v\n", err)
19+
return
20+
}
21+
22+
fmt.Printf("You choose %q\n", result)
23+
}

_examples/custom_prompt/main.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
7+
"github.com/manifoldco/promptui"
8+
)
9+
10+
type pepper struct {
11+
Name string
12+
HeatUnit int
13+
Peppers int
14+
}
15+
16+
func main() {
17+
validate := func(input string) error {
18+
_, err := strconv.ParseFloat(input, 64)
19+
return err
20+
}
21+
22+
templates := &promptui.PromptTemplates{
23+
Prompt: "{{ . }} ",
24+
Valid: "{{ . | green }} ",
25+
Invalid: "{{ . | red }} ",
26+
Success: "{{ . | bold }} ",
27+
}
28+
29+
prompt := promptui.Prompt{
30+
Label: "Spicy Level",
31+
Templates: templates,
32+
Validate: validate,
33+
}
34+
35+
result, err := prompt.Run()
36+
37+
if err != nil {
38+
fmt.Printf("Prompt failed %v\n", err)
39+
return
40+
}
41+
42+
fmt.Printf("You answered %s\n", result)
43+
}

_examples/custom_select/main.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/manifoldco/promptui"
7+
)
8+
9+
type pepper struct {
10+
Name string
11+
HeatUnit int
12+
Peppers int
13+
}
14+
15+
func main() {
16+
peppers := []pepper{
17+
{Name: "Bell Pepper", HeatUnit: 0, Peppers: 0},
18+
{Name: "Banana Pepper", HeatUnit: 100, Peppers: 1},
19+
{Name: "Poblano", HeatUnit: 1000, Peppers: 2},
20+
{Name: "Jalapeño", HeatUnit: 3500, Peppers: 3},
21+
{Name: "Aleppo", HeatUnit: 10000, Peppers: 4},
22+
{Name: "Tabasco", HeatUnit: 30000, Peppers: 5},
23+
{Name: "Malagueta", HeatUnit: 50000, Peppers: 6},
24+
{Name: "Habanero", HeatUnit: 100000, Peppers: 7},
25+
{Name: "Red Savina Habanero", HeatUnit: 350000, Peppers: 8},
26+
{Name: "Dragon’s Breath", HeatUnit: 855000, Peppers: 9},
27+
}
28+
29+
templates := &promptui.SelectTemplates{
30+
Label: "{{ . }}?",
31+
Active: "\U0001F525 {{ .Name | bold }} ({{ .HeatUnit | red | italic }})",
32+
Inactive: " {{ .Name | bold }} ({{ .HeatUnit | red | italic }})",
33+
Selected: "\U0001F525 {{ .Name | red | bold }}",
34+
}
35+
36+
prompt := promptui.Select{
37+
Label: "Spicy Level",
38+
Items: peppers,
39+
Templates: templates,
40+
}
41+
42+
i, _, err := prompt.Run()
43+
44+
if err != nil {
45+
fmt.Printf("Prompt failed %v\n", err)
46+
return
47+
}
48+
49+
fmt.Printf("You choose number %d: %v\n", i+1, peppers[i])
50+
}
File renamed without changes.

examples/select/main.go _examples/select/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ func main() {
2121
return
2222
}
2323

24-
fmt.Printf("You choose %q\n", result)
24+
fmt.Printf("You choose %s\n", result)
2525
}

codes.go

+26-7
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import (
44
"fmt"
55
"strconv"
66
"strings"
7+
"text/template"
78
)
89

910
const esc = "\033["
1011

1112
type attribute int
1213

13-
// Forground weight/decoration attributes.
14+
// Foreground weight/decoration attributes.
1415
const (
1516
reset attribute = iota
1617

@@ -20,7 +21,7 @@ const (
2021
FGUnderline
2122
)
2223

23-
// Forground color attributes
24+
// Foreground color attributes
2425
const (
2526
FGBlack attribute = iota + 30
2627
FGRed
@@ -35,12 +36,29 @@ const (
3536
// ResetCode is the character code used to reset the terminal formatting
3637
var ResetCode = fmt.Sprintf("%s%dm", esc, reset)
3738

38-
var (
39+
const (
3940
hideCursor = esc + "?25l"
4041
showCursor = esc + "?25h"
4142
clearLine = esc + "2K"
4243
)
4344

45+
// FuncMap defines template helpers for the output. It can be extended as a
46+
// regular map.
47+
var FuncMap = template.FuncMap{
48+
"black": Styler(FGBlack),
49+
"red": Styler(FGRed),
50+
"green": Styler(FGGreen),
51+
"yellow": Styler(FGYellow),
52+
"blue": Styler(FGBlue),
53+
"magenta": Styler(FGMagenta),
54+
"cyan": Styler(FGCyan),
55+
"white": Styler(FGWhite),
56+
"bold": Styler(FGBold),
57+
"faint": Styler(FGFaint),
58+
"italic": Styler(FGItalic),
59+
"underline": Styler(FGUnderline),
60+
}
61+
4462
func upLine(n uint) string {
4563
return movementCode(n, 'A')
4664
}
@@ -55,19 +73,20 @@ func movementCode(n uint, code rune) string {
5573

5674
// Styler returns a func that applies the attributes given in the Styler call
5775
// to the provided string.
58-
func Styler(attrs ...attribute) func(string) string {
76+
func Styler(attrs ...attribute) func(interface{}) string {
5977
attrstrs := make([]string, len(attrs))
6078
for i, v := range attrs {
6179
attrstrs[i] = strconv.Itoa(int(v))
6280
}
6381

6482
seq := strings.Join(attrstrs, ";")
6583

66-
return func(s string) string {
84+
return func(v interface{}) string {
6785
end := ""
68-
if !strings.HasSuffix(s, ResetCode) {
86+
s, ok := v.(string)
87+
if !ok || !strings.HasSuffix(s, ResetCode) {
6988
end = ResetCode
7089
}
71-
return fmt.Sprintf("%s%sm%s%s", esc, seq, s, end)
90+
return fmt.Sprintf("%s%sm%v%s", esc, seq, v, end)
7291
}
7392
}

codes_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ func TestStyler(t *testing.T) {
1717
if boldRed != expected {
1818
t.Errorf("style did not match: %s != %s", boldRed, expected)
1919
}
20-
2120
})
2221

2322
t.Run("should not repeat reset codes for nested styles", func(t *testing.T) {
@@ -27,6 +26,5 @@ func TestStyler(t *testing.T) {
2726
if boldRed != expected {
2827
t.Errorf("style did not match: %s != %s", boldRed, expected)
2928
}
30-
3129
})
3230
}

0 commit comments

Comments
 (0)