Refactor KeybindingKeystroke (#37065)
This pull request refactors the `KeybindingKeystroke` struct and related code to improve platform abstraction. The changes centralize platform-specific logic within `KeybindingKeystroke` and update its usage throughout the codebase, making the API more consistent and less error-prone. Release Notes: - N/A
This commit is contained in:
@@ -14,9 +14,9 @@ use gpui::{
|
||||
Action, AppContext as _, AsyncApp, Axis, ClickEvent, Context, DismissEvent, Entity,
|
||||
EventEmitter, FocusHandle, Focusable, Global, IsZero,
|
||||
KeyBindingContextPredicate::{And, Descendant, Equal, Identifier, Not, NotEqual, Or},
|
||||
KeyContext, KeybindingKeystroke, Keystroke, MouseButton, PlatformKeyboardMapper, Point,
|
||||
ScrollStrategy, ScrollWheelEvent, Stateful, StyledText, Subscription, Task,
|
||||
TextStyleRefinement, WeakEntity, actions, anchored, deferred, div,
|
||||
KeyContext, KeybindingKeystroke, MouseButton, PlatformKeyboardMapper, Point, ScrollStrategy,
|
||||
ScrollWheelEvent, Stateful, StyledText, Subscription, Task, TextStyleRefinement, WeakEntity,
|
||||
actions, anchored, deferred, div,
|
||||
};
|
||||
use language::{Language, LanguageConfig, ToOffset as _};
|
||||
use notifications::status_toast::{StatusToast, ToastIcon};
|
||||
@@ -420,7 +420,7 @@ fn keystrokes_match_exactly(
|
||||
) -> bool {
|
||||
keystrokes1.len() == keystrokes2.len()
|
||||
&& keystrokes1.iter().zip(keystrokes2).all(|(k1, k2)| {
|
||||
k1.inner.key == k2.inner.key && k1.inner.modifiers == k2.inner.modifiers
|
||||
k1.inner().key == k2.inner().key && k1.inner().modifiers == k2.inner().modifiers
|
||||
})
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ impl KeymapEditor {
|
||||
|
||||
let keystroke_query = keystroke_query
|
||||
.into_iter()
|
||||
.map(|keystroke| keystroke.inner.unparse())
|
||||
.map(|keystroke| keystroke.inner().unparse())
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ");
|
||||
|
||||
@@ -606,13 +606,13 @@ impl KeymapEditor {
|
||||
let query = &keystroke_query[query_cursor];
|
||||
let keystroke = &keystrokes[keystroke_cursor];
|
||||
let matches = query
|
||||
.inner
|
||||
.inner()
|
||||
.modifiers
|
||||
.is_subset_of(&keystroke.inner.modifiers)
|
||||
&& ((query.inner.key.is_empty()
|
||||
|| query.inner.key == keystroke.inner.key)
|
||||
&& query.inner.key_char.as_ref().is_none_or(
|
||||
|q_kc| q_kc == &keystroke.inner.key,
|
||||
.is_subset_of(&keystroke.inner().modifiers)
|
||||
&& ((query.inner().key.is_empty()
|
||||
|| query.inner().key == keystroke.inner().key)
|
||||
&& query.inner().key_char.as_ref().is_none_or(
|
||||
|q_kc| q_kc == &keystroke.inner().key,
|
||||
));
|
||||
if matches {
|
||||
found_count += 1;
|
||||
@@ -2256,12 +2256,10 @@ impl KeybindingEditorModal {
|
||||
let fs = self.fs.clone();
|
||||
let tab_size = cx.global::<settings::SettingsStore>().json_tab_size();
|
||||
|
||||
let new_keystrokes = self
|
||||
.validate_keystrokes(cx)
|
||||
.map_err(InputError::error)?
|
||||
.into_iter()
|
||||
.map(remove_key_char)
|
||||
.collect::<Vec<_>>();
|
||||
let mut new_keystrokes = self.validate_keystrokes(cx).map_err(InputError::error)?;
|
||||
new_keystrokes
|
||||
.iter_mut()
|
||||
.for_each(|ks| ks.remove_key_char());
|
||||
|
||||
let new_context = self.validate_context(cx).map_err(InputError::error)?;
|
||||
let new_action_args = self
|
||||
@@ -2454,24 +2452,6 @@ impl KeybindingEditorModal {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_key_char(
|
||||
KeybindingKeystroke {
|
||||
inner,
|
||||
display_modifiers,
|
||||
display_key,
|
||||
}: KeybindingKeystroke,
|
||||
) -> KeybindingKeystroke {
|
||||
KeybindingKeystroke {
|
||||
inner: Keystroke {
|
||||
modifiers: inner.modifiers,
|
||||
key: inner.key,
|
||||
key_char: None,
|
||||
},
|
||||
display_modifiers,
|
||||
display_key,
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for KeybindingEditorModal {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let theme = cx.theme().colors();
|
||||
|
||||
@@ -116,7 +116,7 @@ impl KeystrokeInput {
|
||||
&& self
|
||||
.keystrokes
|
||||
.last()
|
||||
.is_some_and(|last| last.display_key.is_empty())
|
||||
.is_some_and(|last| last.key().is_empty())
|
||||
{
|
||||
return &self.keystrokes[..self.keystrokes.len() - 1];
|
||||
}
|
||||
@@ -124,15 +124,11 @@ impl KeystrokeInput {
|
||||
}
|
||||
|
||||
fn dummy(modifiers: Modifiers) -> KeybindingKeystroke {
|
||||
KeybindingKeystroke {
|
||||
inner: Keystroke {
|
||||
modifiers,
|
||||
key: "".to_string(),
|
||||
key_char: None,
|
||||
},
|
||||
display_modifiers: modifiers,
|
||||
display_key: "".to_string(),
|
||||
}
|
||||
KeybindingKeystroke::from_keystroke(Keystroke {
|
||||
modifiers,
|
||||
key: "".to_string(),
|
||||
key_char: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn keystrokes_changed(&self, cx: &mut Context<Self>) {
|
||||
@@ -258,7 +254,7 @@ impl KeystrokeInput {
|
||||
self.keystrokes_changed(cx);
|
||||
|
||||
if let Some(last) = self.keystrokes.last_mut()
|
||||
&& last.display_key.is_empty()
|
||||
&& last.key().is_empty()
|
||||
&& keystrokes_len <= Self::KEYSTROKE_COUNT_MAX
|
||||
{
|
||||
if !self.search && !event.modifiers.modified() {
|
||||
@@ -267,15 +263,14 @@ impl KeystrokeInput {
|
||||
}
|
||||
if self.search {
|
||||
if self.previous_modifiers.modified() {
|
||||
last.display_modifiers |= event.modifiers;
|
||||
last.inner.modifiers |= event.modifiers;
|
||||
let modifiers = *last.modifiers() | event.modifiers;
|
||||
last.set_modifiers(modifiers);
|
||||
} else {
|
||||
self.keystrokes.push(Self::dummy(event.modifiers));
|
||||
}
|
||||
self.previous_modifiers |= event.modifiers;
|
||||
} else {
|
||||
last.display_modifiers = event.modifiers;
|
||||
last.inner.modifiers = event.modifiers;
|
||||
last.set_modifiers(event.modifiers);
|
||||
return;
|
||||
}
|
||||
} else if keystrokes_len < Self::KEYSTROKE_COUNT_MAX {
|
||||
@@ -303,10 +298,13 @@ impl KeystrokeInput {
|
||||
return;
|
||||
}
|
||||
|
||||
let keystroke =
|
||||
KeybindingKeystroke::new(keystroke.clone(), false, cx.keyboard_mapper().as_ref());
|
||||
let keystroke = KeybindingKeystroke::new_with_mapper(
|
||||
keystroke.clone(),
|
||||
false,
|
||||
cx.keyboard_mapper().as_ref(),
|
||||
);
|
||||
if let Some(last) = self.keystrokes.last()
|
||||
&& last.display_key.is_empty()
|
||||
&& last.key().is_empty()
|
||||
&& (!self.search || self.previous_modifiers.modified())
|
||||
{
|
||||
self.keystrokes.pop();
|
||||
@@ -825,7 +823,7 @@ mod tests {
|
||||
input
|
||||
.keystrokes
|
||||
.iter()
|
||||
.map(|keystroke| keystroke.inner.clone())
|
||||
.map(|keystroke| keystroke.inner().clone())
|
||||
.collect()
|
||||
});
|
||||
Self::expect_keystrokes_equal(&actual, expected);
|
||||
@@ -1094,7 +1092,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn keystrokes_str(ks: &[KeybindingKeystroke]) -> String {
|
||||
ks.iter().map(|ks| ks.inner.unparse()).join(" ")
|
||||
ks.iter().map(|ks| ks.inner().unparse()).join(" ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user