print.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package text
  2. import (
  3. "fmt"
  4. "os"
  5. "strconv"
  6. "strings"
  7. "syscall"
  8. "unicode"
  9. "github.com/leonelquinteros/gotext"
  10. "golang.org/x/sys/unix"
  11. )
  12. const (
  13. arrow = "==>"
  14. smallArrow = " ->"
  15. opSymbol = "::"
  16. )
  17. var (
  18. cachedColumnCount = -1
  19. DebugMode = false
  20. )
  21. func Debugln(a ...interface{}) {
  22. if !DebugMode {
  23. return
  24. }
  25. fmt.Fprintln(os.Stdout, append([]interface{}{Bold(yellow("[DEBUG]"))}, a...)...)
  26. fmt.Fprint(os.Stdout, ResetCode)
  27. }
  28. func OperationInfoln(a ...interface{}) {
  29. fmt.Fprint(os.Stdout, append([]interface{}{Bold(Cyan(opSymbol + " ")), boldCode}, a...)...)
  30. fmt.Fprintln(os.Stdout, ResetCode)
  31. }
  32. func OperationInfo(a ...interface{}) {
  33. fmt.Fprint(os.Stdout, append([]interface{}{Bold(Cyan(opSymbol + " ")), boldCode}, a...)...)
  34. fmt.Fprint(os.Stdout, ResetCode)
  35. }
  36. func SprintOperationInfo(a ...interface{}) string {
  37. return fmt.Sprint(append([]interface{}{Bold(Cyan(opSymbol + " ")), boldCode}, a...)...) + ResetCode
  38. }
  39. func Info(a ...interface{}) {
  40. fmt.Fprint(os.Stdout, append([]interface{}{Bold(Green(arrow + " "))}, a...)...)
  41. }
  42. func Infoln(a ...interface{}) {
  43. fmt.Fprintln(os.Stdout, append([]interface{}{Bold(Green(arrow))}, a...)...)
  44. }
  45. func SprintWarn(a ...interface{}) string {
  46. return fmt.Sprint(append([]interface{}{Bold(yellow(smallArrow + " "))}, a...)...)
  47. }
  48. func Warn(a ...interface{}) {
  49. fmt.Fprint(os.Stdout, append([]interface{}{Bold(yellow(smallArrow + " "))}, a...)...)
  50. }
  51. func Warnln(a ...interface{}) {
  52. fmt.Fprintln(os.Stdout, append([]interface{}{Bold(yellow(smallArrow))}, a...)...)
  53. }
  54. func SprintError(a ...interface{}) string {
  55. return fmt.Sprint(append([]interface{}{Bold(Red(smallArrow + " "))}, a...)...)
  56. }
  57. func Error(a ...interface{}) {
  58. fmt.Fprint(os.Stderr, append([]interface{}{Bold(Red(smallArrow + " "))}, a...)...)
  59. }
  60. func Errorln(a ...interface{}) {
  61. fmt.Fprintln(os.Stderr, append([]interface{}{Bold(Red(smallArrow))}, a...)...)
  62. }
  63. func getColumnCount() int {
  64. if cachedColumnCount > 0 {
  65. return cachedColumnCount
  66. }
  67. if count, err := strconv.Atoi(os.Getenv("COLUMNS")); err == nil {
  68. cachedColumnCount = count
  69. return cachedColumnCount
  70. }
  71. if ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ); err == nil {
  72. cachedColumnCount = int(ws.Col)
  73. return cachedColumnCount
  74. }
  75. return 80
  76. }
  77. func PrintInfoValue(key string, values ...string) {
  78. const (
  79. keyLength = 32
  80. delimCount = 2
  81. )
  82. specialWordsCount := 0
  83. for _, runeValue := range key {
  84. // CJK handling: the character 'ー' is Katakana
  85. // but if use unicode.Katakana, it will return false
  86. if unicode.IsOneOf([]*unicode.RangeTable{
  87. unicode.Han,
  88. unicode.Hiragana,
  89. unicode.Katakana,
  90. unicode.Hangul,
  91. }, runeValue) || runeValue == 'ー' {
  92. specialWordsCount++
  93. }
  94. }
  95. keyTextCount := specialWordsCount - keyLength + delimCount
  96. str := fmt.Sprintf(Bold("%-*s: "), keyTextCount, key)
  97. if len(values) == 0 || (len(values) == 1 && values[0] == "") {
  98. fmt.Fprintf(os.Stdout, "%s%s\n", str, gotext.Get("None"))
  99. return
  100. }
  101. maxCols := getColumnCount()
  102. cols := keyLength + len(values[0])
  103. str += values[0]
  104. for _, value := range values[1:] {
  105. if maxCols > keyLength && cols+len(value)+delimCount >= maxCols {
  106. cols = keyLength
  107. str += "\n" + strings.Repeat(" ", keyLength)
  108. } else if cols != keyLength {
  109. str += strings.Repeat(" ", delimCount)
  110. cols += delimCount
  111. }
  112. str += value
  113. cols += len(value)
  114. }
  115. fmt.Println(str)
  116. }