| 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) 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()) |
| } |