Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/chzyer/readline/rawreader_windows.go
2875 views
1
// +build windows
2
3
package readline
4
5
import "unsafe"
6
7
const (
8
VK_CANCEL = 0x03
9
VK_BACK = 0x08
10
VK_TAB = 0x09
11
VK_RETURN = 0x0D
12
VK_SHIFT = 0x10
13
VK_CONTROL = 0x11
14
VK_MENU = 0x12
15
VK_ESCAPE = 0x1B
16
VK_LEFT = 0x25
17
VK_UP = 0x26
18
VK_RIGHT = 0x27
19
VK_DOWN = 0x28
20
VK_DELETE = 0x2E
21
VK_LSHIFT = 0xA0
22
VK_RSHIFT = 0xA1
23
VK_LCONTROL = 0xA2
24
VK_RCONTROL = 0xA3
25
)
26
27
// RawReader translate input record to ANSI escape sequence.
28
// To provides same behavior as unix terminal.
29
type RawReader struct {
30
ctrlKey bool
31
altKey bool
32
}
33
34
func NewRawReader() *RawReader {
35
r := new(RawReader)
36
return r
37
}
38
39
// only process one action in one read
40
func (r *RawReader) Read(buf []byte) (int, error) {
41
ir := new(_INPUT_RECORD)
42
var read int
43
var err error
44
next:
45
err = kernel.ReadConsoleInputW(stdin,
46
uintptr(unsafe.Pointer(ir)),
47
1,
48
uintptr(unsafe.Pointer(&read)),
49
)
50
if err != nil {
51
return 0, err
52
}
53
if ir.EventType != EVENT_KEY {
54
goto next
55
}
56
ker := (*_KEY_EVENT_RECORD)(unsafe.Pointer(&ir.Event[0]))
57
if ker.bKeyDown == 0 { // keyup
58
if r.ctrlKey || r.altKey {
59
switch ker.wVirtualKeyCode {
60
case VK_RCONTROL, VK_LCONTROL:
61
r.ctrlKey = false
62
case VK_MENU: //alt
63
r.altKey = false
64
}
65
}
66
goto next
67
}
68
69
if ker.unicodeChar == 0 {
70
var target rune
71
switch ker.wVirtualKeyCode {
72
case VK_RCONTROL, VK_LCONTROL:
73
r.ctrlKey = true
74
case VK_MENU: //alt
75
r.altKey = true
76
case VK_LEFT:
77
target = CharBackward
78
case VK_RIGHT:
79
target = CharForward
80
case VK_UP:
81
target = CharPrev
82
case VK_DOWN:
83
target = CharNext
84
}
85
if target != 0 {
86
return r.write(buf, target)
87
}
88
goto next
89
}
90
char := rune(ker.unicodeChar)
91
if r.ctrlKey {
92
switch char {
93
case 'A':
94
char = CharLineStart
95
case 'E':
96
char = CharLineEnd
97
case 'R':
98
char = CharBckSearch
99
case 'S':
100
char = CharFwdSearch
101
}
102
} else if r.altKey {
103
switch char {
104
case VK_BACK:
105
char = CharBackspace
106
}
107
return r.writeEsc(buf, char)
108
}
109
return r.write(buf, char)
110
}
111
112
func (r *RawReader) writeEsc(b []byte, char rune) (int, error) {
113
b[0] = '\033'
114
n := copy(b[1:], []byte(string(char)))
115
return n + 1, nil
116
}
117
118
func (r *RawReader) write(b []byte, char rune) (int, error) {
119
n := copy(b, []byte(string(char)))
120
return n, nil
121
}
122
123
func (r *RawReader) Close() error {
124
return nil
125
}
126
127