template.go 2.6 KB

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