forked from mattn/go-tty
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtty.go
124 lines (105 loc) · 2.08 KB
/
tty.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package tty
import (
"os"
"strings"
"unicode"
)
func Open() (*TTY, error) {
return open()
}
func (tty *TTY) Raw() (func() error, error) {
return tty.raw()
}
func (tty *TTY) MustRaw() func() error {
f, err := tty.raw()
if err != nil {
panic(err.Error())
}
return f
}
func (tty *TTY) Buffered() bool {
return tty.buffered()
}
func (tty *TTY) ReadRune() (rune, error) {
return tty.readRune()
}
func (tty *TTY) Close() error {
return tty.close()
}
func (tty *TTY) Size() (int, int, error) {
return tty.size()
}
func (tty *TTY) SizePixel() (int, int, int, int, error) {
return tty.sizePixel()
}
func (tty *TTY) Input() *os.File {
return tty.input()
}
func (tty *TTY) Output() *os.File {
return tty.output()
}
// Display types.
const (
displayNone = iota
displayRune
displayMask
)
func (tty *TTY) readString(displayType int) (string, error) {
rs := []rune{}
loop:
for {
r, err := tty.readRune()
if err != nil {
return "", err
}
switch r {
case 13:
break loop
case 8, 127:
if len(rs) > 0 {
rs = rs[:len(rs)-1]
if displayType != displayNone {
tty.Output().WriteString("\b \b")
}
}
default:
if unicode.IsPrint(r) {
rs = append(rs, r)
switch displayType {
case displayRune:
tty.Output().WriteString(string(r))
case displayMask:
tty.Output().WriteString("*")
}
}
}
}
return string(rs), nil
}
func (tty *TTY) ReadString() (string, error) {
defer tty.Output().WriteString("\n")
return tty.readString(displayRune)
}
func (tty *TTY) ReadPassword() (string, error) {
defer tty.Output().WriteString("\n")
return tty.readString(displayMask)
}
func (tty *TTY) ReadPasswordNoEcho() (string, error) {
defer tty.Output().WriteString("\n")
return tty.readString(displayNone)
}
func (tty *TTY) ReadPasswordClear() (string, error) {
s, err := tty.readString(displayMask)
tty.Output().WriteString(
strings.Repeat("\b", len(s)) +
strings.Repeat(" ", len(s)) +
strings.Repeat("\b", len(s)))
return s, err
}
type WINSIZE struct {
W int
H int
}
func (tty *TTY) SIGWINCH() chan WINSIZE {
return tty.sigwinch()
}