Fix bindings incorrectly getting replaced

Fixes #2794.
This commit is contained in:
Christian Duerr 2019-09-16 17:02:29 +02:00 committed by GitHub
parent fb37a9cb55
commit c42df41332
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 95 additions and 26 deletions

View File

@ -198,10 +198,21 @@ impl<T: Eq> Binding<T> {
#[inline]
pub fn triggers_match(&self, binding: &Binding<T>) -> bool {
self.trigger == binding.trigger
&& self.mods == binding.mods
&& (self.mode.contains(binding.mode) || binding.mode.contains(self.mode))
&& (self.notmode.contains(binding.notmode) || binding.notmode.contains(self.notmode))
// Check the binding's key and modifiers
if self.trigger != binding.trigger || self.mods != binding.mods {
return false;
}
// Completely empty modes match all modes
if (self.mode.is_empty() && self.notmode.is_empty())
|| (binding.mode.is_empty() && binding.notmode.is_empty())
{
return true;
}
// Check for intersection (equality is required since empty does not intersect itself)
(self.mode == binding.mode || self.mode.intersects(binding.mode))
&& (self.notmode == binding.notmode || self.notmode.intersects(binding.notmode))
}
}
@ -1074,28 +1085,6 @@ mod tests {
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();
@ -1107,6 +1096,86 @@ mod tests {
assert!(!subset_mods.triggers_match(&superset_mods));
}
#[test]
fn binding_matches_identical_mode() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::ALT_SCREEN;
let mut b2 = MockBinding::default();
b2.mode = TermMode::ALT_SCREEN;
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_without_mode_matches_any_mode() {
let b1 = MockBinding::default();
let mut b2 = MockBinding::default();
b2.mode = TermMode::APP_KEYPAD;
b2.notmode = TermMode::ALT_SCREEN;
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_with_mode_matches_empty_mode() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::APP_KEYPAD;
b1.notmode = TermMode::ALT_SCREEN;
let b2 = MockBinding::default();
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_matches_superset_mode() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::APP_KEYPAD;
let mut b2 = MockBinding::default();
b2.mode = TermMode::ALT_SCREEN | TermMode::APP_KEYPAD;
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_matches_subset_mode() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::ALT_SCREEN | TermMode::APP_KEYPAD;
let mut b2 = MockBinding::default();
b2.mode = TermMode::APP_KEYPAD;
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_matches_partial_intersection() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::ALT_SCREEN | TermMode::APP_KEYPAD;
let mut b2 = MockBinding::default();
b2.mode = TermMode::APP_KEYPAD | TermMode::APP_CURSOR;
assert!(b1.triggers_match(&b2));
}
#[test]
fn binding_mismatches_notmode() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::ALT_SCREEN;
let mut b2 = MockBinding::default();
b2.notmode = TermMode::ALT_SCREEN;
assert!(!b1.triggers_match(&b2));
}
#[test]
fn binding_mismatches_unrelated() {
let mut b1 = MockBinding::default();
b1.mode = TermMode::ALT_SCREEN;
let mut b2 = MockBinding::default();
b2.mode = TermMode::APP_KEYPAD;
assert!(!b1.triggers_match(&b2));
}
#[test]
fn binding_trigger_input() {
let mut binding = MockBinding::default();