David K. Bainbridge | 528b318 | 2017-01-23 08:51:59 -0800 | [diff] [blame] | 1 | package vtclean |
| 2 | |
| 3 | type char struct { |
| 4 | char byte |
| 5 | vt100 []byte |
| 6 | } |
| 7 | |
| 8 | func chars(p []byte) []char { |
| 9 | tmp := make([]char, len(p)) |
| 10 | for i, v := range p { |
| 11 | tmp[i].char = v |
| 12 | } |
| 13 | return tmp |
| 14 | } |
| 15 | |
| 16 | type lineEdit struct { |
| 17 | buf []char |
| 18 | pos, size int |
| 19 | vt100 []byte |
| 20 | } |
| 21 | |
| 22 | func newLineEdit(length int) *lineEdit { |
| 23 | return &lineEdit{buf: make([]char, length)} |
| 24 | } |
| 25 | |
| 26 | func (l *lineEdit) Vt100(p []byte) { |
| 27 | l.vt100 = p |
| 28 | } |
| 29 | |
| 30 | func (l *lineEdit) Move(x int) { |
| 31 | if x < 0 && l.pos <= -x { |
| 32 | l.pos = 0 |
| 33 | } else if x > 0 && l.pos+x > l.size { |
| 34 | l.pos = l.size |
| 35 | } else { |
| 36 | l.pos += x |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | func (l *lineEdit) Write(p []byte) { |
| 41 | c := chars(p) |
| 42 | if len(c) > 0 { |
| 43 | c[0].vt100 = l.vt100 |
| 44 | l.vt100 = nil |
| 45 | } |
| 46 | if len(l.buf)-l.pos < len(c) { |
| 47 | l.buf = append(l.buf[:l.pos], c...) |
| 48 | } else { |
| 49 | copy(l.buf[l.pos:], c) |
| 50 | } |
| 51 | l.pos += len(c) |
| 52 | if l.pos > l.size { |
| 53 | l.size = l.pos |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | func (l *lineEdit) Insert(p []byte) { |
| 58 | c := chars(p) |
| 59 | if len(c) > 0 { |
| 60 | c[0].vt100 = l.vt100 |
| 61 | l.vt100 = nil |
| 62 | } |
| 63 | l.size += len(c) |
| 64 | c = append(c, l.buf[l.pos:]...) |
| 65 | l.buf = append(l.buf[:l.pos], c...) |
| 66 | } |
| 67 | |
| 68 | func (l *lineEdit) Delete(n int) { |
| 69 | most := l.size - l.pos |
| 70 | if n > most { |
| 71 | n = most |
| 72 | } |
| 73 | copy(l.buf[l.pos:], l.buf[l.pos+n:]) |
| 74 | l.size -= n |
| 75 | } |
| 76 | |
| 77 | func (l *lineEdit) Clear() { |
| 78 | for i := 0; i < len(l.buf); i++ { |
| 79 | l.buf[i].char = ' ' |
| 80 | } |
| 81 | } |
| 82 | func (l *lineEdit) ClearLeft() { |
| 83 | for i := 0; i < l.pos+1; i++ { |
| 84 | l.buf[i].char = ' ' |
| 85 | } |
| 86 | } |
| 87 | func (l *lineEdit) ClearRight() { |
| 88 | l.size = l.pos |
| 89 | } |
| 90 | |
| 91 | func (l *lineEdit) Bytes() []byte { |
| 92 | length := 0 |
| 93 | buf := l.buf[:l.size] |
| 94 | for _, v := range buf { |
| 95 | length += 1 + len(v.vt100) |
| 96 | } |
| 97 | tmp := make([]byte, 0, length) |
| 98 | for _, v := range buf { |
| 99 | tmp = append(tmp, v.vt100...) |
| 100 | tmp = append(tmp, v.char) |
| 101 | } |
| 102 | return tmp |
| 103 | } |
| 104 | |
| 105 | func (l *lineEdit) String() string { |
| 106 | return string(l.Bytes()) |
| 107 | } |