parent
1c05b3bb0c
commit
3c3239b1cb
|
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- On macOS, Alacritty will now fallback to Menlo if a font specified in the config cannot be loaded
|
- On macOS, Alacritty will now fallback to Menlo if a font specified in the config cannot be loaded
|
||||||
- Debug ref tests are now written to disk regardless of shutdown method
|
- Debug ref tests are now written to disk regardless of shutdown method
|
||||||
- Cursor color setting with escape sequence
|
- Cursor color setting with escape sequence
|
||||||
|
- Override default bindings with subset terminal mode match
|
||||||
|
|
||||||
## 0.3.3
|
## 0.3.3
|
||||||
|
|
||||||
|
|
|
@ -152,17 +152,17 @@ impl<T: Eq> Binding<T> {
|
||||||
// the most likely item to fail so prioritizing it here allows more
|
// the most likely item to fail so prioritizing it here allows more
|
||||||
// checks to be short circuited.
|
// checks to be short circuited.
|
||||||
self.trigger == *input
|
self.trigger == *input
|
||||||
&& self.mode_matches(mode)
|
&& mode.contains(self.mode)
|
||||||
&& self.not_mode_matches(mode)
|
&& !mode.intersects(self.notmode)
|
||||||
&& self.mods_match(mods, relaxed)
|
&& self.mods_match(mods, relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn triggers_match(&self, binding: &Binding<T>) -> bool {
|
pub fn triggers_match(&self, binding: &Binding<T>) -> bool {
|
||||||
self.trigger == binding.trigger
|
self.trigger == binding.trigger
|
||||||
&& self.mode == binding.mode
|
|
||||||
&& self.notmode == binding.notmode
|
|
||||||
&& self.mods == binding.mods
|
&& self.mods == binding.mods
|
||||||
|
&& (self.mode.contains(binding.mode) || binding.mode.contains(self.mode))
|
||||||
|
&& (self.notmode.contains(binding.notmode) || binding.notmode.contains(self.notmode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,16 +173,6 @@ impl<T> Binding<T> {
|
||||||
self.action.execute(ctx, mouse_mode)
|
self.action.execute(ctx, mouse_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mode_matches(&self, mode: TermMode) -> bool {
|
|
||||||
self.mode.is_empty() || mode.intersects(self.mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn not_mode_matches(&self, mode: TermMode) -> bool {
|
|
||||||
self.notmode.is_empty() || !mode.intersects(self.notmode)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that two mods descriptions for equivalence
|
/// Check that two mods descriptions for equivalence
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mods_match(&self, mods: ModifiersState, relaxed: bool) -> bool {
|
fn mods_match(&self, mods: ModifiersState, relaxed: bool) -> bool {
|
||||||
|
@ -996,6 +986,130 @@ mod tests {
|
||||||
|
|
||||||
const KEY: VirtualKeyCode = VirtualKeyCode::Key0;
|
const KEY: VirtualKeyCode = VirtualKeyCode::Key0;
|
||||||
|
|
||||||
|
type MockBinding = Binding<usize>;
|
||||||
|
|
||||||
|
impl Default for MockBinding {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
mods: Default::default(),
|
||||||
|
action: Default::default(),
|
||||||
|
mode: TermMode::empty(),
|
||||||
|
notmode: TermMode::empty(),
|
||||||
|
trigger: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_matches_itself() {
|
||||||
|
let binding = MockBinding::default();
|
||||||
|
let identical_binding = MockBinding::default();
|
||||||
|
|
||||||
|
assert!(binding.triggers_match(&identical_binding));
|
||||||
|
assert!(identical_binding.triggers_match(&binding));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_matches_different_action() {
|
||||||
|
let binding = MockBinding::default();
|
||||||
|
let mut different_action = MockBinding::default();
|
||||||
|
different_action.action = Action::ClearHistory;
|
||||||
|
|
||||||
|
assert!(binding.triggers_match(&different_action));
|
||||||
|
assert!(different_action.triggers_match(&binding));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn subset_mode_binding_matches_superset() {
|
||||||
|
let mut superset_mode = MockBinding::default();
|
||||||
|
superset_mode.mode = TermMode::ALT_SCREEN | TermMode::INSERT | TermMode::ORIGIN;
|
||||||
|
let mut subset_mode = MockBinding::default();
|
||||||
|
subset_mode.mode = TermMode::ALT_SCREEN | TermMode::ORIGIN;
|
||||||
|
|
||||||
|
assert!(superset_mode.triggers_match(&subset_mode));
|
||||||
|
assert!(subset_mode.triggers_match(&superset_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn subset_notmode_binding_matches_superset() {
|
||||||
|
let mut superset_notmode = MockBinding::default();
|
||||||
|
superset_notmode.notmode = TermMode::ALT_SCREEN | TermMode::INSERT | TermMode::ORIGIN;
|
||||||
|
let mut subset_notmode = MockBinding::default();
|
||||||
|
subset_notmode.notmode = TermMode::ALT_SCREEN | TermMode::ORIGIN;
|
||||||
|
|
||||||
|
assert!(superset_notmode.triggers_match(&subset_notmode));
|
||||||
|
assert!(subset_notmode.triggers_match(&superset_notmode));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mods_binding_requires_strict_match() {
|
||||||
|
let mut superset_mods = MockBinding::default();
|
||||||
|
superset_mods.mods = ModifiersState { alt: true, logo: true, ctrl: true, shift: true };
|
||||||
|
let mut subset_mods = MockBinding::default();
|
||||||
|
subset_mods.mods = ModifiersState { alt: true, logo: false, ctrl: false, shift: false };
|
||||||
|
|
||||||
|
assert!(!superset_mods.triggers_match(&subset_mods));
|
||||||
|
assert!(!subset_mods.triggers_match(&superset_mods));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binding_trigger_input() {
|
||||||
|
let mut binding = MockBinding::default();
|
||||||
|
binding.trigger = 13;
|
||||||
|
|
||||||
|
let mods = binding.mods;
|
||||||
|
let mode = binding.mode;
|
||||||
|
|
||||||
|
assert!(binding.is_triggered_by(mode, mods, &13, true));
|
||||||
|
assert!(!binding.is_triggered_by(mode, mods, &32, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_trigger_mods() {
|
||||||
|
let mut binding = MockBinding::default();
|
||||||
|
binding.mods = ModifiersState { alt: true, logo: true, ctrl: false, shift: false };
|
||||||
|
|
||||||
|
let superset_mods = ModifiersState { alt: true, logo: true, ctrl: true, shift: true };
|
||||||
|
let subset_mods = ModifiersState { alt: false, logo: false, ctrl: false, shift: false };
|
||||||
|
|
||||||
|
let t = binding.trigger;
|
||||||
|
let mode = binding.mode;
|
||||||
|
|
||||||
|
assert!(binding.is_triggered_by(mode, binding.mods, &t, true));
|
||||||
|
assert!(binding.is_triggered_by(mode, binding.mods, &t, false));
|
||||||
|
|
||||||
|
assert!(binding.is_triggered_by(mode, superset_mods, &t, true));
|
||||||
|
assert!(!binding.is_triggered_by(mode, superset_mods, &t, false));
|
||||||
|
|
||||||
|
assert!(!binding.is_triggered_by(mode, subset_mods, &t, true));
|
||||||
|
assert!(!binding.is_triggered_by(mode, subset_mods, &t, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_trigger_modes() {
|
||||||
|
let mut binding = MockBinding::default();
|
||||||
|
binding.mode = TermMode::ALT_SCREEN;
|
||||||
|
|
||||||
|
let t = binding.trigger;
|
||||||
|
let mods = binding.mods;
|
||||||
|
|
||||||
|
assert!(!binding.is_triggered_by(TermMode::INSERT, mods, &t, true));
|
||||||
|
assert!(binding.is_triggered_by(TermMode::ALT_SCREEN, mods, &t, true));
|
||||||
|
assert!(binding.is_triggered_by(TermMode::ALT_SCREEN | TermMode::INSERT, mods, &t, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_trigger_notmodes() {
|
||||||
|
let mut binding = MockBinding::default();
|
||||||
|
binding.notmode = TermMode::ALT_SCREEN;
|
||||||
|
|
||||||
|
let t = binding.trigger;
|
||||||
|
let mods = binding.mods;
|
||||||
|
|
||||||
|
assert!(binding.is_triggered_by(TermMode::INSERT, mods, &t, true));
|
||||||
|
assert!(!binding.is_triggered_by(TermMode::ALT_SCREEN, mods, &t, true));
|
||||||
|
assert!(!binding.is_triggered_by(TermMode::ALT_SCREEN | TermMode::INSERT, mods, &t, true));
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum MultiClick {
|
enum MultiClick {
|
||||||
DoubleClick,
|
DoubleClick,
|
||||||
|
|
Loading…
Reference in New Issue