checkpoint
This commit is contained in:
parent
f602c1d69e
commit
8e357210f1
5 changed files with 87 additions and 48 deletions
|
@ -9171,7 +9171,7 @@ impl Editor {
|
||||||
max_width: Pixels,
|
max_width: Pixels,
|
||||||
cursor_point: Point,
|
cursor_point: Point,
|
||||||
style: &EditorStyle,
|
style: &EditorStyle,
|
||||||
accept_keystroke: Option<&gpui::Keystroke>,
|
accept_keystroke: Option<&gpui::KeybindingKeystroke>,
|
||||||
_window: &Window,
|
_window: &Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> Option<AnyElement> {
|
) -> Option<AnyElement> {
|
||||||
|
|
|
@ -43,10 +43,10 @@ use gpui::{
|
||||||
Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle,
|
Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle,
|
||||||
DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _, FontId,
|
DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _, FontId,
|
||||||
GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero,
|
GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero,
|
||||||
Keystroke, Length, ModifiersChangedEvent, MouseButton, MouseClickEvent, MouseDownEvent,
|
KeybindingKeystroke, Length, ModifiersChangedEvent, MouseButton, MouseClickEvent,
|
||||||
MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollHandle,
|
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
|
||||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled,
|
ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement,
|
||||||
TextRun, TextStyleRefinement, WeakEntity, Window, anchored, deferred, div, fill,
|
Style, Styled, TextRun, TextStyleRefinement, WeakEntity, Window, anchored, deferred, div, fill,
|
||||||
linear_color_stop, linear_gradient, outline, point, px, quad, relative, size, solid_background,
|
linear_color_stop, linear_gradient, outline, point, px, quad, relative, size, solid_background,
|
||||||
transparent_black,
|
transparent_black,
|
||||||
};
|
};
|
||||||
|
@ -7150,7 +7150,7 @@ fn header_jump_data(
|
||||||
pub struct AcceptEditPredictionBinding(pub(crate) Option<gpui::KeyBinding>);
|
pub struct AcceptEditPredictionBinding(pub(crate) Option<gpui::KeyBinding>);
|
||||||
|
|
||||||
impl AcceptEditPredictionBinding {
|
impl AcceptEditPredictionBinding {
|
||||||
pub fn keystroke(&self) -> Option<&Keystroke> {
|
pub fn keystroke(&self) -> Option<&KeybindingKeystroke> {
|
||||||
if let Some(binding) = self.0.as_ref() {
|
if let Some(binding) = self.0.as_ref() {
|
||||||
match &binding.keystrokes() {
|
match &binding.keystrokes() {
|
||||||
[keystroke, ..] => Some(keystroke),
|
[keystroke, ..] => Some(keystroke),
|
||||||
|
|
|
@ -14,7 +14,7 @@ use gpui::{
|
||||||
Action, AppContext as _, AsyncApp, Axis, ClickEvent, Context, DismissEvent, Entity,
|
Action, AppContext as _, AsyncApp, Axis, ClickEvent, Context, DismissEvent, Entity,
|
||||||
EventEmitter, FocusHandle, Focusable, Global, IsZero,
|
EventEmitter, FocusHandle, Focusable, Global, IsZero,
|
||||||
KeyBindingContextPredicate::{And, Descendant, Equal, Identifier, Not, NotEqual, Or},
|
KeyBindingContextPredicate::{And, Descendant, Equal, Identifier, Not, NotEqual, Or},
|
||||||
KeyContext, Keystroke, MouseButton, Point, ScrollStrategy, ScrollWheelEvent, Stateful,
|
KeyContext, KeybindingKeystroke,Keystroke, MouseButton, Point, ScrollStrategy, ScrollWheelEvent, Stateful,
|
||||||
StyledText, Subscription, Task, TextStyleRefinement, WeakEntity, actions, anchored, deferred,
|
StyledText, Subscription, Task, TextStyleRefinement, WeakEntity, actions, anchored, deferred,
|
||||||
div,
|
div,
|
||||||
};
|
};
|
||||||
|
@ -174,7 +174,7 @@ impl FilterState {
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq, Clone, Hash)]
|
#[derive(Debug, Default, PartialEq, Eq, Clone, Hash)]
|
||||||
struct ActionMapping {
|
struct ActionMapping {
|
||||||
keystrokes: Vec<Keystroke>,
|
keystrokes: Vec<KeybindingKeystroke>,
|
||||||
context: Option<SharedString>,
|
context: Option<SharedString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,12 +414,14 @@ impl Focusable for KeymapEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Helper function to check if two keystroke sequences match exactly
|
/// Helper function to check if two keystroke sequences match exactly
|
||||||
fn keystrokes_match_exactly(keystrokes1: &[Keystroke], keystrokes2: &[Keystroke]) -> bool {
|
fn keystrokes_match_exactly(
|
||||||
|
keystrokes1: &[KeybindingKeystroke],
|
||||||
|
keystrokes2: &[KeybindingKeystroke],
|
||||||
|
) -> bool {
|
||||||
keystrokes1.len() == keystrokes2.len()
|
keystrokes1.len() == keystrokes2.len()
|
||||||
&& keystrokes1
|
&& keystrokes1.iter().zip(keystrokes2).all(|(k1, k2)| {
|
||||||
.iter()
|
k1.inner.key == k2.inner.key && k1.inner.modifiers == k2.inner.modifiers
|
||||||
.zip(keystrokes2)
|
})
|
||||||
.all(|(k1, k2)| k1.key == k2.key && k1.modifiers == k2.modifiers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeymapEditor {
|
impl KeymapEditor {
|
||||||
|
@ -509,7 +511,7 @@ impl KeymapEditor {
|
||||||
self.filter_editor.read(cx).text(cx)
|
self.filter_editor.read(cx).text(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_keystroke_query(&self, cx: &App) -> Vec<Keystroke> {
|
fn current_keystroke_query(&self, cx: &App) -> Vec<KeybindingKeystroke> {
|
||||||
match self.search_mode {
|
match self.search_mode {
|
||||||
SearchMode::KeyStroke { .. } => self.keystroke_editor.read(cx).keystrokes().to_vec(),
|
SearchMode::KeyStroke { .. } => self.keystroke_editor.read(cx).keystrokes().to_vec(),
|
||||||
SearchMode::Normal => Default::default(),
|
SearchMode::Normal => Default::default(),
|
||||||
|
@ -530,7 +532,7 @@ impl KeymapEditor {
|
||||||
|
|
||||||
let keystroke_query = keystroke_query
|
let keystroke_query = keystroke_query
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|keystroke| keystroke.unparse())
|
.map(|keystroke| keystroke.inner.unparse())
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(" ");
|
.join(" ");
|
||||||
|
|
||||||
|
@ -554,7 +556,7 @@ impl KeymapEditor {
|
||||||
async fn update_matches(
|
async fn update_matches(
|
||||||
this: WeakEntity<Self>,
|
this: WeakEntity<Self>,
|
||||||
action_query: String,
|
action_query: String,
|
||||||
keystroke_query: Vec<Keystroke>,
|
keystroke_query: Vec<KeybindingKeystroke>,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let action_query = command_palette::normalize_action_query(&action_query);
|
let action_query = command_palette::normalize_action_query(&action_query);
|
||||||
|
@ -604,12 +606,15 @@ impl KeymapEditor {
|
||||||
let query = &keystroke_query[query_cursor];
|
let query = &keystroke_query[query_cursor];
|
||||||
let keystroke = &keystrokes[keystroke_cursor];
|
let keystroke = &keystrokes[keystroke_cursor];
|
||||||
let matches =
|
let matches =
|
||||||
query.modifiers.is_subset_of(&keystroke.modifiers)
|
query.inner.modifiers.is_subset_of(&keystroke.inner.modifiers)
|
||||||
&& ((query.key.is_empty()
|
&& ((query.inner.key.is_empty()
|
||||||
|| query.key == keystroke.key)
|
|| query.inner.key == keystroke.inner.key)
|
||||||
&& query.key_char.as_ref().is_none_or(
|
&& query.inner
|
||||||
|q_kc| q_kc == &keystroke.key,
|
.key_char
|
||||||
));
|
.as_ref()
|
||||||
|
.is_none_or(|q_kc| {
|
||||||
|
q_kc == &keystroke.inner.key
|
||||||
|
});
|
||||||
if matches {
|
if matches {
|
||||||
found_count += 1;
|
found_count += 1;
|
||||||
query_cursor += 1;
|
query_cursor += 1;
|
||||||
|
@ -678,7 +683,7 @@ impl KeymapEditor {
|
||||||
.map(KeybindSource::from_meta)
|
.map(KeybindSource::from_meta)
|
||||||
.unwrap_or(KeybindSource::Unknown);
|
.unwrap_or(KeybindSource::Unknown);
|
||||||
|
|
||||||
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 = ui::KeyBinding::new_from_gpui(key_binding.clone(), cx)
|
let ui_key_binding = ui::KeyBinding::new_from_gpui(key_binding.clone(), cx)
|
||||||
.vim_mode(source == KeybindSource::Vim);
|
.vim_mode(source == KeybindSource::Vim);
|
||||||
|
|
||||||
|
@ -1422,7 +1427,7 @@ impl ProcessedBinding {
|
||||||
.map(|keybind| keybind.get_action_mapping())
|
.map(|keybind| keybind.get_action_mapping())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keystrokes(&self) -> Option<&[Keystroke]> {
|
fn keystrokes(&self) -> Option<&[KeybindingKeystroke]> {
|
||||||
self.ui_key_binding()
|
self.ui_key_binding()
|
||||||
.map(|binding| binding.keystrokes.as_slice())
|
.map(|binding| binding.keystrokes.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -2220,7 +2225,7 @@ impl KeybindingEditorModal {
|
||||||
Ok(action_arguments)
|
Ok(action_arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_keystrokes(&self, cx: &App) -> anyhow::Result<Vec<Keystroke>> {
|
fn validate_keystrokes(&self, cx: &App) -> anyhow::Result<Vec<KeybindingKeystroke>> {
|
||||||
let new_keystrokes = self
|
let new_keystrokes = self
|
||||||
.keybind_editor
|
.keybind_editor
|
||||||
.read_with(cx, |editor, _| editor.keystrokes().to_vec());
|
.read_with(cx, |editor, _| editor.keystrokes().to_vec());
|
||||||
|
@ -2445,11 +2450,21 @@ impl KeybindingEditorModal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_key_char(Keystroke { modifiers, key, .. }: Keystroke) -> Keystroke {
|
fn remove_key_char(
|
||||||
Keystroke {
|
KeybindingKeystroke {
|
||||||
|
inner,
|
||||||
|
modifiers,
|
||||||
|
key,
|
||||||
|
}: KeybindingKeystroke,
|
||||||
|
) -> KeybindingKeystroke {
|
||||||
|
KeybindingKeystroke {
|
||||||
|
inner: Keystroke {
|
||||||
|
modifiers: inner.modifiers,
|
||||||
|
key: inner.key,
|
||||||
|
key_char: None,
|
||||||
|
},
|
||||||
modifiers,
|
modifiers,
|
||||||
key,
|
key,
|
||||||
..Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Animation, AnimationExt, Context, EventEmitter, FocusHandle, Focusable, FontWeight, KeyContext,
|
Animation, AnimationExt, Context, EventEmitter, FocusHandle, Focusable, FontWeight, KeyContext,
|
||||||
Keystroke, Modifiers, ModifiersChangedEvent, Subscription, Task, actions,
|
KeybindingKeystroke, Keystroke, Modifiers, ModifiersChangedEvent, Subscription, Task, actions,
|
||||||
};
|
};
|
||||||
use ui::{
|
use ui::{
|
||||||
ActiveTheme as _, Color, IconButton, IconButtonShape, IconName, IconSize, Label, LabelSize,
|
ActiveTheme as _, Color, IconButton, IconButtonShape, IconName, IconSize, Label, LabelSize,
|
||||||
|
@ -42,8 +42,8 @@ impl PartialEq for CloseKeystrokeResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KeystrokeInput {
|
pub struct KeystrokeInput {
|
||||||
keystrokes: Vec<Keystroke>,
|
keystrokes: Vec<KeybindingKeystroke>,
|
||||||
placeholder_keystrokes: Option<Vec<Keystroke>>,
|
placeholder_keystrokes: Option<Vec<KeybindingKeystroke>>,
|
||||||
outer_focus_handle: FocusHandle,
|
outer_focus_handle: FocusHandle,
|
||||||
inner_focus_handle: FocusHandle,
|
inner_focus_handle: FocusHandle,
|
||||||
intercept_subscription: Option<Subscription>,
|
intercept_subscription: Option<Subscription>,
|
||||||
|
@ -70,7 +70,7 @@ impl KeystrokeInput {
|
||||||
const KEYSTROKE_COUNT_MAX: usize = 3;
|
const KEYSTROKE_COUNT_MAX: usize = 3;
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
placeholder_keystrokes: Option<Vec<Keystroke>>,
|
placeholder_keystrokes: Option<Vec<KeybindingKeystroke>>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -97,7 +97,7 @@ impl KeystrokeInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_keystrokes(&mut self, keystrokes: Vec<Keystroke>, cx: &mut Context<Self>) {
|
pub fn set_keystrokes(&mut self, keystrokes: Vec<KeybindingKeystroke>, cx: &mut Context<Self>) {
|
||||||
self.keystrokes = keystrokes;
|
self.keystrokes = keystrokes;
|
||||||
self.keystrokes_changed(cx);
|
self.keystrokes_changed(cx);
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ impl KeystrokeInput {
|
||||||
self.search = search;
|
self.search = search;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keystrokes(&self) -> &[Keystroke] {
|
pub fn keystrokes(&self) -> &[KeybindingKeystroke] {
|
||||||
if let Some(placeholders) = self.placeholder_keystrokes.as_ref()
|
if let Some(placeholders) = self.placeholder_keystrokes.as_ref()
|
||||||
&& self.keystrokes.is_empty()
|
&& self.keystrokes.is_empty()
|
||||||
{
|
{
|
||||||
|
@ -123,11 +123,15 @@ impl KeystrokeInput {
|
||||||
&self.keystrokes
|
&self.keystrokes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dummy(modifiers: Modifiers) -> Keystroke {
|
fn dummy(modifiers: Modifiers) -> KeybindingKeystroke {
|
||||||
Keystroke {
|
KeybindingKeystroke {
|
||||||
|
inner: Keystroke {
|
||||||
|
modifiers,
|
||||||
|
key: "".to_string(),
|
||||||
|
key_char: None,
|
||||||
|
},
|
||||||
modifiers,
|
modifiers,
|
||||||
key: "".to_string(),
|
key: "".to_string(),
|
||||||
key_char: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +301,7 @@ impl KeystrokeInput {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut keystroke = keystroke.clone();
|
let mut keystroke = KeybindingKeystroke::new(keystroke.clone());
|
||||||
if let Some(last) = self.keystrokes.last()
|
if let Some(last) = self.keystrokes.last()
|
||||||
&& last.key.is_empty()
|
&& last.key.is_empty()
|
||||||
&& (!self.search || self.previous_modifiers.modified())
|
&& (!self.search || self.previous_modifiers.modified())
|
||||||
|
@ -809,9 +813,13 @@ mod tests {
|
||||||
/// Verifies that the keystrokes match the expected strings
|
/// Verifies that the keystrokes match the expected strings
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn expect_keystrokes(&mut self, expected: &[&str]) -> &mut Self {
|
pub fn expect_keystrokes(&mut self, expected: &[&str]) -> &mut Self {
|
||||||
let actual = self
|
let actual: Vec<Keystroke> = self.input.read_with(&self.cx, |input, _| {
|
||||||
.input
|
input
|
||||||
.read_with(&self.cx, |input, _| input.keystrokes.clone());
|
.keystrokes
|
||||||
|
.iter()
|
||||||
|
.map(|keystroke| keystroke.inner.clone())
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
Self::expect_keystrokes_equal(&actual, expected);
|
Self::expect_keystrokes_equal(&actual, expected);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -939,7 +947,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KeystrokeUpdateTracker {
|
struct KeystrokeUpdateTracker {
|
||||||
initial_keystrokes: Vec<Keystroke>,
|
initial_keystrokes: Vec<KeybindingKeystroke>,
|
||||||
_subscription: Subscription,
|
_subscription: Subscription,
|
||||||
input: Entity<KeystrokeInput>,
|
input: Entity<KeystrokeInput>,
|
||||||
received_keystrokes_updated: bool,
|
received_keystrokes_updated: bool,
|
||||||
|
@ -983,8 +991,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keystrokes_str(ks: &[Keystroke]) -> String {
|
fn keystrokes_str(ks: &[KeybindingKeystroke]) -> String {
|
||||||
ks.iter().map(|ks| ks.unparse()).join(" ")
|
ks.iter().map(|ks| ks.inner.unparse()).join(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::PlatformStyle;
|
use crate::PlatformStyle;
|
||||||
use crate::{Icon, IconName, IconSize, h_flex, prelude::*};
|
use crate::{Icon, IconName, IconSize, h_flex, prelude::*};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, AnyElement, App, FocusHandle, Global, IntoElement, KeybindingKeystroke, Modifiers,
|
Action, AnyElement, App, FocusHandle, Global, IntoElement, KeybindingKeystroke, Keystroke,
|
||||||
Window, relative,
|
Modifiers, Window, relative,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
@ -387,10 +387,26 @@ impl KeyIcon {
|
||||||
/// Returns a textual representation of the key binding for the given [`Action`].
|
/// 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> {
|
pub fn text_for_action(action: &dyn Action, window: &Window, cx: &App) -> Option<String> {
|
||||||
let key_binding = window.highest_precedence_binding_for_action(action)?;
|
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_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
|
||||||
|
.iter()
|
||||||
|
.map(|keystroke| {
|
||||||
|
keystroke_text(
|
||||||
|
&keystroke.modifiers,
|
||||||
|
&keystroke.key,
|
||||||
|
platform_style,
|
||||||
|
vim_enabled,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.join(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_for_keybinding_keystrokes(keystrokes: &[KeybindingKeystroke], cx: &App) -> String {
|
||||||
let platform_style = PlatformStyle::platform();
|
let platform_style = PlatformStyle::platform();
|
||||||
let vim_enabled = cx.try_global::<VimStyle>().is_some();
|
let vim_enabled = cx.try_global::<VimStyle>().is_some();
|
||||||
keystrokes
|
keystrokes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue