github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/unicode.go (about)

     1  package readline
     2  
     3  import "github.com/mattn/go-runewidth"
     4  
     5  type UnicodeT struct {
     6  	rl    *Instance
     7  	value []rune
     8  	rPos  int
     9  	cPos  int
    10  }
    11  
    12  func (u *UnicodeT) Set(rl *Instance, r []rune) {
    13  	u.rl = rl
    14  	u.value = r
    15  	u.cPos = u.cellPos()
    16  }
    17  
    18  func (u *UnicodeT) Runes() []rune {
    19  	return u.value
    20  }
    21  
    22  func (u *UnicodeT) String() string {
    23  	return string(u.value)
    24  }
    25  
    26  func (u *UnicodeT) RuneLen() int {
    27  	return len(u.value)
    28  }
    29  
    30  func (u *UnicodeT) RunePos() int {
    31  	return u.rPos
    32  }
    33  
    34  func (u *UnicodeT) _offByOne(i int) int {
    35  	if len(u.value) == 0 {
    36  		return 0
    37  	}
    38  	if u.rl != nil && u.rl.modeViMode != vimInsert && i == len(u.value) {
    39  		i = len(u.value) - 1
    40  	}
    41  	return i
    42  }
    43  
    44  func (u *UnicodeT) SetRunePos(i int) {
    45  	if i < 0 {
    46  		i = 0
    47  	}
    48  	if i > len(u.value) {
    49  		i = len(u.value)
    50  	}
    51  
    52  	u.rPos = u._offByOne(i)
    53  	u.cPos = u.cellPos()
    54  }
    55  
    56  func (u *UnicodeT) Duplicate() *UnicodeT {
    57  	dup := new(UnicodeT)
    58  	dup.value = make([]rune, len(u.value))
    59  	copy(dup.value, u.value)
    60  	dup.rPos = u.rPos
    61  	dup.cPos = u.cPos
    62  	return dup
    63  }
    64  
    65  func (u *UnicodeT) CellLen() int {
    66  	return runewidth.StringWidth(u.String())
    67  }
    68  
    69  func (u *UnicodeT) cellPos() int {
    70  	var cPos, i, last int
    71  	for ; i < len(u.value) && i < u.rPos; i++ {
    72  		w := runewidth.RuneWidth(u.value[i])
    73  		cPos += w
    74  		last = w
    75  	}
    76  	if last == 2 {
    77  		cPos--
    78  	}
    79  
    80  	return cPos
    81  }
    82  
    83  func (u *UnicodeT) CellPos() int {
    84  	return u.cPos
    85  }
    86  
    87  func (u *UnicodeT) SetCellPos(cPos int) {
    88  	u._setCellPos(cPos)
    89  	i := u._offByOne(u.rPos)
    90  	if i != u.rPos {
    91  		u.rPos--
    92  		u.cPos -= runewidth.RuneWidth(u.value[u.rPos])
    93  	}
    94  }
    95  
    96  func (u *UnicodeT) _setCellPos(cPos int) {
    97  	if len(u.value) == 0 {
    98  		return
    99  	}
   100  
   101  	u.cPos = 0
   102  	var last int
   103  	for u.rPos = 0; u.rPos < len(u.value); u.rPos++ {
   104  		if u.cPos >= cPos {
   105  			if last == 2 {
   106  				u.cPos--
   107  			}
   108  			return
   109  		}
   110  		w := runewidth.RuneWidth(u.value[u.rPos])
   111  		u.cPos += w
   112  		last = w
   113  	}
   114  
   115  	if last == 2 {
   116  		u.cPos--
   117  	}
   118  	u.rPos = len(u.value)
   119  	if u.rPos < 0 {
   120  		u.rPos = 0
   121  	}
   122  }