Make edit prediction bindings backwards compatible with existing user keymaps (#24802)

Release Notes:

- N/A

---------

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Agus Zubiaga
2025-02-13 14:22:08 +00:00
committed by GitHub
co-authored by Antonio
parent d57f5937d4
commit c3afeda80b
8 changed files with 185 additions and 106 deletions
+10 -55
View File
@@ -15,14 +15,13 @@ use crate::{
items::BufferSearchHighlights,
mouse_context_menu::{self, MenuPosition, MouseContextMenu},
scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair},
AcceptEditPrediction, BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint,
DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint, DisplayRow,
DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk,
GoToPrevHunk, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor,
InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point,
RevertSelectedHunks, RowExt, RowRangeExt, SelectPhase, Selection, SoftWrap,
StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR,
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT, FILE_HEADER_HEIGHT,
StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT,
GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
};
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus};
@@ -35,11 +34,11 @@ use gpui::{
point, px, quad, relative, size, svg, transparent_black, Action, AnyElement, App,
AvailableSpace, Axis, Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners,
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _,
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement,
KeyBindingContextPredicate, Keystroke, Length, ModifiersChangedEvent, MouseButton,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled,
Subscription, TextRun, TextStyleRefinement, WeakEntity, Window,
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length,
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size,
StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement,
WeakEntity, Window,
};
use itertools::Itertools;
use language::{
@@ -55,7 +54,7 @@ use multi_buffer::{
RowInfo, ToOffset,
};
use project::project_settings::{GitGutterSetting, ProjectSettings};
use settings::{KeyBindingValidator, KeyBindingValidatorRegistration, Settings};
use settings::Settings;
use smallvec::{smallvec, SmallVec};
use std::{
any::TypeId,
@@ -75,7 +74,7 @@ use ui::{
POPOVER_Y_PADDING,
};
use unicode_segmentation::UnicodeSegmentation;
use util::{markdown::MarkdownString, RangeExt, ResultExt};
use util::{RangeExt, ResultExt};
use workspace::{item::Item, notifications::NotifyTaskExt, Workspace};
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
@@ -5834,50 +5833,6 @@ impl AcceptEditPredictionBinding {
}
}
struct AcceptEditPredictionsBindingValidator;
inventory::submit! { KeyBindingValidatorRegistration(|| Box::new(AcceptEditPredictionsBindingValidator)) }
impl KeyBindingValidator for AcceptEditPredictionsBindingValidator {
fn action_type_id(&self) -> TypeId {
TypeId::of::<AcceptEditPrediction>()
}
fn validate(&self, binding: &gpui::KeyBinding) -> Result<(), MarkdownString> {
use KeyBindingContextPredicate::*;
if binding.keystrokes().len() == 1 && binding.keystrokes()[0].modifiers.modified() {
return Ok(());
}
let required_predicate =
Not(Identifier(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT.into()).into());
match binding.predicate() {
Some(predicate) if required_predicate.is_superset(&predicate) => {
return Ok(());
}
_ => {}
}
let negated_requires_modifier_key_context = MarkdownString::inline_code(&format!(
"!{}",
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT
));
Err(MarkdownString(format!(
"{} can only be bound to a single keystroke with modifiers, so \
that pressing these modifiers can be used for prediction \
preview.\n\n\
This restriction does not apply when the context requires {}, \
since these bindings are not used for prediction preview. For \
example, in the default keymap `tab` requires {}, and `alt-tab` \
is used otherwise.\n\n\
See [the documentation]({}) for more details.",
MarkdownString::inline_code(AcceptEditPrediction.name()),
negated_requires_modifier_key_context.clone(),
negated_requires_modifier_key_context,
"https://zed.dev/docs/completions#edit-predictions",
)))
}
}
#[allow(clippy::too_many_arguments)]
fn prepaint_gutter_button(
button: IconButton,