checkpoint

Junkui Zhang created

Change summary

crates/editor/src/editor.rs            |  2 
crates/editor/src/element.rs           | 14 +++++-----
crates/gpui/src/platform/keystroke.rs  | 10 +++++++
crates/settings_ui/src/keybindings.rs  | 27 ++++++++++++-------
crates/ui/src/components/keybinding.rs | 37 ++++++++++++++++++---------
crates/vim/src/mode_indicator.rs       |  2 +
6 files changed, 62 insertions(+), 30 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -9000,7 +9000,7 @@ impl Editor {
         max_width: Pixels,
         cursor_point: Point,
         style: &EditorStyle,
-        accept_keystroke: Option<&gpui::Keystroke>,
+        accept_keystroke: Option<&gpui::KeybindingKeystroke>,
         _window: &Window,
         cx: &mut Context<Editor>,
     ) -> Option<AnyElement> {

crates/editor/src/element.rs 🔗

@@ -42,12 +42,12 @@ use gpui::{
     Action, Along, AnyElement, App, AppContext, AvailableSpace, Axis as ScrollbarAxis, BorderStyle,
     Bounds, ClickEvent, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase, Edges,
     Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox,
-    HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero, Keystroke, Length,
-    ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
-    ParentElement, Pixels, ScrollDelta, ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString,
-    Size, StatefulInteractiveElement, Style, Styled, TextRun, TextStyleRefinement, WeakEntity,
-    Window, anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px,
-    quad, relative, size, solid_background, transparent_black,
+    HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero, KeybindingKeystroke, Keystroke,
+    Length, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
+    PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollHandle, ScrollWheelEvent, ShapedLine,
+    SharedString, Size, StatefulInteractiveElement, Style, Styled, TextRun, TextStyleRefinement,
+    WeakEntity, Window, anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline,
+    point, px, quad, relative, size, solid_background, transparent_black,
 };
 use itertools::Itertools;
 use language::language_settings::{
@@ -6994,7 +6994,7 @@ fn header_jump_data(
 pub struct AcceptEditPredictionBinding(pub(crate) Option<gpui::KeyBinding>);
 
 impl AcceptEditPredictionBinding {
-    pub fn keystroke(&self) -> Option<&Keystroke> {
+    pub fn keystroke(&self) -> Option<&KeybindingKeystroke> {
         if let Some(binding) = self.0.as_ref() {
             match &binding.keystrokes() {
                 [keystroke, ..] => Some(keystroke),

crates/gpui/src/platform/keystroke.rs 🔗

@@ -272,6 +272,16 @@ impl Keystroke {
         }
         self
     }
+
+    /// TODO:
+    pub fn into_keybinding_keystroke(self) -> KeybindingKeystroke {
+        let (key, modifiers) = temp_keyboard_mapper(self.key.clone(), self.modifiers);
+        KeybindingKeystroke {
+            inner: self,
+            modifiers,
+            key,
+        }
+    }
 }
 
 impl KeybindingKeystroke {

crates/settings_ui/src/keybindings.rs 🔗

@@ -11,8 +11,8 @@ use fs::Fs;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
     AppContext as _, AsyncApp, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
-    Global, KeyContext, Keystroke, ModifiersChangedEvent, ScrollStrategy, StyledText, Subscription,
-    WeakEntity, actions, div, transparent_black,
+    Global, KeyContext, KeybindingKeystroke, Keystroke, ModifiersChangedEvent, ScrollStrategy,
+    StyledText, Subscription, WeakEntity, actions, div, transparent_black,
 };
 use language::{Language, LanguageConfig, ToOffset as _};
 use settings::{BaseKeymap, KeybindSource, KeymapFile, SettingsAssets};
@@ -274,7 +274,7 @@ impl KeymapEditor {
         for key_binding in key_bindings {
             let source = key_binding.meta().map(settings::KeybindSource::from_meta);
 
-            let keystroke_text = ui::text_for_keystrokes(key_binding.keystrokes(), cx);
+            let keystroke_text = ui::text_for_keybinding_keystrokes(key_binding.keystrokes(), cx);
             let ui_key_binding = Some(
                 ui::KeyBinding::new_from_gpui(key_binding.clone(), cx)
                     .vim_mode(source == Some(settings::KeybindSource::Vim)),
@@ -1143,7 +1143,7 @@ async fn load_rust_language(workspace: WeakEntity<Workspace>, cx: &mut AsyncApp)
 
 async fn save_keybinding_update(
     existing: ProcessedKeybinding,
-    new_keystrokes: &[Keystroke],
+    new_keystrokes: &[KeybindingKeystroke],
     new_context: Option<&str>,
     fs: &Arc<dyn Fs>,
     tab_size: usize,
@@ -1280,15 +1280,21 @@ impl KeystrokeInput {
         cx.notify();
     }
 
-    fn keystrokes(&self) -> &[Keystroke] {
-        if self
+    fn keystrokes(&self) -> Vec<KeybindingKeystroke> {
+        let keystrokes = if self
             .keystrokes
             .last()
             .map_or(false, |last| last.key.is_empty())
         {
-            return &self.keystrokes[..self.keystrokes.len() - 1];
-        }
-        return &self.keystrokes;
+            &self.keystrokes[..self.keystrokes.len() - 1]
+        } else {
+            &self.keystrokes
+        };
+        keystrokes
+            .to_vec()
+            .into_iter()
+            .map(|keystroke| keystroke.into_keybinding_keystroke())
+            .collect()
     }
 }
 
@@ -1332,7 +1338,8 @@ impl Render for KeystrokeInput {
                     .gap(ui::DynamicSpacing::Base04.rems(cx))
                     .children(self.keystrokes.iter().map(|keystroke| {
                         h_flex().children(ui::render_keystroke(
-                            keystroke,
+                            &keystroke.modifiers,
+                            &keystroke.key,
                             None,
                             Some(rems(0.875).into()),
                             ui::PlatformStyle::platform(),

crates/ui/src/components/keybinding.rs 🔗

@@ -138,7 +138,8 @@ impl RenderOnce for KeyBinding {
                     .rounded_xs()
                     .text_color(cx.theme().colors().text_muted)
                     .children(render_keystroke(
-                        keystroke,
+                        &keystroke.modifiers,
+                        &keystroke.key,
                         color,
                         self.size,
                         self.platform_style,
@@ -149,7 +150,8 @@ impl RenderOnce for KeyBinding {
 }
 
 pub fn render_keystroke(
-    keystroke: &KeybindingKeystroke,
+    modifiers: &Modifiers,
+    key: &str,
     color: Option<Color>,
     size: impl Into<Option<AbsoluteLength>>,
     platform_style: PlatformStyle,
@@ -164,12 +166,7 @@ pub fn render_keystroke(
 
     if use_text {
         let element = Key::new(
-            keystroke_text(
-                &keystroke.modifiers,
-                &keystroke.key,
-                platform_style,
-                vim_mode,
-            ),
+            keystroke_text(modifiers, key, platform_style, vim_mode),
             color,
         )
         .size(size)
@@ -178,13 +175,13 @@ pub fn render_keystroke(
     } else {
         let mut elements = Vec::new();
         elements.extend(render_modifiers(
-            &keystroke.modifiers,
+            modifiers,
             platform_style,
             color,
             size,
             true,
         ));
-        elements.push(render_key(&keystroke.key, color, platform_style, size));
+        elements.push(render_key(key, color, platform_style, size));
         elements
     }
 }
@@ -387,10 +384,26 @@ impl KeyIcon {
 /// Returns a textual representation of the key binding for the given [`Action`].
 pub fn text_for_action(action: &dyn Action, window: &Window, cx: &App) -> Option<String> {
     let key_binding = window.highest_precedence_binding_for_action(action)?;
-    Some(text_for_keystrokes(key_binding.keystrokes(), cx))
+    Some(text_for_keybinding_keystrokes(key_binding.keystrokes(), cx))
+}
+
+pub fn text_for_keybinding_keystrokes(keystrokes: &[KeybindingKeystroke], cx: &App) -> String {
+    let platform_style = PlatformStyle::platform();
+    let vim_enabled = cx.try_global::<VimStyle>().is_some();
+    keystrokes
+        .iter()
+        .map(|keystroke| {
+            keystroke_text(
+                &keystroke.modifiers,
+                &keystroke.key,
+                platform_style,
+                vim_enabled,
+            )
+        })
+        .join(" ")
 }
 
-pub fn text_for_keystrokes(keystrokes: &[KeybindingKeystroke], cx: &App) -> String {
+pub fn text_for_keystrokes(keystrokes: &[Keystroke], cx: &App) -> String {
     let platform_style = PlatformStyle::platform();
     let vim_enabled = cx.try_global::<VimStyle>().is_some();
     keystrokes

crates/vim/src/mode_indicator.rs 🔗

@@ -50,6 +50,8 @@ impl ModeIndicator {
         }
     }
 
+    // TODO:
+    // what's this?
     fn update_pending_keys(&mut self, window: &mut Window, cx: &App) {
         self.pending_keys = window
             .pending_input_keystrokes()