-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
interactive.go
113 lines (106 loc) · 2.84 KB
/
interactive.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
106
107
108
109
110
111
112
113
package main
import (
"fmt"
"os"
"strings"
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/briandowns/spinner"
"github.com/c-bata/go-prompt"
"github.com/charmbracelet/glamour"
)
func completer(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{
{Text: "!quit", Description: "Quit the application"},
{Text: "!editor", Description: "use $EDITOR to write the question"},
{Text: "!reset", Description: "Reset the conversation"},
{Text: "!write <file>", Description: "Write the conversation to a file"},
}
return prompt.FilterHasPrefix(s, d.Text, true)
}
func renderToMD(f *os.File, text string) {
out := ""
if f == os.Stdout {
o, _ := os.Stdout.Stat()
if (o.Mode()&os.ModeCharDevice) == os.ModeCharDevice && !nocolor { //Terminal
out, _ = glamour.RenderWithEnvironmentConfig(text)
} else {
out = text
}
} else {
out = text
}
fmt.Fprintln(f, out)
}
func sanitizeQuestion(question string) string {
// url encode the question. BUG: this breaks UTF-8. for now returning the question
return question
// return url.QueryEscape(question)
}
func normalQ(askFn func(string) (string, error), question string) string {
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.UpdateCharSet(spinner.CharSets[11])
s.Start()
answer, err := askFn(sanitizeQuestion(question))
if err != nil {
fmt.Println(err)
answer = ""
}
s.Stop()
return answer
}
// RunInteractive runs the interactive mode of the CLI
func RunInteractive(askFn func(string) (string, error)) {
fmt.Println("press <tab> to see the list of commands")
outFile := os.Stdout
for {
text := prompt.Input("> ", completer)
switch {
case strings.HasPrefix(text, "!quit"):
return
case strings.HasPrefix(text, "!editor"):
editorQ := ""
prompt := &survey.Editor{
Message: "Question:",
FileName: "*.md",
}
if err := survey.AskOne(prompt, &editorQ); err != nil {
fmt.Println(err)
continue
}
// trim the last newline
editorQ = editorQ[:len(editorQ)-1]
fmt.Fprintln(outFile, "Q: "+text)
renderToMD(outFile, normalQ(askFn, editorQ))
continue
case strings.HasPrefix(text, "!reset"):
// TODO: fix
continue
case strings.TrimSpace(text) == "":
continue
case strings.HasPrefix(text, "!write"):
// get the file name by spiliting the text after !write
fname := strings.Split(text, "!write")
if len(fname) < 2 {
fmt.Println("Please provide a file name")
continue
}
outFileName := strings.TrimSpace(fname[1])
if outFileName == "" {
fmt.Println("Please provide a file name")
continue
}
var err error
outFile, err = os.OpenFile(outFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println(err)
continue
}
default:
// Write the question back as well
fmt.Fprintln(outFile, "Q: "+text)
renderToMD(outFile, normalQ(askFn, text))
continue
}
}
}