Reorganize edit prediction code and remove old experiments (#44187)

Release Notes:

- N/A

---------

Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
Max Brunsfeld
2025-12-04 15:56:57 -08:00
committed by GitHub
co-authored by Agus Zubiaga Ben Kunkle
parent 76167109db
commit 42583c1141
113 changed files with 5598 additions and 15080 deletions
+35 -29
View File
@@ -1,4 +1,4 @@
use edit_prediction::EditPredictionProvider;
use edit_prediction_types::EditPredictionDelegate;
use gpui::{Entity, KeyBinding, Modifiers, prelude::*};
use indoc::indoc;
use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint};
@@ -15,7 +15,7 @@ async fn test_edit_prediction_insert(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
assign_editor_completion_provider(provider.clone(), &mut cx);
cx.set_state("let absolute_zero_celsius = ˇ;");
@@ -37,7 +37,7 @@ async fn test_edit_prediction_modification(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
assign_editor_completion_provider(provider.clone(), &mut cx);
cx.set_state("let pi = ˇ\"foo\";");
@@ -59,7 +59,7 @@ async fn test_edit_prediction_jump_button(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
assign_editor_completion_provider(provider.clone(), &mut cx);
// Cursor is 2+ lines above the proposed edit
@@ -128,7 +128,7 @@ async fn test_edit_prediction_invalidation_range(cx: &mut gpui::TestAppContext)
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
assign_editor_completion_provider(provider.clone(), &mut cx);
// Cursor is 3+ lines above the proposed edit
@@ -233,7 +233,7 @@ async fn test_edit_prediction_jump_disabled_for_non_zed_providers(cx: &mut gpui:
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeNonZedEditPredictionProvider::default());
let provider = cx.new(|_| FakeNonZedEditPredictionDelegate::default());
assign_editor_completion_provider_non_zed(provider.clone(), &mut cx);
// Cursor is 2+ lines above the proposed edit
@@ -281,7 +281,7 @@ async fn test_edit_prediction_preview_cleanup_on_toggle_off(cx: &mut gpui::TestA
cx.update(|cx| cx.bind_keys([KeyBinding::new("ctrl-shift-a", AcceptEditPrediction, None)]));
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
assign_editor_completion_provider(provider.clone(), &mut cx);
cx.set_state("let x = ˇ;");
@@ -371,7 +371,7 @@ fn accept_completion(cx: &mut EditorTestContext) {
}
fn propose_edits<T: ToOffset>(
provider: &Entity<FakeEditPredictionProvider>,
provider: &Entity<FakeEditPredictionDelegate>,
edits: Vec<(Range<T>, &str)>,
cx: &mut EditorTestContext,
) {
@@ -383,7 +383,7 @@ fn propose_edits<T: ToOffset>(
cx.update(|_, cx| {
provider.update(cx, |provider, _| {
provider.set_edit_prediction(Some(edit_prediction::EditPrediction::Local {
provider.set_edit_prediction(Some(edit_prediction_types::EditPrediction::Local {
id: None,
edits: edits.collect(),
edit_preview: None,
@@ -393,7 +393,7 @@ fn propose_edits<T: ToOffset>(
}
fn assign_editor_completion_provider(
provider: Entity<FakeEditPredictionProvider>,
provider: Entity<FakeEditPredictionDelegate>,
cx: &mut EditorTestContext,
) {
cx.update_editor(|editor, window, cx| {
@@ -402,7 +402,7 @@ fn assign_editor_completion_provider(
}
fn propose_edits_non_zed<T: ToOffset>(
provider: &Entity<FakeNonZedEditPredictionProvider>,
provider: &Entity<FakeNonZedEditPredictionDelegate>,
edits: Vec<(Range<T>, &str)>,
cx: &mut EditorTestContext,
) {
@@ -414,7 +414,7 @@ fn propose_edits_non_zed<T: ToOffset>(
cx.update(|_, cx| {
provider.update(cx, |provider, _| {
provider.set_edit_prediction(Some(edit_prediction::EditPrediction::Local {
provider.set_edit_prediction(Some(edit_prediction_types::EditPrediction::Local {
id: None,
edits: edits.collect(),
edit_preview: None,
@@ -424,7 +424,7 @@ fn propose_edits_non_zed<T: ToOffset>(
}
fn assign_editor_completion_provider_non_zed(
provider: Entity<FakeNonZedEditPredictionProvider>,
provider: Entity<FakeNonZedEditPredictionDelegate>,
cx: &mut EditorTestContext,
) {
cx.update_editor(|editor, window, cx| {
@@ -433,17 +433,20 @@ fn assign_editor_completion_provider_non_zed(
}
#[derive(Default, Clone)]
pub struct FakeEditPredictionProvider {
pub completion: Option<edit_prediction::EditPrediction>,
pub struct FakeEditPredictionDelegate {
pub completion: Option<edit_prediction_types::EditPrediction>,
}
impl FakeEditPredictionProvider {
pub fn set_edit_prediction(&mut self, completion: Option<edit_prediction::EditPrediction>) {
impl FakeEditPredictionDelegate {
pub fn set_edit_prediction(
&mut self,
completion: Option<edit_prediction_types::EditPrediction>,
) {
self.completion = completion;
}
}
impl EditPredictionProvider for FakeEditPredictionProvider {
impl EditPredictionDelegate for FakeEditPredictionDelegate {
fn name() -> &'static str {
"fake-completion-provider"
}
@@ -452,7 +455,7 @@ impl EditPredictionProvider for FakeEditPredictionProvider {
"Fake Completion Provider"
}
fn show_completions_in_menu() -> bool {
fn show_predictions_in_menu() -> bool {
true
}
@@ -486,7 +489,7 @@ impl EditPredictionProvider for FakeEditPredictionProvider {
&mut self,
_buffer: gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_direction: edit_prediction::Direction,
_direction: edit_prediction_types::Direction,
_cx: &mut gpui::Context<Self>,
) {
}
@@ -500,23 +503,26 @@ impl EditPredictionProvider for FakeEditPredictionProvider {
_buffer: &gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_cx: &mut gpui::Context<Self>,
) -> Option<edit_prediction::EditPrediction> {
) -> Option<edit_prediction_types::EditPrediction> {
self.completion.clone()
}
}
#[derive(Default, Clone)]
pub struct FakeNonZedEditPredictionProvider {
pub completion: Option<edit_prediction::EditPrediction>,
pub struct FakeNonZedEditPredictionDelegate {
pub completion: Option<edit_prediction_types::EditPrediction>,
}
impl FakeNonZedEditPredictionProvider {
pub fn set_edit_prediction(&mut self, completion: Option<edit_prediction::EditPrediction>) {
impl FakeNonZedEditPredictionDelegate {
pub fn set_edit_prediction(
&mut self,
completion: Option<edit_prediction_types::EditPrediction>,
) {
self.completion = completion;
}
}
impl EditPredictionProvider for FakeNonZedEditPredictionProvider {
impl EditPredictionDelegate for FakeNonZedEditPredictionDelegate {
fn name() -> &'static str {
"fake-non-zed-provider"
}
@@ -525,7 +531,7 @@ impl EditPredictionProvider for FakeNonZedEditPredictionProvider {
"Fake Non-Zed Provider"
}
fn show_completions_in_menu() -> bool {
fn show_predictions_in_menu() -> bool {
false
}
@@ -559,7 +565,7 @@ impl EditPredictionProvider for FakeNonZedEditPredictionProvider {
&mut self,
_buffer: gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_direction: edit_prediction::Direction,
_direction: edit_prediction_types::Direction,
_cx: &mut gpui::Context<Self>,
) {
}
@@ -573,7 +579,7 @@ impl EditPredictionProvider for FakeNonZedEditPredictionProvider {
_buffer: &gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_cx: &mut gpui::Context<Self>,
) -> Option<edit_prediction::EditPrediction> {
) -> Option<edit_prediction_types::EditPrediction> {
self.completion.clone()
}
}
+12 -12
View File
@@ -51,7 +51,7 @@ pub mod test;
pub(crate) use actions::*;
pub use display_map::{ChunkRenderer, ChunkRendererContext, DisplayPoint, FoldPlaceholder};
pub use edit_prediction::Direction;
pub use edit_prediction_types::Direction;
pub use editor_settings::{
CurrentLineHighlight, DocumentColorsRenderMode, EditorSettings, HideMouseMode,
ScrollBeyondLastLine, ScrollbarAxes, SearchSettings, ShowMinimap,
@@ -92,7 +92,7 @@ use collections::{BTreeMap, HashMap, HashSet, VecDeque};
use convert_case::{Case, Casing};
use dap::TelemetrySpawnLocation;
use display_map::*;
use edit_prediction::{EditPredictionProvider, EditPredictionProviderHandle};
use edit_prediction_types::{EditPredictionDelegate, EditPredictionDelegateHandle};
use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings};
use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap, layout_line};
use futures::{
@@ -1120,7 +1120,7 @@ pub struct Editor {
pending_mouse_down: Option<Rc<RefCell<Option<MouseDownEvent>>>>,
gutter_hovered: bool,
hovered_link_state: Option<HoveredLinkState>,
edit_prediction_provider: Option<RegisteredEditPredictionProvider>,
edit_prediction_provider: Option<RegisteredEditPredictionDelegate>,
code_action_providers: Vec<Rc<dyn CodeActionProvider>>,
active_edit_prediction: Option<EditPredictionState>,
/// Used to prevent flickering as the user types while the menu is open
@@ -1562,8 +1562,8 @@ pub struct RenameState {
struct InvalidationStack<T>(Vec<T>);
struct RegisteredEditPredictionProvider {
provider: Arc<dyn EditPredictionProviderHandle>,
struct RegisteredEditPredictionDelegate {
provider: Arc<dyn EditPredictionDelegateHandle>,
_subscription: Subscription,
}
@@ -2988,9 +2988,9 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) where
T: EditPredictionProvider,
T: EditPredictionDelegate,
{
self.edit_prediction_provider = provider.map(|provider| RegisteredEditPredictionProvider {
self.edit_prediction_provider = provider.map(|provider| RegisteredEditPredictionDelegate {
_subscription: cx.observe_in(&provider, window, |this, _, window, cx| {
if this.focus_handle.is_focused(window) {
this.update_visible_edit_prediction(window, cx);
@@ -7394,7 +7394,7 @@ impl Editor {
&& self
.edit_prediction_provider
.as_ref()
.is_some_and(|provider| provider.provider.show_completions_in_menu());
.is_some_and(|provider| provider.provider.show_predictions_in_menu());
let preview_requires_modifier =
all_language_settings(file, cx).edit_predictions_mode() == EditPredictionsMode::Subtle;
@@ -8095,12 +8095,12 @@ impl Editor {
let edit_prediction = provider.suggest(&buffer, cursor_buffer_position, cx)?;
let (completion_id, edits, edit_preview) = match edit_prediction {
edit_prediction::EditPrediction::Local {
edit_prediction_types::EditPrediction::Local {
id,
edits,
edit_preview,
} => (id, edits, edit_preview),
edit_prediction::EditPrediction::Jump {
edit_prediction_types::EditPrediction::Jump {
id,
snapshot,
target,
@@ -8241,7 +8241,7 @@ impl Editor {
Some(())
}
pub fn edit_prediction_provider(&self) -> Option<Arc<dyn EditPredictionProviderHandle>> {
pub fn edit_prediction_provider(&self) -> Option<Arc<dyn EditPredictionDelegateHandle>> {
Some(self.edit_prediction_provider.as_ref()?.provider.clone())
}
@@ -9563,7 +9563,7 @@ impl Editor {
editor_bg_color.blend(accent_color.opacity(0.6))
}
fn get_prediction_provider_icon_name(
provider: &Option<RegisteredEditPredictionProvider>,
provider: &Option<RegisteredEditPredictionDelegate>,
) -> IconName {
match provider {
Some(provider) => match provider.provider.name() {
+3 -3
View File
@@ -2,7 +2,7 @@ use super::*;
use crate::{
JoinLines,
code_context_menus::CodeContextMenu,
edit_prediction_tests::FakeEditPredictionProvider,
edit_prediction_tests::FakeEditPredictionDelegate,
element::StickyHeader,
linked_editing_ranges::LinkedEditingRanges,
scroll::scroll_amount::ScrollAmount,
@@ -8636,7 +8636,7 @@ async fn test_undo_edit_prediction_scrolls_to_edit_pos(cx: &mut TestAppContext)
let mut cx = EditorTestContext::new(cx).await;
let provider = cx.new(|_| FakeEditPredictionProvider::default());
let provider = cx.new(|_| FakeEditPredictionDelegate::default());
cx.update_editor(|editor, window, cx| {
editor.set_edit_prediction_provider(Some(provider.clone()), window, cx);
});
@@ -8659,7 +8659,7 @@ async fn test_undo_edit_prediction_scrolls_to_edit_pos(cx: &mut TestAppContext)
cx.update(|_, cx| {
provider.update(cx, |provider, _| {
provider.set_edit_prediction(Some(edit_prediction::EditPrediction::Local {
provider.set_edit_prediction(Some(edit_prediction_types::EditPrediction::Local {
id: None,
edits: vec![(edit_position..edit_position, "X".into())],
edit_preview: None,