@@ -22,11 +22,10 @@ const (
2222
2323// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation.
2424type ansiReader struct {
25- file * os.File
26- fd uintptr
27- buffer []byte
28- cbBuffer int
29- command []byte
25+ file * os.File
26+ fd uintptr
27+ buffer []byte
28+ command []byte
3029}
3130
3231// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a
@@ -99,11 +98,8 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
9998
10099// readInputEvents polls until at least one event is available.
101100func readInputEvents (ar * ansiReader , maxBytes int ) ([]winterm.INPUT_RECORD , error ) {
102- // Determine the maximum number of records to retrieve
103- // -- Cast around the type system to obtain the size of a single INPUT_RECORD.
104- // unsafe.Sizeof requires an expression vs. a type-reference; the casting
105- // tricks the type system into believing it has such an expression.
106- recordSize := int (unsafe .Sizeof (* ((* winterm .INPUT_RECORD )(unsafe .Pointer (& maxBytes )))))
101+ // Determine the size of a single INPUT_RECORD.
102+ recordSize := int (unsafe .Sizeof (winterm.INPUT_RECORD {}))
107103 countRecords := maxBytes / recordSize
108104 if countRecords > ansiterm .MAX_INPUT_EVENTS {
109105 countRecords = ansiterm .MAX_INPUT_EVENTS
@@ -167,9 +163,10 @@ var keyMapPrefix = map[uint16]string{
167163// translateKeyEvents converts the input events into the appropriate ANSI string.
168164func translateKeyEvents (events []winterm.INPUT_RECORD , escapeSequence []byte ) []byte {
169165 var buffer bytes.Buffer
170- for _ , event := range events {
166+ for i := range events {
167+ event := events [i ]
171168 if event .EventType == winterm .KEY_EVENT && event .KeyEvent .KeyDown != 0 {
172- buffer .WriteString (keyToString (& event .KeyEvent , escapeSequence ))
169+ buffer .WriteString (keyToString (& events [ i ] .KeyEvent , escapeSequence ))
173170 }
174171 }
175172
@@ -181,24 +178,24 @@ func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) stri
181178 if keyEvent .UnicodeChar == 0 {
182179 return formatVirtualKey (keyEvent .VirtualKeyCode , keyEvent .ControlKeyState , escapeSequence )
183180 }
184-
181+ key := string ( rune ( keyEvent . UnicodeChar ))
185182 _ , alt , control := getControlKeys (keyEvent .ControlKeyState )
186- if control {
183+ switch {
184+ case control && ! alt :
187185 // TODO(azlinux): Implement following control sequences
188186 // <Ctrl>-D Signals the end of input from the keyboard; also exits current shell.
189187 // <Ctrl>-H Deletes the first character to the left of the cursor. Also called the ERASE key.
190188 // <Ctrl>-Q Restarts printing after it has been stopped with <Ctrl>-s.
191189 // <Ctrl>-S Suspends printing on the screen (does not stop the program).
192190 // <Ctrl>-U Deletes all characters on the current line. Also called the KILL key.
193191 // <Ctrl>-E Quits current command and creates a core
192+ return key
193+ case ! control && alt :
194+ // <Alt>+Key generates ESC N Key
195+ return ansiterm .KEY_ESC_N + strings .ToLower (key )
196+ default :
197+ return key
194198 }
195-
196- // <Alt>+Key generates ESC N Key
197- if ! control && alt {
198- return ansiterm .KEY_ESC_N + strings .ToLower (string (rune (keyEvent .UnicodeChar )))
199- }
200-
201- return string (rune (keyEvent .UnicodeChar ))
202199}
203200
204201// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
@@ -219,9 +216,9 @@ func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) st
219216
220217// getControlKeys extracts the shift, alt, and ctrl key states.
221218func getControlKeys (controlState uint32 ) (shift , alt , control bool ) {
222- shift = 0 != ( controlState & winterm .SHIFT_PRESSED )
223- alt = 0 != ( controlState & (winterm .LEFT_ALT_PRESSED | winterm .RIGHT_ALT_PRESSED ))
224- control = 0 != ( controlState & (winterm .LEFT_CTRL_PRESSED | winterm .RIGHT_CTRL_PRESSED ))
219+ shift = controlState & winterm .SHIFT_PRESSED != 0
220+ alt = controlState & (winterm .LEFT_ALT_PRESSED | winterm .RIGHT_ALT_PRESSED ) != 0
221+ control = controlState & (winterm .LEFT_CTRL_PRESSED | winterm .RIGHT_CTRL_PRESSED ) != 0
225222 return shift , alt , control
226223}
227224
0 commit comments