diff --git a/crates/gpui3/src/keymap/keymap.rs b/crates/gpui3/src/keymap/keymap.rs index f7b537af46e1f27a1702d9cdee7b34bc4059634f..6bbb87a0e3ae9865644e4e058f8c116fdad10cf3 100644 --- a/crates/gpui3/src/keymap/keymap.rs +++ b/crates/gpui3/src/keymap/keymap.rs @@ -25,10 +25,7 @@ impl Keymap { self.version } - pub(crate) fn bindings_for_action( - &self, - action_id: TypeId, - ) -> impl Iterator { + pub fn bindings_for_action(&self, action_id: TypeId) -> impl Iterator { self.binding_indices_by_action_id .get(&action_id) .map(SmallVec::as_slice) diff --git a/crates/gpui3/src/keymap/matcher.rs b/crates/gpui3/src/keymap/matcher.rs index 38c8cc42f0cc46e40d25dfb32a2f12b1cc57d3a0..38d2f38029726561dabede829957b3c78fde99fa 100644 --- a/crates/gpui3/src/keymap/matcher.rs +++ b/crates/gpui3/src/keymap/matcher.rs @@ -1,6 +1,7 @@ -use crate::{Binding, Keymap, KeymapContext, KeymapVersion, Keystroke}; +use crate::{Keymap, KeymapContext, KeymapVersion, Keystroke}; +use parking_lot::RwLock; use smallvec::SmallVec; -use std::any::{Any, TypeId}; +use std::{any::Any, sync::Arc}; pub trait Action: Any + Send + Sync { fn partial_eq(&self, action: &dyn Action) -> bool; @@ -10,22 +11,24 @@ pub trait Action: Any + Send + Sync { pub struct KeyMatcher { pending_keystrokes: Vec, - keymap: Keymap, + keymap: Arc>, keymap_version: KeymapVersion, } impl KeyMatcher { - pub fn new(keymap: Keymap) -> Self { + pub fn new(keymap: Arc>) -> Self { + let keymap_version = keymap.read().version(); Self { pending_keystrokes: Vec::new(), - keymap_version: keymap.version(), + keymap_version, keymap, } } - pub fn bindings_for_action(&self, action_id: TypeId) -> impl Iterator { - self.keymap.bindings_for_action(action_id) - } + // todo!("replace with a function that calls an FnMut for every binding matching the action") + // pub fn bindings_for_action(&self, action_id: TypeId) -> impl Iterator { + // self.keymap.read().bindings_for_action(action_id) + // } pub fn clear_pending(&mut self) { self.pending_keystrokes.clear(); @@ -49,20 +52,21 @@ impl KeyMatcher { keystroke: &Keystroke, context_stack: &[KeymapContext], ) -> KeyMatch { + let keymap = self.keymap.read(); // Clear pending keystrokes if the keymap has changed since the last matched keystroke. - if self.keymap.version() != self.keymap_version { - self.keymap_version = self.keymap.version(); + if keymap.version() != self.keymap_version { + self.keymap_version = keymap.version(); self.pending_keystrokes.clear(); } let mut pending_key = None; - for binding in self.keymap.bindings().iter().rev() { + for binding in keymap.bindings().iter().rev() { for candidate in keystroke.match_candidates() { self.pending_keystrokes.push(candidate.clone()); match binding.match_keystrokes(&self.pending_keystrokes, context_stack) { KeyMatch::Some(action) => { - self.clear_pending(); + self.pending_keystrokes.clear(); return KeyMatch::Some(action); } KeyMatch::Pending => { @@ -91,6 +95,7 @@ impl KeyMatcher { contexts: &[KeymapContext], ) -> Option> { self.keymap + .read() .bindings() .iter() .rev() @@ -98,12 +103,6 @@ impl KeyMatcher { } } -impl Default for KeyMatcher { - fn default() -> Self { - Self::new(Keymap::default()) - } -} - pub enum KeyMatch { None, Pending,