print.go 3.1 KB

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