7 "github.com/zyedidia/micro/internal/buffer"
8 luar "layeh.com/gopher-luar"
10 "github.com/zyedidia/micro/internal/config"
11 ulua "github.com/zyedidia/micro/internal/lua"
12 "github.com/zyedidia/micro/internal/screen"
15 // The InfoBuf displays messages and other info at the bottom of the screen.
16 // It is respresented as a buffer and a message with a style.
30 // This map stores the history for all the different kinds of uses Prompt has
31 // It's a map of history type -> history array
32 History map[string][]string
35 // Is the current message a message from the gutter
38 PromptCallback func(resp string, canceled bool)
39 EventCallback func(resp string)
40 YNCallback func(yes bool, canceled bool)
43 // NewBuffer returns a new infobuffer
44 func NewBuffer() *InfoBuf {
46 ib.History = make(map[string][]string)
48 ib.Buffer = buffer.NewBufferFromString("", "", buffer.BTInfo)
54 // Close performs any cleanup necessary when shutting down the infobuffer
55 func (i *InfoBuf) Close() {
59 // Message sends a message to the user
60 func (i *InfoBuf) Message(msg ...interface{}) {
61 // only display a new message if there isn't an active prompt
62 // this is to prevent overwriting an existing prompt to the user
63 if i.HasPrompt == false {
64 displayMessage := fmt.Sprint(msg...)
65 // if there is no active prompt then style and display the message as normal
66 i.Msg = displayMessage
67 i.HasMessage, i.HasError = true, false
71 // GutterMessage displays a message and marks it as a gutter message
72 func (i *InfoBuf) GutterMessage(msg ...interface{}) {
77 // ClearGutter clears the info bar and unmarks the message
78 func (i *InfoBuf) ClearGutter() {
83 // Error sends an error message to the user
84 func (i *InfoBuf) Error(msg ...interface{}) {
85 // only display a new message if there isn't an active prompt
86 // this is to prevent overwriting an existing prompt to the user
87 if i.HasPrompt == false {
88 // if there is no active prompt then style and display the message as normal
89 i.Msg = fmt.Sprint(msg...)
90 i.HasMessage, i.HasError = false, true
95 // Prompt starts a prompt for the user, it takes a prompt, a possibly partially filled in msg
96 // and callbacks executed when the user executes an event and when the user finishes the prompt
97 // The eventcb passes the current user response as the argument and donecb passes the user's message
98 // and a boolean indicating if the prompt was canceled
99 func (i *InfoBuf) Prompt(prompt string, msg string, ptype string, eventcb func(string), donecb func(string, bool)) {
100 // If we get another prompt mid-prompt we cancel the one getting overwritten
105 if _, ok := i.History[ptype]; !ok {
106 i.History[ptype] = []string{""}
108 i.History[ptype] = append(i.History[ptype], "")
110 i.HistoryNum = len(i.History[ptype]) - 1
115 i.HasMessage, i.HasError, i.HasYN = false, false, false
117 i.PromptCallback = donecb
118 i.EventCallback = eventcb
119 i.Buffer.Insert(i.Buffer.Start(), msg)
122 // YNPrompt creates a yes or no prompt, and the callback returns the yes/no result and whether
123 // the prompt was canceled
124 func (i *InfoBuf) YNPrompt(prompt string, donecb func(bool, bool)) {
132 i.HasMessage, i.HasError = false, false
134 i.YNCallback = donecb
137 // PlugPrompt provides a plugin interface for calling "Prompt" with the appropriate Lua callbacks
138 func (i *InfoBuf) PlugPrompt(prompt string, msg string, ptype string, eventcb string, donecb string) {
139 eventLuaFn := strings.Split(eventcb, ".")
140 doneLuaFn := strings.Split(donecb, ".")
141 var luaEventcb func(string)
142 var luaDonecb func(string, bool)
144 if len(eventLuaFn) == 2 {
145 plName, plFn := doneLuaFn[0], doneLuaFn[1]
146 pl := config.FindPlugin(plName)
148 luaEventcb = func(resp string) {
149 _, err := pl.Call(plFn, luar.New(ulua.L, resp))
150 if err != nil && err != config.ErrNoSuchFunction {
151 screen.TermMessage(err)
157 if len(doneLuaFn) == 2 {
158 plName, plFn := doneLuaFn[0], doneLuaFn[1]
159 pl := config.FindPlugin(plName)
161 luaDonecb = func(resp string, canceled bool) {
162 _, err := pl.Call(plFn, luar.New(ulua.L, resp), luar.New(ulua.L, canceled))
163 if err != nil && err != config.ErrNoSuchFunction {
164 screen.TermMessage(err)
170 i.Prompt(prompt, msg, ptype, luaEventcb, luaDonecb)
173 // PlugYNPrompt provides a plugin interface for calling "YNPrompt" with the appropriate Lua callbacks
174 func (i *InfoBuf) PlugYNPrompt(prompt string, donecb string) {
175 doneLuaFn := strings.Split(donecb, ".")
176 var luaDonecb func(bool, bool)
178 if len(doneLuaFn) == 2 {
179 plName, plFn := doneLuaFn[0], doneLuaFn[1]
180 pl := config.FindPlugin(plName)
182 luaDonecb = func(resp bool, canceled bool) {
183 _, err := pl.Call(plFn, luar.New(ulua.L, resp), luar.New(ulua.L, canceled))
184 if err != nil && err != config.ErrNoSuchFunction {
185 screen.TermMessage(err)
191 i.YNPrompt(prompt, luaDonecb)
194 // DonePrompt finishes the current prompt and indicates whether or not it was canceled
195 func (i *InfoBuf) DonePrompt(canceled bool) {
201 if i.PromptCallback != nil {
203 i.PromptCallback("", true)
204 h := i.History[i.PromptType]
205 i.History[i.PromptType] = h[:len(h)-1]
207 resp := string(i.LineBytes(0))
208 i.PromptCallback(resp, false)
209 h := i.History[i.PromptType]
212 i.PromptCallback = nil
214 i.Replace(i.Start(), i.End(), "")
216 if i.YNCallback != nil && hadYN {
217 i.YNCallback(i.YNResp, canceled)
221 // Reset resets the infobuffer's msg and info
222 func (i *InfoBuf) Reset() {
224 i.HasPrompt, i.HasMessage, i.HasError = false, false, false