1use crate::mode::KeyMod;
11#[doc(inline)]
12pub use crate::{__alt__ as alt, __ctrl__ as ctrl, __event__ as event, __shift__ as shift};
13
14#[macro_export]
73#[doc(hidden)]
74macro_rules! __event__ {
75 (@code $($tokens:tt)*) => {
76 $crate::__modified__!(@code $($tokens)*)
77 };
78 (@modif [$($mods:tt),*] $($tokens:tt)*) => {
79 $crate::__modified__!(@modif [$($mods),*] $($tokens)*)
80 };
81 (@bindings [$($mods:tt),*] $($tokens:tt)*) => {
82 $crate::__modified__!(@bindings [$($mods),*] $($tokens)*)
83 };
84 ($($tokens:tt)*) => {
85 $crate::__modified__!([] $($tokens)*)
86 };
87}
88
89#[macro_export]
153#[doc(hidden)]
154macro_rules! __alt__ {
155 (@code $($tokens:tt)*) => {
156 $crate::__modified__!(@code $($tokens)*)
157 };
158 (@modif [$($mods:tt),*] $($tokens:tt)*) => {
159 $crate::__modified__!(@modif [ALT $(, $mods)*] $($tokens)*)
160 };
161 (@bindings [$($mods:tt),*] $($tokens:tt)*) => {
162 $crate::__modified__!(@bindings [ALT $(, $mods)*] $($tokens)*)
163 };
164 ($($tokens:tt)*) => {
165 $crate::__modified__!([ALT] $($tokens)*)
166 };
167}
168
169#[macro_export]
233#[doc(hidden)]
234macro_rules! __ctrl__ {
235 (@code $($tokens:tt)*) => {
236 $crate::__modified__!(@code $($tokens)*)
237 };
238 (@modif [$($mods:tt),*] $($tokens:tt)*) => {
239 $crate::__modified__!(@modif [CONTROL $(,$mods)*] $($tokens)*)
240 };
241 (@bindings [$($mods:tt),*] $($tokens:tt)*) => {
242 $crate::__modified__!(@bindings [CONTROL $(,$mods)*] $($tokens)*)
243 };
244 ($($tokens:tt)*) => {
245 $crate::__modified__!([CONTROL] $($tokens)*)
246 };
247}
248
249#[macro_export]
328#[doc(hidden)]
329macro_rules! __shift__ {
330 (@code $($tokens:tt)*) => {
331 $crate::__modified__!(@code $($tokens)*)
332 };
333 (@modif [$($mods:tt),*] $($tokens:tt)*) => {
334 $crate::__modified__!(@modif [SHIFT $(, $mods)*] $($tokens)*)
335 };
336 (@bindings [$($mods:tt),*] $($tokens:tt)*) => {
337 $crate::__modified__!(@bindings [SHIFT $(, $mods)*] $($tokens)*)
338 };
339 ($($tokens:tt)*) => {
340 $crate::__modified__!([SHIFT] $($tokens)*)
341 };
342}
343
344#[macro_export]
346#[doc(hidden)]
347macro_rules! __modified__ {
348 ([$($mods:ident),*] $($chars:literal)|*) => {
349 $crate::mode::KeyEvent {
350 code: $crate::mode::KeyCode::Char($($chars)|*),
351 modifiers: $crate::__join_modifiers__![$($mods),*],
352 kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
353 }
354 };
355 ([$($mods:ident),*] $char:ident @ $chars:literal) => {
357 $crate::mode::KeyEvent {
358 code: $crate::mode::KeyCode::Char($char @ $chars),
359 modifiers: $crate::__join_modifiers__![$($mods),*],
360 kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
361 }
362 };
363 ([$($mods:ident),*] $char:ident @ ($($chars:literal)|*)) => {
364 $crate::mode::KeyEvent {
365 code: $crate::mode::KeyCode::Char($char @ ($($chars)|*)),
366 modifiers: $crate::__join_modifiers__![$($mods),*],
367 kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
368 }
369 };
370 ([$($mods:ident),*] $modif:ident$excl:tt($($tokens:tt)*)) => {
373 $crate::mode::KeyEvent {
374 code: $modif$excl(@code $($tokens)*),
375 modifiers: $modif$excl(@modif [$($mods),*] $($tokens)*),
376 kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
377 }
378 };
379 ([$($mods:ident),*] $code:pat) => {
380 $crate::mode::KeyEvent {
381 code: $code,
382 modifiers: $crate::__join_modifiers__![$($mods),*],
383 kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
384 }
385 };
386
387 (@code $modif:ident$excl:tt($($tokens:tt)*)) => {
388 $modif$excl(@code $($tokens)*)
389 };
390 (@code $($chars:literal)|*) => {
391 $crate::mode::KeyCode::Char($($chars)|*)
392 };
393 (@code $char:ident @ $chars:literal) => {
394 $crate::mode::KeyCode::Char($char @ $chars)
395 };
396 (@code $char:ident @ ($($chars:literal)|*)) => {
397 $crate::mode::KeyCode::Char($char @ ($($chars)|*))
398 };
399 (@code $code:pat) => {
400 $code
401 };
402
403 (@modif [$($mods:ident),*] $modif:ident$excl:tt($($tokens:tt)*)) => {
404 $modif$excl(@modif [$($mods),*] $($tokens)*)
405 };
406 (@modif [$($mods:ident),*] $($other:tt)*) => {
407 $crate::__join_modifiers__![$($mods),*]
408 };
409
410 (@bindings [$($mods:ident),*] $list:ident, $modif:ident$excl:tt($($tokens:tt)*)) => {
411 $modif$excl(@bindings [$($mods),*] $list, $($tokens)*)
412 };
413 (@bindings [$($mods:ident),*] $list:ident, $char:literal) => {{
414 $list.push($crate::mode::Binding::new(
415 $crate::mode::KeyCode::Char($char),
416 $crate::__join_modifiers__![$($mods),*],
417 ))
418 }};
419 (@bindings [$($mods:ident),*] $list:ident, $($chars:literal)|*) => {{
420 let modif = $crate::__join_modifiers__![$($mods),*];
421 $list.extend([$(
422 $crate::mode::Binding::new($crate::mode::KeyCode::Char($chars), modif)
423 ),*])
424 }};
425 (@bindings [$($mods:ident),*] $list:ident, $($tokens:tt)*) => {{
426 let modif = $crate::__join_modifiers__![$($mods),*];
427 $crate::__modified__!(@fill_bindings $list, modif, $($tokens)*);
428 }};
429
430 (@fill_bindings $list:ident, $modif:expr,) => {};
431 (@fill_bindings $list:ident, $modif:expr, $($variant:ident)::+ $(| $($rest:tt)*)?) => {
432 $list.push($crate::mode::Binding::new($($variant)::+, $modif));
433 $crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
434 };
435 (@fill_bindings
436 $list:ident,
437 $modif:expr,
438 $($variant:ident)::+(..)
439 $(| $($rest:tt)*)?
440 ) => {
441 let _unused = |code| matches!(code, $($variant)::+(..));
443 $crate::__modified__!(@two_dots_entry $list, $modif, $($variant)::+);
444 $crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
445 };
446 (@fill_bindings
447 $list:ident,
448 $modif:expr,
449 $($variant:ident)::+($($patterns:tt)*)
450 $(| $($rest:tt)*)?
451 ) => {
452 let _unused = |code| matches!(code, $($variant)::*($($patterns)*));
454 $crate::__modified__!(@binding_entry $list, $modif, $($patterns)*);
455 $crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
456 };
457 (@fill_bindings $list:ident, $modif:expr, _) => {
458 let mut binding = $crate::mode::Binding::anything();
459 binding.modif = Some($modif);
460 $list.push(binding);
461 };
462 (@fill_bindings $list:ident, $modif:expr, $($nonsense:tt)*) => {
463 let _unused = |code: $crate::mode::KeyCode| matches!(code, $($nonsense)*);
465 compile_error!("Pattern may be valid, but can't create known list of bindings");
466 };
467
468 (@binding_entry $list:ident, $modif:expr,) => {};
469 (@binding_entry $list:ident, $modif:expr, $s:literal..$e:literal $(| $($rest:tt)*)?) => {
470 $list.push($crate::mode::Binding::from(($s..$e, $modif)));
471 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
472 };
473 (@binding_entry $list:ident, $modif:expr, $s:literal..=$e:literal $(| $($rest:tt)*)?) => {
474 $list.push($crate::mode::Binding::from(($s..=$e, $modif)));
475 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
476 };
477 (@binding_entry $list:ident, $modif:expr, ..$e:literal $(| $($rest:tt)*)?) => {
478 $list.push($crate::mode::Binding::from((..$e, $modif)));
479 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
480 };
481 (@binding_entry $list:ident, $modif:expr, ..=$e:literal $(| $($rest:tt)*)?) => {
482 $list.push($crate::mode::Binding::from((..=$e, $modif)));
483 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
484 };
485 (@binding_entry $list:ident, $modif:expr, $s:literal.. $(| $($rest:tt)*)?) => {
486 $list.push($crate::mode::Binding::from(($s.., $modif)));
487 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
488 };
489 (@binding_entry $list:ident, $modif:expr, $elem:literal $(| $($rest:tt)*)?) => {
490 $list.push($crate::mode::Binding::from(($elem, $modif)));
491 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
492 };
493 (@binding_entry $list:ident, $modif:expr, $elem:literal $(| $($rest:tt)*)?) => {
494 $list.push($crate::mode::Binding::from(($elem, $modif)));
495 $crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
496 };
497
498 (@two_dots_entry $list:ident, $modif:expr, $path:ident $(::$rest:ident)+) => {{
499 $crate::__modified__!(@two_dots_entry $list, $modif, $($rest)::+);
500 }};
501 (@two_dots_entry $list:ident, $modif:expr, Char) => {{
502 $list.push($crate::mode::Binding::CharRange(
503 ::std::ops::Bound::Unbounded,
504 ::std::ops::Bound::Unbounded,
505 $modif
506 ))
507 }};
508 (@two_dots_entry $list:ident, $modif:expr, F) => {{
509 $list.push($crate::mode::Binding::FnRange(
510 ::std::ops::Bound::Unbounded,
511 ::std::ops::Bound::Unbounded,
512 $modif
513 ))
514 }};
515 (@two_dots_entry $list:ident, $modif:expr, Media) => {{
516 $list.push($crate::mode::Binding::AnyMedia($modif))
517 }};
518 (@two_dots_entry $list:ident, $modif:expr, Modifier) => {{
519 $list.push($crate::mode::Binding::AnyModifier($modif))
520 }}
521}
522
523#[macro_export]
526#[doc(hidden)]
527macro_rules! __join_modifiers__ {
528 [] => { $crate::mode::KeyMod::NONE };
529 [ALT] => { $crate::mode::KeyMod::ALT };
530 [CONTROL] => { $crate::mode::KeyMod::CONTROL };
531 [SHIFT] => { $crate::mode::KeyMod::SHIFT };
532 [ALT, CONTROL] => { $crate::mode::ALT_CONTROL };
533 [CONTROL, ALT] => { $crate::mode::ALT_CONTROL };
534 [ALT, SHIFT] => { $crate::mode::ALT_SHIFT };
535 [SHIFT, ALT] => { $crate::mode::ALT_SHIFT };
536 [CONTROL, SHIFT] => { $crate::mode::CONTROL_SHIFT };
537 [SHIFT, CONTROL] => { $crate::mode::CONTROL_SHIFT };
538 [ALT, CONTROL, SHIFT] => { $crate::mode::ALT_CONTROL_SHIFT };
539 [ALT, SHIFT, CONTROL] => { $crate::mode::ALT_CONTROL_SHIFT };
540 [CONTROL, ALT, SHIFT] => { $crate::mode::ALT_CONTROL_SHIFT };
541 [CONTROL, SHIFT, ALT] => { $crate::mode::ALT_CONTROL_SHIFT };
542 [SHIFT, ALT, CONTROL] => { $crate::mode::ALT_CONTROL_SHIFT };
543 [SHIFT, CONTROL, ALT] => { $crate::mode::ALT_CONTROL_SHIFT };
544 [$($other:tt)+] => {
545 compile_error!("Don't nest identical modifier macros while forming patterns")
546 }
547}
548
549#[doc(hidden)]
551pub const ALT_CONTROL: KeyMod = KeyMod::ALT.union(KeyMod::CONTROL);
552
553#[doc(hidden)]
555pub const ALT_SHIFT: KeyMod = KeyMod::ALT.union(KeyMod::SHIFT);
556
557#[doc(hidden)]
559pub const CONTROL_SHIFT: KeyMod = KeyMod::CONTROL.union(KeyMod::SHIFT);
560
561#[doc(hidden)]
563pub const ALT_CONTROL_SHIFT: KeyMod = KeyMod::ALT.union(KeyMod::CONTROL).union(KeyMod::SHIFT);