1package core 2 3import ( 4 "bytes" 5 "sync" 6 "text/template" 7 8 "github.com/mgutz/ansi" 9) 10 11var DisableColor = false 12 13var ( 14 // HelpInputRune is the rune which the user should enter to trigger 15 // more detailed question help 16 HelpInputRune = '?' 17 18 // ErrorIcon will be be shown before an error 19 ErrorIcon = "X" 20 21 // HelpIcon will be shown before more detailed question help 22 HelpIcon = "?" 23 // QuestionIcon will be shown before a question Message 24 QuestionIcon = "?" 25 26 // MarkedOptionIcon will be prepended before a selected multiselect option 27 MarkedOptionIcon = "[x]" 28 // UnmarkedOptionIcon will be prepended before an unselected multiselect option 29 UnmarkedOptionIcon = "[ ]" 30 31 // SelectFocusIcon is prepended to an option to signify the user is 32 // currently focusing that option 33 SelectFocusIcon = ">" 34) 35 36/* 37 SetFancyIcons changes the err, help, marked, and focus input icons to their 38 fancier forms. These forms may not be compatible with most terminals. 39 This function will not touch the QuestionIcon as its fancy and non fancy form 40 are the same. 41*/ 42func SetFancyIcons() { 43 ErrorIcon = "✘" 44 HelpIcon = "ⓘ" 45 // QuestionIcon fancy and non-fancy form are the same 46 47 MarkedOptionIcon = "◉" 48 UnmarkedOptionIcon = "◯" 49 50 SelectFocusIcon = "❯" 51} 52 53var TemplateFuncs = map[string]interface{}{ 54 // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format 55 "color": func(color string) string { 56 if DisableColor { 57 return "" 58 } 59 return ansi.ColorCode(color) 60 }, 61 "HelpInputRune": func() string { 62 return string(HelpInputRune) 63 }, 64 "ErrorIcon": func() string { 65 return ErrorIcon 66 }, 67 "HelpIcon": func() string { 68 return HelpIcon 69 }, 70 "QuestionIcon": func() string { 71 return QuestionIcon 72 }, 73 "MarkedOptionIcon": func() string { 74 return MarkedOptionIcon 75 }, 76 "UnmarkedOptionIcon": func() string { 77 return UnmarkedOptionIcon 78 }, 79 "SelectFocusIcon": func() string { 80 return SelectFocusIcon 81 }, 82} 83 84var ( 85 memoizedGetTemplate = map[string]*template.Template{} 86 87 memoMutex = &sync.RWMutex{} 88) 89 90func getTemplate(tmpl string) (*template.Template, error) { 91 memoMutex.RLock() 92 if t, ok := memoizedGetTemplate[tmpl]; ok { 93 memoMutex.RUnlock() 94 return t, nil 95 } 96 memoMutex.RUnlock() 97 98 t, err := template.New("prompt").Funcs(TemplateFuncs).Parse(tmpl) 99 if err != nil { 100 return nil, err 101 } 102 103 memoMutex.Lock() 104 memoizedGetTemplate[tmpl] = t 105 memoMutex.Unlock() 106 return t, nil 107} 108 109func RunTemplate(tmpl string, data interface{}) (string, error) { 110 t, err := getTemplate(tmpl) 111 if err != nil { 112 return "", err 113 } 114 buf := bytes.NewBufferString("") 115 err = t.Execute(buf, data) 116 if err != nil { 117 return "", err 118 } 119 return buf.String(), err 120} 121