runewidth_posix.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // +build !windows,!js
  2. package runewidth
  3. import (
  4. "os"
  5. "regexp"
  6. "strings"
  7. )
  8. var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
  9. func IsEastAsian() bool {
  10. locale := os.Getenv("LC_CTYPE")
  11. if locale == "" {
  12. locale = os.Getenv("LANG")
  13. }
  14. // ignore C locale
  15. if locale == "POSIX" || locale == "C" {
  16. return false
  17. }
  18. if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
  19. return false
  20. }
  21. charset := strings.ToLower(locale)
  22. r := reLoc.FindStringSubmatch(locale)
  23. if len(r) == 2 {
  24. charset = strings.ToLower(r[1])
  25. }
  26. if strings.HasSuffix(charset, "@cjk_narrow") {
  27. return false
  28. }
  29. for pos, b := range []byte(charset) {
  30. if b == '@' {
  31. charset = charset[:pos]
  32. break
  33. }
  34. }
  35. mbc_max := 1
  36. switch charset {
  37. case "utf-8", "utf8":
  38. mbc_max = 6
  39. case "jis":
  40. mbc_max = 8
  41. case "eucjp":
  42. mbc_max = 3
  43. case "euckr", "euccn":
  44. mbc_max = 2
  45. case "sjis", "cp932", "cp51932", "cp936", "cp949", "cp950":
  46. mbc_max = 2
  47. case "big5":
  48. mbc_max = 2
  49. case "gbk", "gb2312":
  50. mbc_max = 2
  51. }
  52. if mbc_max > 1 && (charset[0] != 'u' ||
  53. strings.HasPrefix(locale, "ja") ||
  54. strings.HasPrefix(locale, "ko") ||
  55. strings.HasPrefix(locale, "zh")) {
  56. return true
  57. }
  58. return false
  59. }