David K. Bainbridge | 528b318 | 2017-01-23 08:51:59 -0800 | [diff] [blame] | 1 | package vtclean |
| 2 | |
| 3 | import ( |
| 4 | "bytes" |
| 5 | "regexp" |
| 6 | "strconv" |
| 7 | ) |
| 8 | |
| 9 | // see regex.txt for a slightly separated version of this regex |
| 10 | var vt100re = regexp.MustCompile(`^\033([\[\]]([\d\?]+)?(;[\d\?]+)*)?(.)`) |
| 11 | var vt100exc = regexp.MustCompile(`^\033(\[[^a-zA-Z0-9@\?]+|[\(\)]).`) |
| 12 | |
| 13 | func Clean(line string, color bool) string { |
| 14 | var edit = newLineEdit(len(line)) |
| 15 | lineb := []byte(line) |
| 16 | |
| 17 | hadColor := false |
| 18 | for i := 0; i < len(lineb); { |
| 19 | c := lineb[i] |
| 20 | switch c { |
| 21 | case '\b': |
| 22 | edit.Move(-1) |
| 23 | case '\033': |
| 24 | // set terminal title |
| 25 | if bytes.HasPrefix(lineb[i:], []byte("\x1b]0;")) { |
| 26 | pos := bytes.Index(lineb[i:], []byte("\a")) |
| 27 | if pos != -1 { |
| 28 | i += pos + 1 |
| 29 | continue |
| 30 | } |
| 31 | } |
| 32 | if m := vt100exc.Find(lineb[i:]); m != nil { |
| 33 | i += len(m) |
| 34 | } else if m := vt100re.FindSubmatch(lineb[i:]); m != nil { |
| 35 | i += len(m[0]) |
| 36 | num := string(m[2]) |
| 37 | n, err := strconv.Atoi(num) |
| 38 | if err != nil || n > 10000 { |
| 39 | n = 1 |
| 40 | } |
| 41 | switch m[4][0] { |
| 42 | case 'm': |
| 43 | if color { |
| 44 | hadColor = true |
| 45 | edit.Vt100(m[0]) |
| 46 | } |
| 47 | case '@': |
| 48 | edit.Insert(bytes.Repeat([]byte{' '}, n)) |
| 49 | case 'C': |
| 50 | edit.Move(n) |
| 51 | case 'D': |
| 52 | edit.Move(-n) |
| 53 | case 'P': |
| 54 | edit.Delete(n) |
| 55 | case 'K': |
| 56 | switch num { |
| 57 | case "", "0": |
| 58 | edit.ClearRight() |
| 59 | case "1": |
| 60 | edit.ClearLeft() |
| 61 | case "2": |
| 62 | edit.Clear() |
| 63 | } |
| 64 | } |
| 65 | } else { |
| 66 | i += 1 |
| 67 | } |
| 68 | continue |
| 69 | default: |
| 70 | if c == '\n' || c >= ' ' { |
| 71 | edit.Write([]byte{c}) |
| 72 | } |
| 73 | } |
| 74 | i += 1 |
| 75 | } |
| 76 | out := edit.Bytes() |
| 77 | if hadColor { |
| 78 | out = append(out, []byte("\033[0m")...) |
| 79 | } |
| 80 | return string(out) |
| 81 | } |