print.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. GlobalLogger = NewLogger(os.Stdout, os.Stderr, os.Stdin, false, "global")
  20. )
  21. func Debugln(a ...interface{}) {
  22. GlobalLogger.Debugln(a...)
  23. }
  24. func OperationInfoln(a ...interface{}) {
  25. GlobalLogger.OperationInfoln(a...)
  26. }
  27. func OperationInfo(a ...interface{}) {
  28. GlobalLogger.OperationInfo(a...)
  29. }
  30. func SprintOperationInfo(a ...interface{}) string {
  31. return GlobalLogger.SprintOperationInfo(a...)
  32. }
  33. func Info(a ...interface{}) {
  34. GlobalLogger.Info(a...)
  35. }
  36. func Infoln(a ...interface{}) {
  37. GlobalLogger.Infoln(a...)
  38. }
  39. func SprintWarn(a ...interface{}) string {
  40. return GlobalLogger.SprintWarn(a...)
  41. }
  42. func Warn(a ...interface{}) {
  43. GlobalLogger.Warn(a...)
  44. }
  45. func Warnln(a ...interface{}) {
  46. GlobalLogger.Warnln(a...)
  47. }
  48. func SprintError(a ...interface{}) string {
  49. return GlobalLogger.SprintError(a...)
  50. }
  51. func Error(a ...interface{}) {
  52. GlobalLogger.Error(a...)
  53. }
  54. func Errorln(a ...interface{}) {
  55. GlobalLogger.Errorln(a...)
  56. }
  57. func getColumnCount() int {
  58. if cachedColumnCount > 0 {
  59. return cachedColumnCount
  60. }
  61. if count, err := strconv.Atoi(os.Getenv("COLUMNS")); err == nil {
  62. cachedColumnCount = count
  63. return cachedColumnCount
  64. }
  65. if ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ); err == nil {
  66. cachedColumnCount = int(ws.Col)
  67. return cachedColumnCount
  68. }
  69. return 80
  70. }
  71. func PrintInfoValue(key string, values ...string) {
  72. const (
  73. keyLength = 32
  74. delimCount = 2
  75. )
  76. specialWordsCount := 0
  77. for _, runeValue := range key {
  78. // CJK handling: the character 'ー' is Katakana
  79. // but if use unicode.Katakana, it will return false
  80. if unicode.IsOneOf([]*unicode.RangeTable{
  81. unicode.Han,
  82. unicode.Hiragana,
  83. unicode.Katakana,
  84. unicode.Hangul,
  85. }, runeValue) || runeValue == 'ー' {
  86. specialWordsCount++
  87. }
  88. }
  89. keyTextCount := specialWordsCount - keyLength + delimCount
  90. str := fmt.Sprintf(Bold("%-*s: "), keyTextCount, key)
  91. if len(values) == 0 || (len(values) == 1 && values[0] == "") {
  92. fmt.Fprintf(os.Stdout, "%s%s\n", str, gotext.Get("None"))
  93. return
  94. }
  95. maxCols := getColumnCount()
  96. cols := keyLength + len(values[0])
  97. str += values[0]
  98. for _, value := range values[1:] {
  99. if maxCols > keyLength && cols+len(value)+delimCount >= maxCols {
  100. cols = keyLength
  101. str += "\n" + strings.Repeat(" ", keyLength)
  102. } else if cols != keyLength {
  103. str += strings.Repeat(" ", delimCount)
  104. cols += delimCount
  105. }
  106. str += value
  107. cols += len(value)
  108. }
  109. fmt.Println(str)
  110. }