@@ -169,6 +169,7 @@ pub(crate) fn parse_csi(buffer: &[u8]) -> Result<Option<InternalEvent>> {
169
169
b'<' => return parse_csi_sgr_mouse ( buffer) ,
170
170
b'I' => Some ( Event :: FocusGained ) ,
171
171
b'O' => Some ( Event :: FocusLost ) ,
172
+ b';' => return parse_csi_modifier_key_code ( buffer) ,
172
173
b'0' ..=b'9' => {
173
174
// Numbered escape code.
174
175
if buffer. len ( ) == 3 {
@@ -251,9 +252,30 @@ fn parse_modifiers(mask: u8) -> KeyModifiers {
251
252
if modifier_mask & 4 != 0 {
252
253
modifiers |= KeyModifiers :: CONTROL ;
253
254
}
255
+ if modifier_mask & 8 != 0 {
256
+ modifiers |= KeyModifiers :: SUPER ;
257
+ }
258
+ if modifier_mask & 16 != 0 {
259
+ modifiers |= KeyModifiers :: HYPER ;
260
+ }
261
+ if modifier_mask & 32 != 0 {
262
+ modifiers |= KeyModifiers :: META ;
263
+ }
254
264
modifiers
255
265
}
256
266
267
+ fn parse_modifiers_to_state ( mask : u8 ) -> KeyEventState {
268
+ let modifier_mask = mask. saturating_sub ( 1 ) ;
269
+ let mut state = KeyEventState :: empty ( ) ;
270
+ if modifier_mask & 64 != 0 {
271
+ state |= KeyEventState :: CAPS_LOCK ;
272
+ }
273
+ if modifier_mask & 128 != 0 {
274
+ state |= KeyEventState :: NUM_LOCK ;
275
+ }
276
+ state
277
+ }
278
+
257
279
fn parse_key_event_kind ( kind : u8 ) -> KeyEventKind {
258
280
match kind {
259
281
1 => KeyEventKind :: Press ,
@@ -265,11 +287,32 @@ fn parse_key_event_kind(kind: u8) -> KeyEventKind {
265
287
266
288
pub ( crate ) fn parse_csi_modifier_key_code ( buffer : & [ u8 ] ) -> Result < Option < InternalEvent > > {
267
289
assert ! ( buffer. starts_with( & [ b'\x1B' , b'[' ] ) ) ; // ESC [
290
+ //
291
+ let s = std:: str:: from_utf8 ( & buffer[ 2 ..buffer. len ( ) - 1 ] )
292
+ . map_err ( |_| could_not_parse_event_error ( ) ) ?;
293
+ let mut split = s. split ( ';' ) ;
268
294
269
- let modifier_mask = buffer[ buffer. len ( ) - 2 ] ;
270
- let key = buffer[ buffer. len ( ) - 1 ] ;
295
+ split. next ( ) ;
271
296
272
- let modifiers = parse_modifiers ( modifier_mask) ;
297
+ let ( modifiers, kind) =
298
+ if let Ok ( ( modifier_mask, kind_code) ) = modifier_and_kind_parsed ( & mut split) {
299
+ (
300
+ parse_modifiers ( modifier_mask) ,
301
+ parse_key_event_kind ( kind_code) ,
302
+ )
303
+ } else if buffer. len ( ) > 3 {
304
+ (
305
+ parse_modifiers (
306
+ ( buffer[ buffer. len ( ) - 2 ] as char )
307
+ . to_digit ( 10 )
308
+ . ok_or_else ( could_not_parse_event_error) ? as u8 ,
309
+ ) ,
310
+ KeyEventKind :: Press ,
311
+ )
312
+ } else {
313
+ ( KeyModifiers :: NONE , KeyEventKind :: Press )
314
+ } ;
315
+ let key = buffer[ buffer. len ( ) - 1 ] ;
273
316
274
317
let keycode = match key {
275
318
b'A' => KeyCode :: Up ,
@@ -285,7 +328,7 @@ pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result<Option<Intern
285
328
_ => return Err ( could_not_parse_event_error ( ) ) ,
286
329
} ;
287
330
288
- let input_event = Event :: Key ( KeyEvent :: new ( keycode, modifiers) ) ;
331
+ let input_event = Event :: Key ( KeyEvent :: new_with_kind ( keycode, modifiers, kind ) ) ;
289
332
290
333
Ok ( Some ( InternalEvent :: Event ( input_event) ) )
291
334
}
@@ -404,17 +447,18 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result<Option<Inter
404
447
// codepoint: ASCII Dec value
405
448
let codepoint = next_parsed :: < u32 > ( & mut split) ?;
406
449
407
- let ( mut modifiers, kind) =
450
+ let ( mut modifiers, kind, state_from_modifiers ) =
408
451
if let Ok ( ( modifier_mask, kind_code) ) = modifier_and_kind_parsed ( & mut split) {
409
452
(
410
453
parse_modifiers ( modifier_mask) ,
411
454
parse_key_event_kind ( kind_code) ,
455
+ parse_modifiers_to_state ( modifier_mask) ,
412
456
)
413
457
} else {
414
- ( KeyModifiers :: NONE , KeyEventKind :: Press )
458
+ ( KeyModifiers :: NONE , KeyEventKind :: Press , KeyEventState :: NONE )
415
459
} ;
416
460
417
- let ( keycode, state ) = {
461
+ let ( keycode, state_from_keycode ) = {
418
462
if let Some ( ( special_key_code, state) ) = translate_functional_key_code ( codepoint) {
419
463
( special_key_code, state)
420
464
} else if let Some ( c) = char:: from_u32 ( codepoint) {
@@ -455,12 +499,24 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result<Option<Inter
455
499
ModifierKeyCode :: LeftShift | ModifierKeyCode :: RightShift => {
456
500
modifiers. set ( KeyModifiers :: SHIFT , true )
457
501
}
502
+ ModifierKeyCode :: LeftSuper | ModifierKeyCode :: RightSuper => {
503
+ modifiers. set ( KeyModifiers :: SUPER , true )
504
+ }
505
+ ModifierKeyCode :: LeftHyper | ModifierKeyCode :: RightHyper => {
506
+ modifiers. set ( KeyModifiers :: HYPER , true )
507
+ }
508
+ ModifierKeyCode :: LeftMeta | ModifierKeyCode :: RightMeta => {
509
+ modifiers. set ( KeyModifiers :: META , true )
510
+ }
458
511
_ => { }
459
512
}
460
513
}
461
514
462
515
let input_event = Event :: Key ( KeyEvent :: new_with_kind_and_state (
463
- keycode, modifiers, kind, state,
516
+ keycode,
517
+ modifiers,
518
+ kind,
519
+ state_from_keycode | state_from_modifiers,
464
520
) ) ;
465
521
466
522
Ok ( Some ( InternalEvent :: Event ( input_event) ) )
@@ -1169,5 +1225,97 @@ mod tests {
1169
1225
KeyEventKind :: Release ,
1170
1226
) ) ) ) ,
1171
1227
) ;
1228
+ assert_eq ! (
1229
+ parse_csi_u_encoded_key_code( b"\x1B [57450u" ) . unwrap( ) ,
1230
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1231
+ KeyCode :: Modifier ( ModifierKeyCode :: RightSuper ) ,
1232
+ KeyModifiers :: SUPER ,
1233
+ ) ) ) ) ,
1234
+ ) ;
1235
+ assert_eq ! (
1236
+ parse_csi_u_encoded_key_code( b"\x1B [57451u" ) . unwrap( ) ,
1237
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1238
+ KeyCode :: Modifier ( ModifierKeyCode :: RightHyper ) ,
1239
+ KeyModifiers :: HYPER ,
1240
+ ) ) ) ) ,
1241
+ ) ;
1242
+ assert_eq ! (
1243
+ parse_csi_u_encoded_key_code( b"\x1B [57452u" ) . unwrap( ) ,
1244
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1245
+ KeyCode :: Modifier ( ModifierKeyCode :: RightMeta ) ,
1246
+ KeyModifiers :: META ,
1247
+ ) ) ) ) ,
1248
+ ) ;
1249
+ }
1250
+
1251
+ #[ test]
1252
+ fn test_parse_csi_u_encoded_key_code_with_extra_modifiers ( ) {
1253
+ assert_eq ! (
1254
+ parse_csi_u_encoded_key_code( b"\x1B [97;9u" ) . unwrap( ) ,
1255
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1256
+ KeyCode :: Char ( 'a' ) ,
1257
+ KeyModifiers :: SUPER
1258
+ ) ) ) ) ,
1259
+ ) ;
1260
+ assert_eq ! (
1261
+ parse_csi_u_encoded_key_code( b"\x1B [97;17u" ) . unwrap( ) ,
1262
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1263
+ KeyCode :: Char ( 'a' ) ,
1264
+ KeyModifiers :: HYPER ,
1265
+ ) ) ) ) ,
1266
+ ) ;
1267
+ assert_eq ! (
1268
+ parse_csi_u_encoded_key_code( b"\x1B [97;33u" ) . unwrap( ) ,
1269
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new(
1270
+ KeyCode :: Char ( 'a' ) ,
1271
+ KeyModifiers :: META ,
1272
+ ) ) ) ) ,
1273
+ ) ;
1274
+ }
1275
+
1276
+ #[ test]
1277
+ fn test_parse_csi_u_encoded_key_code_with_extra_state ( ) {
1278
+ assert_eq ! (
1279
+ parse_csi_u_encoded_key_code( b"\x1B [97;65u" ) . unwrap( ) ,
1280
+ Some ( InternalEvent :: Event ( Event :: Key (
1281
+ KeyEvent :: new_with_kind_and_state(
1282
+ KeyCode :: Char ( 'a' ) ,
1283
+ KeyModifiers :: empty( ) ,
1284
+ KeyEventKind :: Press ,
1285
+ KeyEventState :: CAPS_LOCK ,
1286
+ )
1287
+ ) ) ) ,
1288
+ ) ;
1289
+ assert_eq ! (
1290
+ parse_csi_u_encoded_key_code( b"\x1B [49;129u" ) . unwrap( ) ,
1291
+ Some ( InternalEvent :: Event ( Event :: Key (
1292
+ KeyEvent :: new_with_kind_and_state(
1293
+ KeyCode :: Char ( '1' ) ,
1294
+ KeyModifiers :: empty( ) ,
1295
+ KeyEventKind :: Press ,
1296
+ KeyEventState :: NUM_LOCK ,
1297
+ )
1298
+ ) ) ) ,
1299
+ ) ;
1300
+ }
1301
+
1302
+ #[ test]
1303
+ fn test_parse_csi_special_key_code_with_types ( ) {
1304
+ assert_eq ! (
1305
+ parse_event( b"\x1B [;1:3B" , false ) . unwrap( ) ,
1306
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new_with_kind(
1307
+ KeyCode :: Down ,
1308
+ KeyModifiers :: empty( ) ,
1309
+ KeyEventKind :: Release ,
1310
+ ) ) ) ) ,
1311
+ ) ;
1312
+ assert_eq ! (
1313
+ parse_event( b"\x1B [1;1:3B" , false ) . unwrap( ) ,
1314
+ Some ( InternalEvent :: Event ( Event :: Key ( KeyEvent :: new_with_kind(
1315
+ KeyCode :: Down ,
1316
+ KeyModifiers :: empty( ) ,
1317
+ KeyEventKind :: Release ,
1318
+ ) ) ) ) ,
1319
+ ) ;
1172
1320
}
1173
1321
}
0 commit comments