summaryrefslogtreecommitdiff
path: root/vendor/github.com/lunixbochs/vtclean/line.go
blob: 66ee990be6fabedbc8bd8e61759affb042744140 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package vtclean

type char struct {
	char  byte
	vt100 []byte
}

func chars(p []byte) []char {
	tmp := make([]char, len(p))
	for i, v := range p {
		tmp[i].char = v
	}
	return tmp
}

type lineEdit struct {
	buf       []char
	pos, size int
	vt100     []byte
}

func newLineEdit(length int) *lineEdit {
	return &lineEdit{buf: make([]char, length)}
}

func (l *lineEdit) Vt100(p []byte) {
	l.vt100 = p
}

func (l *lineEdit) Move(x int) {
	if x < 0 && l.pos <= -x {
		l.pos = 0
	} else if x > 0 && l.pos+x > l.size {
		l.pos = l.size
	} else {
		l.pos += x
	}
}

func (l *lineEdit) MoveAbs(x int) {
	if x < l.size {
		l.pos = x
	}
}

func (l *lineEdit) Write(p []byte) {
	c := chars(p)
	if len(c) > 0 {
		c[0].vt100 = l.vt100
		l.vt100 = nil
	}
	if len(l.buf)-l.pos < len(c) {
		l.buf = append(l.buf[:l.pos], c...)
	} else {
		copy(l.buf[l.pos:], c)
	}
	l.pos += len(c)
	if l.pos > l.size {
		l.size = l.pos
	}
}

func (l *lineEdit) Insert(p []byte) {
	c := chars(p)
	if len(c) > 0 {
		c[0].vt100 = l.vt100
		l.vt100 = nil
	}
	l.size += len(c)
	c = append(c, l.buf[l.pos:]...)
	l.buf = append(l.buf[:l.pos], c...)
}

func (l *lineEdit) Delete(n int) {
	most := l.size - l.pos
	if n > most {
		n = most
	}
	copy(l.buf[l.pos:], l.buf[l.pos+n:])
	l.size -= n
}

func (l *lineEdit) Clear() {
	for i := 0; i < len(l.buf); i++ {
		l.buf[i].char = ' '
	}
}
func (l *lineEdit) ClearLeft() {
	for i := 0; i < l.pos+1; i++ {
		l.buf[i].char = ' '
	}
}
func (l *lineEdit) ClearRight() {
	l.size = l.pos
}

func (l *lineEdit) Bytes() []byte {
	length := 0
	buf := l.buf[:l.size]
	for _, v := range buf {
		length += 1 + len(v.vt100)
	}
	tmp := make([]byte, 0, length)
	for _, v := range buf {
		tmp = append(tmp, v.vt100...)
		tmp = append(tmp, v.char)
	}
	return tmp
}

func (l *lineEdit) String() string {
	return string(l.Bytes())
}