diff options
Diffstat (limited to 'vendor/github.com/lunixbochs/vtclean/vtclean.go')
-rw-r--r-- | vendor/github.com/lunixbochs/vtclean/vtclean.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/vendor/github.com/lunixbochs/vtclean/vtclean.go b/vendor/github.com/lunixbochs/vtclean/vtclean.go new file mode 100644 index 000000000..64fe01fdb --- /dev/null +++ b/vendor/github.com/lunixbochs/vtclean/vtclean.go @@ -0,0 +1,95 @@ +package vtclean + +import ( + "bytes" + "regexp" + "strconv" +) + +// regex based on ECMA-48: +// 1. optional: +// one of [ or ] +// any amount of 0x30-0x3f +// any amount of 0x20-0x2f +// 3. exactly one 0x40-0x7e +var vt100re = regexp.MustCompile(`^\033([\[\]]([0-9:;<=>\?]*)([!"#$%&'()*+,\-./]*))?([@A-Z\[\]^_\x60a-z{|}~])`) +var vt100exc = regexp.MustCompile(`^\033(\[[^a-zA-Z0-9@\?]+|[\(\)]).`) + +// this is to handle the RGB escape generated by `tput initc 1 500 500 500` +var vt100long = regexp.MustCompile(`^\033](\d+);([^\033]+)\033\\`) + +func Clean(line string, color bool) string { + var edit = newLineEdit(len(line)) + lineb := []byte(line) + + hadColor := false + for i := 0; i < len(lineb); { + c := lineb[i] + switch c { + case '\r': + edit.MoveAbs(0) + case '\b': + edit.Move(-1) + case '\033': + // set terminal title + if bytes.HasPrefix(lineb[i:], []byte("\x1b]0;")) { + pos := bytes.Index(lineb[i:], []byte("\a")) + if pos != -1 { + i += pos + 1 + continue + } + } + if m := vt100long.Find(lineb[i:]); m != nil { + i += len(m) + } else if m := vt100exc.Find(lineb[i:]); m != nil { + i += len(m) + } else if m := vt100re.FindSubmatch(lineb[i:]); m != nil { + i += len(m[0]) + num := string(m[2]) + n, err := strconv.Atoi(num) + if err != nil || n > 10000 { + n = 1 + } + switch m[4][0] { + case 'm': + if color { + hadColor = true + edit.Vt100(m[0]) + } + case '@': + edit.Insert(bytes.Repeat([]byte{' '}, n)) + case 'G': + edit.MoveAbs(n) + case 'C': + edit.Move(n) + case 'D': + edit.Move(-n) + case 'P': + edit.Delete(n) + case 'K': + switch num { + case "", "0": + edit.ClearRight() + case "1": + edit.ClearLeft() + case "2": + edit.Clear() + } + } + } else { + i += 1 + } + continue + default: + if c == '\n' || c == '\t' || c >= ' ' { + edit.Write([]byte{c}) + } + } + i += 1 + } + out := edit.Bytes() + if hadColor { + out = append(out, []byte("\033[0m")...) + } + return string(out) +} |