-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathpromptkit.go
105 lines (85 loc) · 2.64 KB
/
promptkit.go
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
/*
Package promptkit is a collection of common command line prompts for interactive
programs. Each prompts comes with sensible defaults, re-mappable key bindings
and many opportunities for heavy customization.
The actual prompt components can be found in the sub directories.
*/
package promptkit
import (
"bufio"
"fmt"
"strings"
"text/template"
"github.com/muesli/reflow/ansi"
"github.com/muesli/reflow/truncate"
"github.com/muesli/reflow/wordwrap"
"github.com/muesli/reflow/wrap"
)
// ErrAborted is returned when the prompt was aborted.
var ErrAborted = fmt.Errorf("prompt aborted")
// UtilFuncMap returns a template.FuncMap with handy utility functions for
// prompt templates.
//
// - Repeat(string, int) string: Identical to strings.Repeat.
// - Len(string): reflow/ansi.PrintableRuneWidth, Len works like len but is
// aware of ansi codes and returns the length of the string as it appears
// on the screen.
// - Min(int, int) int: The minimum of two ints.
// - Max(int, int) int: The maximum of two ints.
// - Add(int, int) int: The sum of two ints.
// - Sub(int, int) int: The difference of two ints.
// - Mul(int, int) int: The product of two ints.
func UtilFuncMap() template.FuncMap {
return template.FuncMap{
"Repeat": strings.Repeat,
"Len": ansi.PrintableRuneWidth,
"Min": func(a, b int) int {
if a <= b {
return a
}
return b
},
"Max": func(a, b int) int {
if a >= b {
return a
}
return b
},
"Add": func(a, b int) int { return a + b },
"Sub": func(a, b int) int { return a - b },
"Mul": func(a, b int) int { return a * b },
}
}
// WrapMode decides in which way text is wrapped.
type WrapMode func(string, int) string
// WordWrap performs a word wrap on the input and forces a wrap at width if a
// word is still larger that width after soft wrapping. This is known to cause
// issues with coloring in some terminals depending on the prompt style.
func WordWrap(input string, width int) string {
if width == 0 {
return input
}
return wrap.String(wordwrap.String(input, width), width)
}
var _ WrapMode = WordWrap
// HardWrap performs a hard wrap at the given width.
func HardWrap(input string, width int) string {
if width == 0 {
return input
}
return wrap.String(input, width)
}
var _ WrapMode = HardWrap
// Truncate cuts the string after the given width.
func Truncate(input string, width int) string {
if width == 0 {
return input
}
var truncated strings.Builder
scanner := bufio.NewScanner(strings.NewReader(input))
for scanner.Scan() {
truncated.WriteString(truncate.String(scanner.Text(), uint(width)) + "\n")
}
return truncated.String()
}
var _ WrapMode = Truncate