edit predictions: Fix predictions bar disappearing while loading (#24582)
Release Notes: - N/A --------- Co-authored-by: Max <max@zed.dev>
This commit is contained in:
parent
89e051d650
commit
1f288f7327
3 changed files with 65 additions and 50 deletions
|
@ -190,6 +190,7 @@ pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250);
|
||||||
pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||||
pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
|
pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
|
||||||
|
|
||||||
|
pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";
|
||||||
pub(crate) const EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT: &str =
|
pub(crate) const EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT: &str =
|
||||||
"edit_prediction_requires_modifier";
|
"edit_prediction_requires_modifier";
|
||||||
|
|
||||||
|
@ -1488,13 +1489,13 @@ impl Editor {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mouse_menu_is_focused(&self, window: &mut Window, cx: &mut App) -> bool {
|
pub fn mouse_menu_is_focused(&self, window: &Window, cx: &App) -> bool {
|
||||||
self.mouse_context_menu
|
self.mouse_context_menu
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|menu| menu.context_menu.focus_handle(cx).is_focused(window))
|
.is_some_and(|menu| menu.context_menu.focus_handle(cx).is_focused(window))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_context(&self, window: &mut Window, cx: &mut Context<Self>) -> KeyContext {
|
fn key_context(&self, window: &Window, cx: &App) -> KeyContext {
|
||||||
let mut key_context = KeyContext::new_with_defaults();
|
let mut key_context = KeyContext::new_with_defaults();
|
||||||
key_context.add("Editor");
|
key_context.add("Editor");
|
||||||
let mode = match self.mode {
|
let mode = match self.mode {
|
||||||
|
@ -1547,7 +1548,7 @@ impl Editor {
|
||||||
|
|
||||||
if self.has_active_inline_completion() {
|
if self.has_active_inline_completion() {
|
||||||
key_context.add("copilot_suggestion");
|
key_context.add("copilot_suggestion");
|
||||||
key_context.add("edit_prediction");
|
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||||
|
|
||||||
if showing_completions || self.edit_prediction_requires_modifier() {
|
if showing_completions || self.edit_prediction_requires_modifier() {
|
||||||
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
||||||
|
@ -1561,6 +1562,22 @@ impl Editor {
|
||||||
key_context
|
key_context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn accept_edit_prediction_keybind(
|
||||||
|
&self,
|
||||||
|
window: &Window,
|
||||||
|
cx: &App,
|
||||||
|
) -> AcceptEditPredictionBinding {
|
||||||
|
let mut context = self.key_context(window, cx);
|
||||||
|
context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||||
|
|
||||||
|
AcceptEditPredictionBinding(
|
||||||
|
window
|
||||||
|
.bindings_for_action_in_context(&AcceptEditPrediction, context)
|
||||||
|
.into_iter()
|
||||||
|
.next(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_file(
|
pub fn new_file(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &workspace::NewFile,
|
_: &workspace::NewFile,
|
||||||
|
@ -5128,8 +5145,7 @@ impl Editor {
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
if self.show_edit_predictions_in_menu() {
|
if self.show_edit_predictions_in_menu() {
|
||||||
let accept_binding =
|
let accept_binding = self.accept_edit_prediction_keybind(window, cx);
|
||||||
AcceptEditPredictionBinding::resolve(self.focus_handle(cx), window);
|
|
||||||
if let Some(accept_keystroke) = accept_binding.keystroke() {
|
if let Some(accept_keystroke) = accept_binding.keystroke() {
|
||||||
let was_previewing_inline_completion = self.previewing_inline_completion;
|
let was_previewing_inline_completion = self.previewing_inline_completion;
|
||||||
self.previewing_inline_completion = modifiers == accept_keystroke.modifiers
|
self.previewing_inline_completion = modifiers == accept_keystroke.modifiers
|
||||||
|
@ -14408,7 +14424,8 @@ impl Editor {
|
||||||
});
|
});
|
||||||
supports
|
supports
|
||||||
}
|
}
|
||||||
pub fn is_focused(&self, window: &mut Window) -> bool {
|
|
||||||
|
pub fn is_focused(&self, window: &Window) -> bool {
|
||||||
self.focus_handle.is_focused(window)
|
self.focus_handle.is_focused(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,12 @@ use gpui::{
|
||||||
anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px, quad,
|
anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px, quad,
|
||||||
relative, size, svg, transparent_black, Action, AnyElement, App, AvailableSpace, Axis, Bounds,
|
relative, size, svg, transparent_black, Action, AnyElement, App, AvailableSpace, Axis, Bounds,
|
||||||
ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase,
|
ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase,
|
||||||
Edges, Element, ElementInputHandler, Entity, FocusHandle, Focusable as _, FontId,
|
Edges, Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox,
|
||||||
GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, KeyBindingContextPredicate,
|
Hsla, InteractiveElement, IntoElement, KeyBindingContextPredicate, Keystroke, Length,
|
||||||
Keystroke, Length, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent,
|
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
|
||||||
MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine,
|
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size,
|
||||||
SharedString, Size, StatefulInteractiveElement, Style, Styled, Subscription, TextRun,
|
StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement,
|
||||||
TextStyleRefinement, WeakEntity, Window,
|
WeakEntity, Window,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
|
@ -3167,10 +3167,8 @@ impl EditorElement {
|
||||||
);
|
);
|
||||||
|
|
||||||
let edit_prediction = if edit_prediction_popover_visible {
|
let edit_prediction = if edit_prediction_popover_visible {
|
||||||
let accept_binding =
|
|
||||||
AcceptEditPredictionBinding::resolve(self.editor.focus_handle(cx), window);
|
|
||||||
|
|
||||||
self.editor.update(cx, move |editor, cx| {
|
self.editor.update(cx, move |editor, cx| {
|
||||||
|
let accept_binding = editor.accept_edit_prediction_keybind(window, cx);
|
||||||
let mut element = editor.render_edit_prediction_cursor_popover(
|
let mut element = editor.render_edit_prediction_cursor_popover(
|
||||||
min_width,
|
min_width,
|
||||||
max_width,
|
max_width,
|
||||||
|
@ -3569,7 +3567,7 @@ impl EditorElement {
|
||||||
"Jump to Edit",
|
"Jump to Edit",
|
||||||
Some(IconName::ArrowUp),
|
Some(IconName::ArrowUp),
|
||||||
previewing,
|
previewing,
|
||||||
self.editor.focus_handle(cx),
|
editor,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)?;
|
)?;
|
||||||
|
@ -3582,7 +3580,7 @@ impl EditorElement {
|
||||||
"Jump to Edit",
|
"Jump to Edit",
|
||||||
Some(IconName::ArrowDown),
|
Some(IconName::ArrowDown),
|
||||||
previewing,
|
previewing,
|
||||||
self.editor.focus_handle(cx),
|
editor,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)?;
|
)?;
|
||||||
|
@ -3598,7 +3596,7 @@ impl EditorElement {
|
||||||
"Jump to Edit",
|
"Jump to Edit",
|
||||||
None,
|
None,
|
||||||
previewing,
|
previewing,
|
||||||
self.editor.focus_handle(cx),
|
editor,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)?;
|
)?;
|
||||||
|
@ -3657,10 +3655,16 @@ impl EditorElement {
|
||||||
target_display_point.row(),
|
target_display_point.row(),
|
||||||
editor_snapshot.line_len(target_display_point.row()),
|
editor_snapshot.line_len(target_display_point.row()),
|
||||||
);
|
);
|
||||||
let (previewing_inline_completion, origin) =
|
let (mut element, origin) = self.editor.update(cx, |editor, cx| {
|
||||||
self.editor.update(cx, |editor, _cx| {
|
|
||||||
Some((
|
Some((
|
||||||
|
inline_completion_accept_indicator(
|
||||||
|
"Accept",
|
||||||
|
None,
|
||||||
editor.previewing_inline_completion,
|
editor.previewing_inline_completion,
|
||||||
|
editor,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)?,
|
||||||
editor.display_to_pixel_point(
|
editor.display_to_pixel_point(
|
||||||
target_line_end,
|
target_line_end,
|
||||||
editor_snapshot,
|
editor_snapshot,
|
||||||
|
@ -3669,15 +3673,6 @@ impl EditorElement {
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut element = inline_completion_accept_indicator(
|
|
||||||
"Accept",
|
|
||||||
None,
|
|
||||||
previewing_inline_completion,
|
|
||||||
self.editor.focus_handle(cx),
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
element.prepaint_as_root(
|
element.prepaint_as_root(
|
||||||
text_bounds.origin + origin + point(PADDING_X, px(0.)),
|
text_bounds.origin + origin + point(PADDING_X, px(0.)),
|
||||||
AvailableSpace::min_size(),
|
AvailableSpace::min_size(),
|
||||||
|
@ -5675,11 +5670,11 @@ fn inline_completion_accept_indicator(
|
||||||
label: impl Into<SharedString>,
|
label: impl Into<SharedString>,
|
||||||
icon: Option<IconName>,
|
icon: Option<IconName>,
|
||||||
previewing: bool,
|
previewing: bool,
|
||||||
editor_focus_handle: FocusHandle,
|
editor: &Editor,
|
||||||
window: &Window,
|
window: &mut Window,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> Option<AnyElement> {
|
) -> Option<AnyElement> {
|
||||||
let accept_binding = AcceptEditPredictionBinding::resolve(editor_focus_handle, window);
|
let accept_binding = editor.accept_edit_prediction_keybind(window, cx);
|
||||||
let accept_keystroke = accept_binding.keystroke()?;
|
let accept_keystroke = accept_binding.keystroke()?;
|
||||||
|
|
||||||
let accept_key = h_flex()
|
let accept_key = h_flex()
|
||||||
|
@ -5728,18 +5723,9 @@ fn inline_completion_accept_indicator(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AcceptEditPredictionBinding(Option<gpui::KeyBinding>);
|
pub struct AcceptEditPredictionBinding(pub(crate) Option<gpui::KeyBinding>);
|
||||||
|
|
||||||
impl AcceptEditPredictionBinding {
|
impl AcceptEditPredictionBinding {
|
||||||
pub fn resolve(editor_focus_handle: FocusHandle, window: &Window) -> Self {
|
|
||||||
AcceptEditPredictionBinding(
|
|
||||||
window
|
|
||||||
.bindings_for_action_in(&AcceptEditPrediction, &editor_focus_handle)
|
|
||||||
.into_iter()
|
|
||||||
.next(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn keystroke(&self) -> Option<&Keystroke> {
|
pub fn keystroke(&self) -> Option<&Keystroke> {
|
||||||
if let Some(binding) = self.0.as_ref() {
|
if let Some(binding) = self.0.as_ref() {
|
||||||
match &binding.keystrokes() {
|
match &binding.keystrokes() {
|
||||||
|
|
|
@ -3671,6 +3671,18 @@ impl Window {
|
||||||
dispatch_tree.bindings_for_action(action, &context_stack)
|
dispatch_tree.bindings_for_action(action, &context_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the key bindings for the given action in the given context.
|
||||||
|
pub fn bindings_for_action_in_context(
|
||||||
|
&self,
|
||||||
|
action: &dyn Action,
|
||||||
|
context: KeyContext,
|
||||||
|
) -> Vec<KeyBinding> {
|
||||||
|
let dispatch_tree = &self.rendered_frame.dispatch_tree;
|
||||||
|
dispatch_tree.bindings_for_action(action, &[context])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
|
||||||
|
|
||||||
/// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
|
/// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
|
||||||
pub fn listener_for<V: Render, E>(
|
pub fn listener_for<V: Render, E>(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue