use crate::mode::KeyMod;
#[doc(inline)]
pub use crate::{__alt__ as alt, __ctrl__ as ctrl, __event__ as event, __shift__ as shift};
#[macro_export]
#[doc(hidden)]
macro_rules! __event__ {
(@code $($tokens:tt)*) => {
$crate::__modified__!(@code $($tokens)*)
};
(@modif [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@modif [$($mods),*] $($tokens)*)
};
(@bindings [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@bindings [$($mods),*] $($tokens)*)
};
($($tokens:tt)*) => {
$crate::__modified__!([] $($tokens)*)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __alt__ {
(@code $($tokens:tt)*) => {
$crate::__modified__!(@code $($tokens)*)
};
(@modif [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@modif [ALT $(, $mods)*] $($tokens)*)
};
(@bindings [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@bindings [ALT $(, $mods)*] $($tokens)*)
};
($($tokens:tt)*) => {
$crate::__modified__!([ALT] $($tokens)*)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __ctrl__ {
(@code $($tokens:tt)*) => {
$crate::__modified__!(@code $($tokens)*)
};
(@modif [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@modif [CONTROL $(,$mods)*] $($tokens)*)
};
(@bindings [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@bindings [CONTROL $(,$mods)*] $($tokens)*)
};
($($tokens:tt)*) => {
$crate::__modified__!([CONTROL] $($tokens)*)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __shift__ {
(@code $($tokens:tt)*) => {
$crate::__modified__!(@code $($tokens)*)
};
(@modif [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@modif [SHIFT $(, $mods)*] $($tokens)*)
};
(@bindings [$($mods:tt),*] $($tokens:tt)*) => {
$crate::__modified__!(@bindings [SHIFT $(, $mods)*] $($tokens)*)
};
($($tokens:tt)*) => {
$crate::__modified__!([SHIFT] $($tokens)*)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __modified__ {
([$($mods:ident),*] $($chars:literal)|*) => {
$crate::mode::KeyEvent {
code: $crate::mode::KeyCode::Char($($chars)|*),
modifiers: $crate::__join_modifiers__![$($mods),*],
kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
}
};
([$($mods:ident),*] $char:ident @ $chars:literal) => {
$crate::mode::KeyEvent {
code: $crate::mode::KeyCode::Char($char @ $chars),
modifiers: $crate::__join_modifiers__![$($mods),*],
kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
}
};
([$($mods:ident),*] $char:ident @ ($($chars:literal)|*)) => {
$crate::mode::KeyEvent {
code: $crate::mode::KeyCode::Char($char @ ($($chars)|*)),
modifiers: $crate::__join_modifiers__![$($mods),*],
kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
}
};
([$($mods:ident),*] $modif:ident$excl:tt($($tokens:tt)*)) => {
$crate::mode::KeyEvent {
code: $modif$excl(@code $($tokens)*),
modifiers: $modif$excl(@modif [$($mods),*] $($tokens)*),
kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
}
};
([$($mods:ident),*] $code:pat) => {
$crate::mode::KeyEvent {
code: $code,
modifiers: $crate::__join_modifiers__![$($mods),*],
kind: $crate::mode::KeyEventKind::Press | $crate::mode::KeyEventKind::Repeat, ..
}
};
(@code $modif:ident$excl:tt($($tokens:tt)*)) => {
$modif$excl(@code $($tokens)*)
};
(@code $($chars:literal)|*) => {
$crate::mode::KeyCode::Char($($chars)|*)
};
(@code $char:ident @ $chars:literal) => {
$crate::mode::KeyCode::Char($char @ $chars)
};
(@code $char:ident @ ($($chars:literal)|*)) => {
$crate::mode::KeyCode::Char($char @ ($($chars)|*))
};
(@code $code:pat) => {
$code
};
(@modif [$($mods:ident),*] $modif:ident$excl:tt($($tokens:tt)*)) => {
$modif$excl(@modif [$($mods),*] $($tokens)*)
};
(@modif [$($mods:ident),*] $($other:tt)*) => {
$crate::__join_modifiers__![$($mods),*]
};
(@bindings [$($mods:ident),*] $list:ident, $modif:ident$excl:tt($($tokens:tt)*)) => {
$modif$excl(@bindings [$($mods),*] $list, $($tokens)*)
};
(@bindings [$($mods:ident),*] $list:ident, $char:literal) => {{
$list.push($crate::mode::Binding::new(
$crate::mode::KeyCode::Char($char),
$crate::__join_modifiers__![$($mods),*],
))
}};
(@bindings [$($mods:ident),*] $list:ident, $($chars:literal)|*) => {{
let modif = $crate::__join_modifiers__![$($mods),*];
$list.extend([$(
$crate::mode::Binding::new($crate::mode::KeyCode::Char($chars), modif)
),*])
}};
(@bindings [$($mods:ident),*] $list:ident, $($tokens:tt)*) => {{
let modif = $crate::__join_modifiers__![$($mods),*];
$crate::__modified__!(@fill_bindings $list, modif, $($tokens)*);
}};
(@fill_bindings $list:ident, $modif:expr,) => {};
(@fill_bindings $list:ident, $modif:expr, $($variant:ident)::+ $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::new($($variant)::+, $modif));
$crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
};
(@fill_bindings
$list:ident,
$modif:expr,
$($variant:ident)::+(..)
$(| $($rest:tt)*)?
) => {
let _unused = |code| matches!(code, $($variant)::+(..));
$crate::__modified__!(@two_dots_entry $list, $modif, $($variant)::+);
$crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
};
(@fill_bindings
$list:ident,
$modif:expr,
$($variant:ident)::+($($patterns:tt)*)
$(| $($rest:tt)*)?
) => {
let _unused = |code| matches!(code, $($variant)::*($($patterns)*));
$crate::__modified__!(@binding_entry $list, $modif, $($patterns)*);
$crate::__modified__!(@fill_bindings $list, $modif, $($($rest)*)?);
};
(@fill_bindings $list:ident, $modif:expr, _) => {
let mut binding = $crate::mode::Binding::anything();
binding.modif = Some($modif);
$list.push(binding);
};
(@fill_bindings $list:ident, $modif:expr, $($nonsense:tt)*) => {
let _unused = |code: $crate::mode::KeyCode| matches!(code, $($nonsense)*);
compile_error!("Pattern may be valid, but can't create known list of bindings");
};
(@binding_entry $list:ident, $modif:expr,) => {};
(@binding_entry $list:ident, $modif:expr, $s:literal..$e:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from(($s..$e, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, $s:literal..=$e:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from(($s..=$e, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, ..$e:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from((..$e, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, ..=$e:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from((..=$e, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, $s:literal.. $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from(($s.., $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, $elem:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from(($elem, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@binding_entry $list:ident, $modif:expr, $elem:literal $(| $($rest:tt)*)?) => {
$list.push($crate::mode::Binding::from(($elem, $modif)));
$crate::__modified__!(@binding_entry $list, $modif, $($($rest)*)?);
};
(@two_dots_entry $list:ident, $modif:expr, $path:ident $(::$rest:ident)+) => {{
$crate::__modified__!(@two_dots_entry $list, $modif, $($rest)::+);
}};
(@two_dots_entry $list:ident, $modif:expr, Char) => {{
$list.push($crate::mode::Binding::CharRange(
::std::ops::Bound::Unbounded,
::std::ops::Bound::Unbounded,
$modif
))
}};
(@two_dots_entry $list:ident, $modif:expr, F) => {{
$list.push($crate::mode::Binding::FnRange(
::std::ops::Bound::Unbounded,
::std::ops::Bound::Unbounded,
$modif
))
}};
(@two_dots_entry $list:ident, $modif:expr, Media) => {{
$list.push($crate::mode::Binding::AnyMedia($modif))
}};
(@two_dots_entry $list:ident, $modif:expr, Modifier) => {{
$list.push($crate::mode::Binding::AnyModifier($modif))
}}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __join_modifiers__ {
[] => { $crate::mode::KeyMod::NONE };
[ALT] => { $crate::mode::KeyMod::ALT };
[CONTROL] => { $crate::mode::KeyMod::CONTROL };
[SHIFT] => { $crate::mode::KeyMod::SHIFT };
[ALT, CONTROL] => { $crate::mode::ALT_CONTROL };
[CONTROL, ALT] => { $crate::mode::ALT_CONTROL };
[ALT, SHIFT] => { $crate::mode::ALT_SHIFT };
[SHIFT, ALT] => { $crate::mode::ALT_SHIFT };
[CONTROL, SHIFT] => { $crate::mode::CONTROL_SHIFT };
[SHIFT, CONTROL] => { $crate::mode::CONTROL_SHIFT };
[ALT, CONTROL, SHIFT] => { $crate::mode::ALT_CONTROL_SHIFT };
[ALT, SHIFT, CONTROL] => { $crate::mode::ALT_CONTROL_SHIFT };
[CONTROL, ALT, SHIFT] => { $crate::mode::ALT_CONTROL_SHIFT };
[CONTROL, SHIFT, ALT] => { $crate::mode::ALT_CONTROL_SHIFT };
[SHIFT, ALT, CONTROL] => { $crate::mode::ALT_CONTROL_SHIFT };
[SHIFT, CONTROL, ALT] => { $crate::mode::ALT_CONTROL_SHIFT };
[$($other:tt)+] => {
compile_error!("Don't nest identical modifier macros while forming patterns")
}
}
#[doc(hidden)]
pub const ALT_CONTROL: KeyMod = KeyMod::ALT.union(KeyMod::CONTROL);
#[doc(hidden)]
pub const ALT_SHIFT: KeyMod = KeyMod::ALT.union(KeyMod::SHIFT);
#[doc(hidden)]
pub const CONTROL_SHIFT: KeyMod = KeyMod::CONTROL.union(KeyMod::SHIFT);
#[doc(hidden)]
pub const ALT_CONTROL_SHIFT: KeyMod = KeyMod::ALT.union(KeyMod::CONTROL).union(KeyMod::SHIFT);