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  }