You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
2.5 KiB

  1. // deprecated.
  2. // see https://github.com/chzyer/readline/issues/43
  3. // use github.com/chzyer/readline/runes.go
  4. package runes
  5. import (
  6. "bytes"
  7. "unicode"
  8. )
  9. func Equal(a, b []rune) bool {
  10. if len(a) != len(b) {
  11. return false
  12. }
  13. for i := 0; i < len(a); i++ {
  14. if a[i] != b[i] {
  15. return false
  16. }
  17. }
  18. return true
  19. }
  20. // Search in runes from end to front
  21. func IndexAllBck(r, sub []rune) int {
  22. for i := len(r) - len(sub); i >= 0; i-- {
  23. found := true
  24. for j := 0; j < len(sub); j++ {
  25. if r[i+j] != sub[j] {
  26. found = false
  27. break
  28. }
  29. }
  30. if found {
  31. return i
  32. }
  33. }
  34. return -1
  35. }
  36. // Search in runes from front to end
  37. func IndexAll(r, sub []rune) int {
  38. for i := 0; i < len(r); i++ {
  39. found := true
  40. if len(r[i:]) < len(sub) {
  41. return -1
  42. }
  43. for j := 0; j < len(sub); j++ {
  44. if r[i+j] != sub[j] {
  45. found = false
  46. break
  47. }
  48. }
  49. if found {
  50. return i
  51. }
  52. }
  53. return -1
  54. }
  55. func Index(r rune, rs []rune) int {
  56. for i := 0; i < len(rs); i++ {
  57. if rs[i] == r {
  58. return i
  59. }
  60. }
  61. return -1
  62. }
  63. func ColorFilter(r []rune) []rune {
  64. newr := make([]rune, 0, len(r))
  65. for pos := 0; pos < len(r); pos++ {
  66. if r[pos] == '\033' && r[pos+1] == '[' {
  67. idx := Index('m', r[pos+2:])
  68. if idx == -1 {
  69. continue
  70. }
  71. pos += idx + 2
  72. continue
  73. }
  74. newr = append(newr, r[pos])
  75. }
  76. return newr
  77. }
  78. var zeroWidth = []*unicode.RangeTable{
  79. unicode.Mn,
  80. unicode.Me,
  81. unicode.Cc,
  82. unicode.Cf,
  83. }
  84. var doubleWidth = []*unicode.RangeTable{
  85. unicode.Han,
  86. unicode.Hangul,
  87. unicode.Hiragana,
  88. unicode.Katakana,
  89. }
  90. func Width(r rune) int {
  91. if unicode.IsOneOf(zeroWidth, r) {
  92. return 0
  93. }
  94. if unicode.IsOneOf(doubleWidth, r) {
  95. return 2
  96. }
  97. return 1
  98. }
  99. func WidthAll(r []rune) (length int) {
  100. for i := 0; i < len(r); i++ {
  101. length += Width(r[i])
  102. }
  103. return
  104. }
  105. func Backspace(r []rune) []byte {
  106. return bytes.Repeat([]byte{'\b'}, WidthAll(r))
  107. }
  108. func Copy(r []rune) []rune {
  109. n := make([]rune, len(r))
  110. copy(n, r)
  111. return n
  112. }
  113. func HasPrefix(r, prefix []rune) bool {
  114. if len(r) < len(prefix) {
  115. return false
  116. }
  117. return Equal(r[:len(prefix)], prefix)
  118. }
  119. func Aggregate(candicate [][]rune) (same []rune, size int) {
  120. for i := 0; i < len(candicate[0]); i++ {
  121. for j := 0; j < len(candicate)-1; j++ {
  122. if i >= len(candicate[j]) || i >= len(candicate[j+1]) {
  123. goto aggregate
  124. }
  125. if candicate[j][i] != candicate[j+1][i] {
  126. goto aggregate
  127. }
  128. }
  129. size = i + 1
  130. }
  131. aggregate:
  132. if size > 0 {
  133. same = Copy(candicate[0][:size])
  134. for i := 0; i < len(candicate); i++ {
  135. n := Copy(candicate[i])
  136. copy(n, n[size:])
  137. candicate[i] = n[:len(n)-size]
  138. }
  139. }
  140. return
  141. }