mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-04 17:41:50 +08:00
108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package terminalparser
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/mattn/go-runewidth"
|
|
)
|
|
|
|
type Row struct {
|
|
dataRune []rune
|
|
currentX int
|
|
currentRuneIndex int
|
|
|
|
// fish shell 补全提示
|
|
tipRune []rune
|
|
tipRecord bool
|
|
}
|
|
|
|
func (r *Row) String() string {
|
|
return strings.TrimSuffix(string(r.dataRune), string(r.tipRune))
|
|
}
|
|
|
|
func (r *Row) appendCharacter(code rune) {
|
|
width := runewidth.StringWidth(string(code))
|
|
if r.currentRuneIndex < len(r.dataRune) {
|
|
r.dataRune[r.currentRuneIndex] = code
|
|
} else {
|
|
r.dataRune = append(r.dataRune, code)
|
|
|
|
}
|
|
r.currentRuneIndex++
|
|
r.currentX += width
|
|
r.addTipRune(code)
|
|
}
|
|
|
|
func (r *Row) insertCharacters(data []rune) {
|
|
result := make([]rune, len(r.dataRune)+len(data))
|
|
copy(result, r.dataRune[:r.currentRuneIndex])
|
|
copy(result[r.currentRuneIndex:], data)
|
|
copy(result[r.currentRuneIndex+len(data):], r.dataRune[r.currentRuneIndex:])
|
|
for i := range data {
|
|
r.currentRuneIndex++
|
|
r.currentX += runewidth.StringWidth(string(data[i]))
|
|
}
|
|
r.dataRune = result
|
|
}
|
|
|
|
func (r *Row) eraseRight() {
|
|
r.dataRune = r.dataRune[:r.currentRuneIndex]
|
|
}
|
|
|
|
func (r *Row) deleteChars(ps int) {
|
|
result := make([]rune, r.currentRuneIndex, len(r.dataRune))
|
|
copy(result, r.dataRune[:r.currentRuneIndex])
|
|
rest := r.dataRune[r.currentRuneIndex:]
|
|
inits := ps
|
|
for i := range rest {
|
|
inits -= runewidth.StringWidth(string(rest[i]))
|
|
if inits == 0 {
|
|
result = append(result, rest[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
r.dataRune = result
|
|
}
|
|
|
|
func (r *Row) changeCurrentRuneIndex() {
|
|
if r.currentX < 0 {
|
|
r.currentX = 0
|
|
}
|
|
currentRuneIndex := 0
|
|
for i := range r.dataRune {
|
|
currentRuneIndex += runewidth.StringWidth(string(r.dataRune[i]))
|
|
if currentRuneIndex > r.currentX {
|
|
r.currentRuneIndex = i
|
|
return
|
|
}
|
|
}
|
|
r.currentRuneIndex = len(r.dataRune)
|
|
}
|
|
|
|
func (r *Row) changeCursorToX(x int) {
|
|
if r.currentX == x {
|
|
return
|
|
}
|
|
r.currentX = x
|
|
r.changeCurrentRuneIndex()
|
|
}
|
|
|
|
func (r *Row) startRecord() {
|
|
r.tipRecord = true
|
|
r.tipRune = make([]rune, 0, 100)
|
|
}
|
|
|
|
func (r *Row) stopRecord() {
|
|
if !r.tipRecord {
|
|
r.tipRune = make([]rune, 0, 100)
|
|
}
|
|
r.tipRecord = false
|
|
}
|
|
|
|
func (r *Row) addTipRune(code rune) {
|
|
if r.tipRecord {
|
|
r.tipRune = append(r.tipRune, code)
|
|
}
|
|
|
|
}
|