mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-28 17:43:20 +03:00
Add MutableAppContext::keystrokes_for_action
This can be used to lookup keystrokes that will dispatch an action based on the currently focused view. There might be multiple, but we return the first found, meaning the most recently added bindings matching that action for the closest view to the focused view in the hierarchy.
This commit is contained in:
parent
b110fd5fb7
commit
5b7825d5de
@ -1413,6 +1413,28 @@ impl MutableAppContext {
|
||||
self.global_actions.contains_key(&action_type)
|
||||
}
|
||||
|
||||
/// Return keystrokes that would dispatch the given action closest to the focused view, if there are any.
|
||||
pub fn keystrokes_for_action(&self, action: &dyn Action) -> Option<SmallVec<[Keystroke; 2]>> {
|
||||
let window_id = self.cx.platform.key_window_id()?;
|
||||
let (presenter, _) = self.presenters_and_platform_windows.get(&window_id)?;
|
||||
let dispatch_path = presenter.borrow().dispatch_path(&self.cx);
|
||||
|
||||
for view_id in dispatch_path.iter().rev() {
|
||||
let view = self
|
||||
.cx
|
||||
.views
|
||||
.get(&(window_id, *view_id))
|
||||
.expect("view in responder chain does not exist");
|
||||
let cx = view.keymap_context(self.as_ref());
|
||||
let keystrokes = self.keystroke_matcher.keystrokes_for_action(action, &cx);
|
||||
if keystrokes.is_some() {
|
||||
return keystrokes;
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: &dyn Action) {
|
||||
let presenter = self
|
||||
.presenters_and_platform_windows
|
||||
|
@ -30,9 +30,9 @@ pub struct Keymap {
|
||||
}
|
||||
|
||||
pub struct Binding {
|
||||
keystrokes: Vec<Keystroke>,
|
||||
keystrokes: SmallVec<[Keystroke; 2]>,
|
||||
action: Box<dyn Action>,
|
||||
context: Option<ContextPredicate>,
|
||||
context_predicate: Option<ContextPredicate>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@ -146,7 +146,11 @@ impl Matcher {
|
||||
let mut retain_pending = false;
|
||||
for binding in self.keymap.bindings.iter().rev() {
|
||||
if binding.keystrokes.starts_with(&pending.keystrokes)
|
||||
&& binding.context.as_ref().map(|c| c.eval(cx)).unwrap_or(true)
|
||||
&& binding
|
||||
.context_predicate
|
||||
.as_ref()
|
||||
.map(|c| c.eval(cx))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
if binding.keystrokes.len() == pending.keystrokes.len() {
|
||||
self.pending.remove(&view_id);
|
||||
@ -165,6 +169,24 @@ impl Matcher {
|
||||
MatchResult::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keystrokes_for_action(
|
||||
&self,
|
||||
action: &dyn Action,
|
||||
cx: &Context,
|
||||
) -> Option<SmallVec<[Keystroke; 2]>> {
|
||||
for binding in self.keymap.bindings.iter().rev() {
|
||||
if binding.action.id() == action.id()
|
||||
&& binding
|
||||
.context_predicate
|
||||
.as_ref()
|
||||
.map_or(true, |predicate| predicate.eval(cx))
|
||||
{
|
||||
return Some(binding.keystrokes.clone());
|
||||
}
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Matcher {
|
||||
@ -236,7 +258,7 @@ impl Binding {
|
||||
Ok(Self {
|
||||
keystrokes,
|
||||
action,
|
||||
context,
|
||||
context_predicate: context,
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user