Skip to content

Commit 59b30f9

Browse files
author
mritd
committed
feat(prompt): 使用自定义 prompt
使用自定义的 prompt 替换原有库,以实现终端移动,编辑更友好 Signed-off-by: mritd <[email protected]>
1 parent d9400b0 commit 59b30f9

File tree

31 files changed

+324
-113
lines changed

31 files changed

+324
-113
lines changed

pkg/commit/ci.go

Lines changed: 27 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package commit
22

33
import (
4-
"errors"
54
"fmt"
65
"io/ioutil"
76
"os"
8-
"regexp"
97
"strings"
108
"text/template"
119

1210
"github.com/mritd/gitflow-toolkit/pkg/consts"
11+
gitprompt "github.com/mritd/gitflow-toolkit/pkg/prompt"
1312
"github.com/mritd/gitflow-toolkit/pkg/util"
1413
"github.com/mritd/promptui"
1514
)
@@ -84,106 +83,55 @@ func SelectCommitType() consts.CommitType {
8483
// 输入影响范围
8584
func InputScope() string {
8685

87-
validate := func(input string) error {
88-
reg := regexp.MustCompile("\\s+")
89-
if reg.ReplaceAllString(input, "") == "" {
90-
return errors.New("scope is blank")
86+
p := gitprompt.NewDefaultPrompt(func(line []rune) bool {
87+
if strings.TrimSpace(string(line)) == "" {
88+
return false
89+
} else {
90+
return true
9191
}
92-
return nil
93-
}
94-
95-
templates := &promptui.PromptTemplates{
96-
Prompt: "{{ . }} ",
97-
Valid: "{{ . | green }} ",
98-
Invalid: "{{ . | red }} ",
99-
Success: "{{ . | bold }} ",
100-
}
92+
}, "Scope:")
10193

102-
prompt := promptui.Prompt{
103-
Label: "❯ Scope:",
104-
Templates: templates,
105-
Validate: validate,
106-
}
107-
108-
result, err := prompt.Run()
109-
util.CheckAndExit(err)
110-
return result
94+
return p.Run()
11195

11296
}
11397

11498
// 输入提交主题
11599
func InputSubject() string {
116100

117-
validate := func(input string) error {
118-
if strings.TrimSpace(input) == "" {
119-
return errors.New("subject is blank")
101+
p := gitprompt.NewDefaultPrompt(func(line []rune) bool {
102+
if strings.TrimSpace(string(line)) == "" {
103+
return false
104+
} else {
105+
return true
120106
}
121-
if r := []rune(input); len(r) > 50 {
122-
return errors.New("subject too long")
123-
}
124-
125-
return nil
126-
}
107+
}, "Subject:")
127108

128-
templates := &promptui.PromptTemplates{
129-
Prompt: "{{ . }} ",
130-
Valid: "{{ . | green }} ",
131-
Invalid: "{{ . | red }} ",
132-
Success: "{{ . | bold }} ",
133-
}
134-
135-
prompt := promptui.Prompt{
136-
Label: "❯ Subject:",
137-
Templates: templates,
138-
Validate: validate,
139-
}
140-
141-
result, err := prompt.Run()
142-
util.CheckAndExit(err)
143-
return result
109+
return p.Run()
144110
}
145111

146112
// 输入完整提交信息
147113
func InputBody() string {
148114

149-
templates := &promptui.PromptTemplates{
150-
Prompt: "{{ . }} ",
151-
Valid: "{{ . | green }} ",
152-
Invalid: "{{ . | red }} ",
153-
Success: "{{ . | bold }} ",
154-
}
115+
p := gitprompt.NewDefaultPrompt(func(line []rune) bool {
116+
return true
117+
}, "Body:")
155118

156-
prompt := promptui.Prompt{
157-
Label: "❯ Body:",
158-
Templates: templates,
159-
}
160-
161-
result, err := prompt.Run()
162-
util.CheckAndExit(err)
163-
if result == "big" {
119+
body := p.Run()
120+
if body == "big" {
164121
return util.OSEditInput()
165122
}
166-
return result
123+
124+
return body
167125
}
168126

169127
// 输入提交关联信息
170128
func InputFooter() string {
171129

172-
templates := &promptui.PromptTemplates{
173-
Prompt: "{{ . }} ",
174-
Valid: "{{ . | green }} ",
175-
Invalid: "{{ . | red }} ",
176-
Success: "{{ . | bold }} ",
177-
}
178-
179-
prompt := promptui.Prompt{
180-
Label: "❯ Footer:",
181-
Templates: templates,
182-
}
130+
p := gitprompt.NewDefaultPrompt(func(line []rune) bool {
131+
return true
132+
}, "Footer:")
183133

184-
result, err := prompt.Run()
185-
util.CheckAndExit(err)
186-
return result
134+
return p.Run()
187135
}
188136

189137
// 生成 SOB 签名
@@ -221,5 +169,5 @@ func Commit(cm *Message) {
221169
t.Execute(f, cm)
222170
util.MustExec("git", "commit", "-F", f.Name())
223171

224-
fmt.Println("\nAlways code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.")
172+
fmt.Println("\n✔ Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.")
225173
}

pkg/prompt/codes.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package prompt
2+
3+
import (
4+
"strconv"
5+
"strings"
6+
"fmt"
7+
"text/template"
8+
)
9+
10+
const esc = "\033["
11+
12+
type attribute int
13+
14+
// Foreground weight/decoration attributes.
15+
const (
16+
reset attribute = iota
17+
18+
FGBold
19+
FGFaint
20+
FGItalic
21+
FGUnderline
22+
)
23+
24+
// Foreground color attributes
25+
const (
26+
FGBlack attribute = iota + 30
27+
FGRed
28+
FGGreen
29+
FGYellow
30+
FGBlue
31+
FGMagenta
32+
FGCyan
33+
FGWhite
34+
)
35+
36+
// Background color attributes
37+
const (
38+
BGBlack attribute = iota + 40
39+
BGRed
40+
BGGreen
41+
BGYellow
42+
BGBlue
43+
BGMagenta
44+
BGCyan
45+
BGWhite
46+
)
47+
48+
// ResetCode is the character code used to reset the terminal formatting
49+
var ResetCode = fmt.Sprintf("%s%dm", esc, reset)
50+
51+
const (
52+
hideCursor = esc + "?25l"
53+
showCursor = esc + "?25h"
54+
clearLine = esc + "2K"
55+
)
56+
57+
// FuncMap defines template helpers for the output. It can be extended as a
58+
// regular map.
59+
var FuncMap = template.FuncMap{
60+
"black": Styler(FGBlack),
61+
"red": Styler(FGRed),
62+
"green": Styler(FGGreen),
63+
"yellow": Styler(FGYellow),
64+
"blue": Styler(FGBlue),
65+
"magenta": Styler(FGMagenta),
66+
"cyan": Styler(FGCyan),
67+
"white": Styler(FGWhite),
68+
"bgBlack": Styler(BGBlack),
69+
"bgRed": Styler(BGRed),
70+
"bgGreen": Styler(BGGreen),
71+
"bgYellow": Styler(BGYellow),
72+
"bgBlue": Styler(BGBlue),
73+
"bgMagenta": Styler(BGMagenta),
74+
"bgCyan": Styler(BGCyan),
75+
"bgWhite": Styler(BGWhite),
76+
"bold": Styler(FGBold),
77+
"faint": Styler(FGFaint),
78+
"italic": Styler(FGItalic),
79+
"underline": Styler(FGUnderline),
80+
}
81+
82+
func upLine(n uint) string {
83+
return movementCode(n, 'A')
84+
}
85+
86+
func movementCode(n uint, code rune) string {
87+
return esc + strconv.FormatUint(uint64(n), 10) + string(code)
88+
}
89+
90+
// Styler returns a func that applies the attributes given in the Styler call
91+
// to the provided string.
92+
func Styler(attrs ...attribute) func(interface{}) string {
93+
attrstrs := make([]string, len(attrs))
94+
for i, v := range attrs {
95+
attrstrs[i] = strconv.Itoa(int(v))
96+
}
97+
98+
seq := strings.Join(attrstrs, ";")
99+
100+
return func(v interface{}) string {
101+
end := ""
102+
s, ok := v.(string)
103+
if !ok || !strings.HasSuffix(s, ResetCode) {
104+
end = ResetCode
105+
}
106+
return fmt.Sprintf("%s%sm%v%s", esc, seq, v, end)
107+
}
108+
}

0 commit comments

Comments
 (0)