Skip to content

Commit 30bbdcb

Browse files
committed
refactor: buffer sequences of text in between CSI escape sequences
1 parent 8169375 commit 30bbdcb

File tree

2 files changed

+53
-50
lines changed

2 files changed

+53
-50
lines changed

engine/csi/csi.go

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,58 @@ func NewReader(r io.Reader) *Reader {
2020
}
2121

2222
func (r *Reader) Read() (Segment, error) {
23+
var buf []byte
2324
for {
24-
var buf []byte
2525
b, err := r.r.ReadByte()
2626
if err != nil {
27+
if buf != nil {
28+
return Text(buf), nil
29+
}
2730
return nil, err
2831
}
32+
33+
// Not an escape sequence, accumulate.
34+
if b != '\033' {
35+
buf = append(buf, b)
36+
continue
37+
}
38+
39+
// Flush any buffered text.
40+
if b == '\033' && len(buf) > 0 {
41+
_ = r.r.UnreadByte()
42+
return Text(buf), nil
43+
}
44+
45+
buf = append(buf, b)
46+
47+
// Escape sequence.
48+
b, err = r.r.ReadByte()
49+
if err != nil {
50+
return Text(buf), nil
51+
}
2952
buf = append(buf, b)
30-
switch b {
31-
case '\033':
53+
c := CSI{}
54+
for {
55+
// Aborted escape sequence.
3256
b, err := r.r.ReadByte()
3357
if err != nil {
3458
return Text(buf), nil
3559
}
3660
buf = append(buf, b)
37-
c := CSI{}
38-
for {
39-
// Aborted escape sequence.
40-
b, err := r.r.ReadByte()
41-
if err != nil {
42-
return Text(buf), nil
43-
}
44-
buf = append(buf, b)
45-
switch {
46-
case b >= 0x30 && b <= 0x3f:
47-
c.Params = append(c.Params, b)
48-
49-
case b >= 0x20 && b <= 0x2f:
50-
c.Intermediate = append(c.Intermediate, b)
51-
52-
case b >= 0x40 && b <= 0x7e:
53-
c.Final = b
54-
return c, nil
55-
56-
default:
57-
return Text(buf), nil
58-
}
59-
}
61+
switch {
62+
case b >= 0x30 && b <= 0x3f:
63+
c.Params = append(c.Params, b)
6064

61-
default:
62-
return Text(buf), nil
65+
case b >= 0x20 && b <= 0x2f:
66+
c.Intermediate = append(c.Intermediate, b)
67+
68+
case b >= 0x40 && b <= 0x7e:
69+
c.Final = b
70+
return c, nil
71+
72+
default:
73+
return Text(buf), nil
74+
}
6375
}
6476
}
6577
}

engine/csi/csi_test.go

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,20 @@ func TestCSI(t *testing.T) {
2626
}
2727
expected := []Segment{
2828
CSI{Params: []byte("0"), Final: 74}, CSI{Params: []byte("0"), Final: 74},
29-
Text{62}, Text{62}, Text{62}, Text{34}, Text{92}, Text{48}, Text{51},
30-
Text{51}, Text{91}, Text{63}, Text{34}, Text{62}, Text{62}, Text{62},
31-
Text{32}, CSI{Params: []byte("?25"), Final: 108}, CSI{Params: []byte("32"), Final: 109},
32-
Text{226}, Text{160}, Text{139}, CSI{Params: []byte("39"), Final: 109},
33-
Text{32}, CSI{Params: []byte("90"), Final: 109}, CSI{Params: []byte("1"), Final: 109},
34-
Text{66}, Text{117}, Text{105}, Text{108}, Text{100}, Text{105}, Text{110},
35-
Text{103}, Text{32}, Text{105}, Text{110}, Text{100}, Text{101}, Text{120},
36-
Text{46}, Text{104}, Text{116}, Text{109}, Text{108}, Text{46}, Text{46},
37-
Text{46}, CSI{Params: []byte("22"), Final: 109}, CSI{Params: []byte("39"), Final: 109},
38-
Text{32}, Text{62}, Text{62}, Text{62}, Text{34}, Text{10}, Text{34},
39-
Text{62}, Text{62}, Text{62}, Text{32}, CSI{Params: []byte("2"), Final: 75},
40-
CSI{Params: []byte("19"), Final: 71}, CSI{Params: []byte("1"), Final: 65},
41-
CSI{Params: []byte("2"), Final: 75}, CSI{Params: []byte("19"), Final: 71},
42-
CSI{Params: []byte("32"), Final: 109}, Text{62}, Text{62}, Text{62}, Text{34},
43-
Text{226}, Text{34}, Text{62}, Text{62}, Text{62}, Text{32}, Text{226},
44-
Text{160}, Text{153}, CSI{Params: []byte("39"), Final: 109}, Text{32},
29+
Text{62, 62, 62, 34, 92, 48, 51, 51, 91, 63, 34, 62, 62, 62, 32},
30+
CSI{Params: []byte("?25"), Final: 108}, CSI{Params: []byte("32"), Final: 109},
31+
Text{226, 160, 139}, CSI{Params: []byte("39"), Final: 109}, Text{32},
4532
CSI{Params: []byte("90"), Final: 109}, CSI{Params: []byte("1"), Final: 109},
46-
Text{66}, Text{117}, Text{105}, Text{108}, Text{100}, Text{105}, Text{110},
47-
Text{103}, Text{32}, Text{105}, Text{110}, Text{100}, Text{101}, Text{120},
48-
Text{46}, Text{104}, Text{116}, Text{109}, Text{108}, Text{46}, Text{46},
49-
Text{46}, CSI{Params: []byte("22"), Final: 109},
50-
CSI{Params: []byte("39"), Final: 109}, Text{32}, Text{62}, Text{62}, Text{62},
51-
Text{34}, Text{10}, Text{34}, Text{62}, Text{62}, Text{62},
33+
Text{66, 117, 105, 108, 100, 105, 110, 103, 32, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 46, 46, 46},
34+
CSI{Params: []byte("22"), Final: 109}, CSI{Params: []byte("39"), Final: 109}, Text{32, 62, 62, 62, 34, 10, 34, 62, 62, 62, 32},
35+
CSI{Params: []byte("2"), Final: 75}, CSI{Params: []byte("19"), Final: 71},
36+
CSI{Params: []byte("1"), Final: 65}, CSI{Params: []byte("2"), Final: 75},
37+
CSI{Params: []byte("19"), Final: 71}, CSI{Params: []byte("32"), Final: 109},
38+
Text{62, 62, 62, 34, 226, 34, 62, 62, 62, 32, 226, 160, 153}, CSI{Params: []byte("39"), Final: 109},
39+
Text{32}, CSI{Params: []byte("90"), Final: 109}, CSI{Params: []byte("1"), Final: 109},
40+
Text{66, 117, 105, 108, 100, 105, 110, 103, 32, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 46, 46, 46},
41+
CSI{Params: []byte("22"), Final: 109}, CSI{Params: []byte("39"), Final: 109},
42+
Text{32, 62, 62, 62, 34, 10, 34, 62, 62, 62},
5243
}
5344
assert.Equal(t, expected, segments, repr.String(segments))
5445
}

0 commit comments

Comments
 (0)