forked from zyedidia/terminal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
str.go
94 lines (84 loc) · 2.07 KB
/
str.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package terminal
import (
"strconv"
"strings"
)
// STR sequences are similar to CSI sequences, but have string arguments (and
// as far as I can tell, don't really have a name; STR is the name I took from
// suckless which I imagine comes from rxvt or xterm).
type strEscape struct {
typ rune
buf []rune
args []string
}
func (s *strEscape) reset() {
s.typ = 0
s.buf = s.buf[:0]
s.args = nil
}
func (s *strEscape) put(c rune) {
// TODO: improve allocs with an array backed slice; bench first
if len(s.buf) < 256 {
s.buf = append(s.buf, c)
}
// Going by st, it is better to remain silent when the STR sequence is not
// ended so that it is apparent to users something is wrong. The length sanity
// check ensures we don't absorb the entire stream into memory.
// TODO: see what rxvt or xterm does
}
func (s *strEscape) parse() {
s.args = strings.Split(string(s.buf), ";")
}
func (s *strEscape) arg(i, def int) int {
if i >= len(s.args) || i < 0 {
return def
}
i, err := strconv.Atoi(s.args[i])
if err != nil {
return def
}
return i
}
func (s *strEscape) argString(i int, def string) string {
if i >= len(s.args) || i < 0 {
return def
}
return s.args[i]
}
func (t *State) handleSTR() {
s := &t.str
s.parse()
switch s.typ {
case ']': // OSC - operating system command
switch d := s.arg(0, 0); d {
case 0, 1, 2:
title := s.argString(1, "")
if title != "" {
t.setTitle(title)
}
case 4: // color set
if len(s.args) < 3 {
break
}
// setcolorname(s.arg(1, 0), s.argString(2, ""))
case 104: // color reset
// TODO: complain about invalid color, redraw, etc.
// setcolorname(s.arg(1, 0), nil)
default:
t.logf("unknown OSC command %d\n", d)
// TODO: s.dump()
}
case 'k': // old title set compatibility
title := s.argString(0, "")
if title != "" {
t.setTitle(title)
}
default:
// TODO: Ignore these codes instead of complain?
// 'P': // DSC - device control string
// '_': // APC - application program command
// '^': // PM - privacy message
t.logf("unhandled STR sequence '%c'\n", s.typ)
// t.str.dump()
}
}