9 "github.com/gdamore/tcell"
12 // TermMessage sends a message to the user in the terminal. This usually occurs before
13 // micro has been fully initialized -- ie if there is an error in the syntax highlighting
14 // regular expressions
15 // The function must be called when the screen is not initialized
16 // This will write the message, and wait for the user
17 // to press and key to continue
18 func TermMessage(msg string) {
20 fmt.Print("\nPress enter to continue")
22 reader := bufio.NewReader(os.Stdin)
23 reader.ReadString('\n')
26 // TermError sends an error to the user in the terminal. Like TermMessage except formatted
28 func TermError(filename string, lineNum int, err string) {
29 TermMessage(filename + ", " + strconv.Itoa(lineNum) + ": " + err)
32 // Messenger is an object that makes it easy to send messages to the user
33 // and get input from the user
34 type Messenger struct {
35 // Are we currently prompting the user?
37 // Is there a message to print
42 // The user's response to a prompt
44 // style to use when drawing the message
47 // We have to keep track of the cursor for prompting
51 // Message sends a message to the user
52 func (m *Messenger) Message(msg string) {
56 if _, ok := colorscheme["message"]; ok {
57 m.style = colorscheme["message"]
62 // Error sends an error message to the user
63 func (m *Messenger) Error(msg string) {
66 Foreground(tcell.ColorBlack).
67 Background(tcell.ColorMaroon)
69 if _, ok := colorscheme["error-message"]; ok {
70 m.style = colorscheme["error-message"]
75 // YesNoPrompt asks the user a yes or no question (waits for y or n) and returns the result
76 func (m *Messenger) YesNoPrompt(prompt string) bool {
83 event := screen.PollEvent()
85 switch e := event.(type) {
87 if e.Key() == tcell.KeyRune {
90 } else if e.Rune() == 'n' {
98 // Prompt sends the user a message and waits for a response to be typed in
99 // This function blocks the main loop while waiting for input
100 func (m *Messenger) Prompt(prompt string) (string, bool) {
104 response, canceled := "", true
110 event := screen.PollEvent()
112 switch e := event.(type) {
113 case *tcell.EventKey:
115 case tcell.KeyCtrlQ, tcell.KeyCtrlC, tcell.KeyEscape:
119 // User is done entering their response
121 response, canceled = m.response, false
134 return response, canceled
137 // HandleEvent handles an event for the prompter
138 func (m *Messenger) HandleEvent(event tcell.Event) {
139 switch e := event.(type) {
140 case *tcell.EventKey:
147 if m.cursorx < Count(m.response) {
150 case tcell.KeyBackspace2:
152 m.response = string([]rune(m.response)[:m.cursorx-1]) + string(m.response[m.cursorx:])
159 m.response = Insert(m.response, m.cursorx, string(e.Rune()))
165 // Reset resets the messenger's cursor, message and response
166 func (m *Messenger) Reset() {
172 // Clear clears the line at the bottom of the editor
173 func (m *Messenger) Clear() {
174 w, h := screen.Size()
175 for x := 0; x < w; x++ {
176 screen.SetContent(x, h-1, ' ', nil, defStyle)
180 // Display displays messages or prompts
181 func (m *Messenger) Display() {
182 _, h := screen.Size()
184 runes := []rune(m.message + m.response)
185 for x := 0; x < len(runes); x++ {
186 screen.SetContent(x, h-1, runes[x], nil, m.style)
190 screen.ShowCursor(Count(m.message)+m.cursorx, h-1)