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