ep: Improve trigger granularity (#58561)

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #ISSUE

Release Notes:

- N/A or Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle authored and GitHub committed 2026-06-04 22:52:29 +00:00
1 parent 252b52e83f
commit acdef5d09b
15 files changed
+457 -73

No files matched your search

@@ -122,7 +122,13 @@ pub struct PredictEditsBody {
pub enum PredictEditsRequestTrigger {
Testing,
Diagnostics,
DiagnosticNavigation,
Cli,
Explicit,
BufferEdit,
LSPCompletionAccepted,
PredictionAccepted,
PredictionPartiallyAccepted,
#[default]
Other,
}
+2
View File
@@ -2,6 +2,7 @@ use anyhow::Result;
use edit_prediction::cursor_excerpt;
use edit_prediction_types::{
EditPrediction, EditPredictionDelegate, EditPredictionDiscardReason, EditPredictionIconSet,
EditPredictionRequestTrigger,
};
use futures::AsyncReadExt;
use gpui::{App, AppContext as _, Context, Entity, Global, SharedString, Task};
@@ -222,6 +223,7 @@ impl EditPredictionDelegate for CodestralEditPredictionDelegate {
buffer: Entity<Buffer>,
cursor_position: language::Anchor,
debounce: bool,
_trigger: EditPredictionRequestTrigger,
cx: &mut Context<Self>,
) {
log::debug!("Codestral: Refresh called (debounce: {})", debounce);
@@ -8,7 +8,7 @@ use crate::{
use anyhow::Result;
use edit_prediction_types::{
EditPrediction, EditPredictionDelegate, EditPredictionDiscardReason, EditPredictionIconSet,
interpolate_edits,
EditPredictionRequestTrigger, interpolate_edits,
};
use gpui::{App, Context, Entity, Task, TaskExt};
use icons::IconName;
@@ -78,6 +78,7 @@ impl EditPredictionDelegate for CopilotEditPredictionDelegate {
buffer: Entity<Buffer>,
cursor_position: language::Anchor,
debounce: bool,
_trigger: EditPredictionRequestTrigger,
cx: &mut Context<Self>,
) {
let copilot = self.copilot.clone();
@@ -1041,7 +1042,13 @@ mod tests {
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |selections| {
selections.select_ranges([Point::new(0, 0)..Point::new(0, 0)])
});
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
@@ -1051,7 +1058,13 @@ mod tests {
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
s.select_ranges([Point::new(5, 0)..Point::new(5, 0)])
});
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
+45 -11
View File
@@ -22,6 +22,7 @@ use copilot::{Copilot, Reinstall, SignIn, SignOut};
use credentials_provider::CredentialsProvider;
use db::kvp::{Dismissable, KeyValueStore};
use edit_prediction_context::{RelatedExcerptStore, RelatedExcerptStoreEvent, RelatedFile};
use edit_prediction_types::EditPredictionRequestTrigger;
use feature_flags::{FeatureFlag, FeatureFlagAppExt as _, PresenceFlag, register_feature_flag};
use futures::{
AsyncReadExt as _, FutureExt as _, StreamExt as _,
@@ -842,6 +843,28 @@ pub(crate) fn buffer_path_with_id_fallback(
}
}
fn predict_edits_request_trigger_from_editor_trigger(
trigger: EditPredictionRequestTrigger,
) -> PredictEditsRequestTrigger {
match trigger {
EditPredictionRequestTrigger::DiagnosticNavigation => {
PredictEditsRequestTrigger::DiagnosticNavigation
}
EditPredictionRequestTrigger::Explicit => PredictEditsRequestTrigger::Explicit,
EditPredictionRequestTrigger::BufferEdit => PredictEditsRequestTrigger::BufferEdit,
EditPredictionRequestTrigger::LSPCompletionAccepted => {
PredictEditsRequestTrigger::LSPCompletionAccepted
}
EditPredictionRequestTrigger::PredictionAccepted => {
PredictEditsRequestTrigger::PredictionAccepted
}
EditPredictionRequestTrigger::PredictionPartiallyAccepted => {
PredictEditsRequestTrigger::PredictionPartiallyAccepted
}
EditPredictionRequestTrigger::Other => PredictEditsRequestTrigger::Other,
}
}
impl EditPredictionStore {
pub fn try_global(cx: &App) -> Option<Entity<Self>> {
cx.try_global::<EditPredictionStoreGlobal>()
@@ -2215,21 +2238,25 @@ impl EditPredictionStore {
project: Entity<Project>,
buffer: Entity<Buffer>,
position: language::Anchor,
trigger: EditPredictionRequestTrigger,
cx: &mut Context<Self>,
) {
let trigger = predict_edits_request_trigger_from_editor_trigger(trigger);
self.queue_prediction_refresh(
project.clone(),
PredictEditsRequestTrigger::Other,
trigger,
buffer.entity_id(),
cx,
move |this, cx| {
let Some(request_task) = this
.update(cx, |this, cx| {
this.request_prediction(
&project,
&buffer,
this.request_prediction_internal(
project.clone(),
buffer.clone(),
position,
PredictEditsRequestTrigger::Other,
trigger,
cx.has_flag::<EditPredictionJumpsFeatureFlag>(),
cx,
)
})
@@ -2333,11 +2360,12 @@ impl EditPredictionStore {
let Some(prediction_result) = this
.update(cx, |this, cx| {
this.request_prediction(
&project,
&jump_buffer,
this.request_prediction_internal(
project.clone(),
jump_buffer.clone(),
jump_position,
PredictEditsRequestTrigger::Diagnostics,
cx.has_flag::<EditPredictionJumpsFeatureFlag>(),
cx,
)
})?
@@ -2454,7 +2482,8 @@ impl EditPredictionStore {
request_trigger: PredictEditsRequestTrigger,
) -> &mut Option<(EntityId, Instant)> {
match request_trigger {
PredictEditsRequestTrigger::Diagnostics => {
PredictEditsRequestTrigger::Diagnostics
| PredictEditsRequestTrigger::DiagnosticNavigation => {
&mut project_state.last_jump_prediction_refresh
}
_ => &mut project_state.last_edit_prediction_refresh,
@@ -2769,7 +2798,8 @@ impl EditPredictionStore {
inputs.snapshot.clone(),
inputs.position,
match trigger {
PredictEditsRequestTrigger::Diagnostics => {
PredictEditsRequestTrigger::Diagnostics
| PredictEditsRequestTrigger::DiagnosticNavigation => {
JumpExampleTrigger::Diagnostic
}
_ => JumpExampleTrigger::Prediction,
@@ -2802,7 +2832,11 @@ impl EditPredictionStore {
if prediction.is_none()
&& allow_jump
&& has_events
&& !matches!(trigger, PredictEditsRequestTrigger::Diagnostics)
&& !matches!(
trigger,
PredictEditsRequestTrigger::Diagnostics
| PredictEditsRequestTrigger::DiagnosticNavigation
)
{
this.update(cx, |this, cx| {
this.refresh_prediction_from_diagnostics(
@@ -9,10 +9,12 @@ use cloud_api_types::{
SubmitEditPredictionSettledResponse,
};
use cloud_llm_client::{
EditPredictionRejectReason, EditPredictionRejection, RejectEditPredictionsBody,
EditPredictionRejectReason, EditPredictionRejection, PredictEditsRequestTrigger,
RejectEditPredictionsBody,
predict_edits_v3::{PredictEditsV3Request, PredictEditsV3Response},
};
use db::AppDatabase;
use edit_prediction_types::EditPredictionRequestTrigger;
use settings::EditPredictionDataCollectionChoice;
use futures::{
@@ -84,7 +86,13 @@ async fn test_current_state(cx: &mut TestAppContext) {
// Prediction for current file
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer1.clone(), position, cx)
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer1.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
)
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -239,7 +247,13 @@ async fn test_diagnostics_refresh_suppressed_while_following(cx: &mut TestAppCon
ep_store.update(cx, |ep_store, cx| {
ep_store.register_project(&project, cx);
ep_store.register_buffer(&buffer1, &project, cx);
ep_store.refresh_prediction_from_buffer(project.clone(), buffer1.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer1.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -441,7 +455,13 @@ async fn test_simple_request(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
let prediction_task = ep_store.update(cx, |ep_store, cx| {
ep_store.request_prediction(&project, &buffer, position, Default::default(), cx)
ep_store.request_prediction(
&project,
&buffer,
position,
PredictEditsRequestTrigger::Other,
cx,
)
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -517,7 +537,13 @@ async fn test_request_events(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
let prediction_task = ep_store.update(cx, |ep_store, cx| {
ep_store.request_prediction(&project, &buffer, position, Default::default(), cx)
ep_store.request_prediction(
&project,
&buffer,
position,
PredictEditsRequestTrigger::Other,
cx,
)
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1441,7 +1467,13 @@ async fn test_empty_prediction(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1499,7 +1531,13 @@ async fn test_interpolated_empty(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1572,7 +1610,13 @@ async fn test_replace_current(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1595,7 +1639,13 @@ async fn test_replace_current(cx: &mut TestAppContext) {
// a second request is triggered
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1656,7 +1706,13 @@ async fn test_current_preferred(cx: &mut TestAppContext) {
let position = snapshot.anchor_before(language::Point::new(1, 3));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1679,7 +1735,13 @@ async fn test_current_preferred(cx: &mut TestAppContext) {
// a second request is triggered
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -1754,13 +1816,25 @@ async fn test_cancel_earlier_pending_requests(cx: &mut TestAppContext) {
// start two refresh tasks
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request1, respond_first) = requests.predict.next().await.unwrap();
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_second) = requests.predict.next().await.unwrap();
@@ -1848,13 +1922,25 @@ async fn test_cancel_second_on_third_request(cx: &mut TestAppContext) {
// start two refresh tasks
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request1, respond_first) = requests.predict.next().await.unwrap();
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request2, respond_second) = requests.predict.next().await.unwrap();
@@ -1864,7 +1950,13 @@ async fn test_cancel_second_on_third_request(cx: &mut TestAppContext) {
ep_store.update(cx, |ep_store, cx| {
// start a third request
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
// 2 are pending, so 2nd is cancelled
assert_eq!(
@@ -1999,7 +2091,13 @@ async fn test_jump_and_edit_throttles_are_independent(cx: &mut TestAppContext) {
// First edit request - no prior edit, so not throttled.
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (_edit_request, edit_response_tx) = requests.predict.next().await.unwrap();
edit_response_tx.send(empty_response()).unwrap();
@@ -2037,7 +2135,13 @@ async fn test_jump_and_edit_throttles_are_independent(cx: &mut TestAppContext) {
// Second edit request - should be throttled by the first edit.
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
assert_no_predict_request_ready(&mut requests.predict);
@@ -2096,14 +2200,26 @@ async fn test_cloud_timeout_backs_off_zeta_requests(cx: &mut TestAppContext) {
});
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (_request, respond_tx) = requests.predict.next().await.unwrap();
respond_tx.send(request_timeout_response()).unwrap();
cx.run_until_parked();
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
cx.background_executor
.advance_clock(EditPredictionStore::THROTTLE_TIMEOUT);
@@ -2117,7 +2233,13 @@ async fn test_cloud_timeout_backs_off_zeta_requests(cx: &mut TestAppContext) {
cx.run_until_parked();
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (_request, respond_tx) = requests.predict.next().await.unwrap();
respond_tx.send(empty_response()).unwrap();
@@ -2152,8 +2274,20 @@ async fn test_same_frame_duplicate_requests_deduplicated(cx: &mut TestAppContext
// capture the same `proceed_count_at_enqueue`. Only the first task should
// pass the deduplication gate; the second should be skipped.
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
// Let both spawned tasks run to completion (including any throttle waits).
@@ -3013,7 +3147,13 @@ async fn test_edit_prediction_no_spurious_trailing_newline(cx: &mut TestAppConte
let position = snapshot.anchor_before(language::Point::new(0, 5));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -3077,7 +3217,13 @@ async fn test_v3_prediction_strips_cursor_marker_from_edit_text(cx: &mut TestApp
let position = snapshot.anchor_before(language::Point::new(0, 5));
ep_store.update(cx, |ep_store, cx| {
ep_store.refresh_prediction_from_buffer(project.clone(), buffer.clone(), position, cx);
ep_store.refresh_prediction_from_buffer(
project.clone(),
buffer.clone(),
position,
EditPredictionRequestTrigger::Other,
cx,
);
});
let (request, respond_tx) = requests.predict.next().await.unwrap();
@@ -3146,7 +3292,13 @@ async fn run_edit_prediction(
});
cx.background_executor.run_until_parked();
let prediction_task = ep_store.update(cx, |ep_store, cx| {
ep_store.request_prediction(&project, buffer, cursor, Default::default(), cx)
ep_store.request_prediction(
&project,
buffer,
cursor,
PredictEditsRequestTrigger::Other,
cx,
)
});
prediction_task.await.unwrap().unwrap().prediction.unwrap()
}
@@ -3326,7 +3478,13 @@ async fn test_unauthenticated_without_custom_url_blocks_prediction_impl(cx: &mut
let completion_task = ep_store.update(cx, |ep_store, cx| {
ep_store.set_edit_prediction_model(EditPredictionModel::Zeta);
ep_store.request_prediction(&project, &buffer, cursor, Default::default(), cx)
ep_store.request_prediction(
&project,
&buffer,
cursor,
PredictEditsRequestTrigger::Other,
cx,
)
});
assert!(completion_task.await.unwrap().is_none());
@@ -4,7 +4,7 @@ use client::{Client, UserStore};
use cloud_llm_client::EditPredictionRejectReason;
use edit_prediction_types::{
DataCollectionState, EditPredictionDelegate, EditPredictionDiscardReason,
EditPredictionIconSet, SuggestionDisplayType,
EditPredictionIconSet, EditPredictionRequestTrigger, SuggestionDisplayType,
};
use feature_flags::FeatureFlagAppExt;
use fs::Fs;
@@ -143,6 +143,7 @@ impl EditPredictionDelegate for ZedEditPredictionDelegate {
buffer: Entity<language::Buffer>,
cursor_position: language::Anchor,
_debounce: bool,
trigger: EditPredictionRequestTrigger,
cx: &mut Context<Self>,
) {
let store = self.store.read(cx);
@@ -163,7 +164,13 @@ impl EditPredictionDelegate for ZedEditPredictionDelegate {
}
store.refresh_context(&self.project, &buffer, cursor_position, cx);
store.refresh_prediction_from_buffer(self.project.clone(), buffer, cursor_position, cx)
store.refresh_prediction_from_buffer(
self.project.clone(),
buffer,
cursor_position,
trigger,
cx,
)
});
}
@@ -8,6 +8,19 @@ pub enum EditPredictionDiscardReason {
Rejected,
Ignored,
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum EditPredictionRequestTrigger {
DiagnosticNavigation,
Explicit,
BufferEdit,
LSPCompletionAccepted,
PredictionAccepted,
PredictionPartiallyAccepted,
#[default]
Other,
}
use icons::IconName;
use language::{Anchor, Buffer, OffsetRangeExt};
@@ -185,6 +198,7 @@ pub trait EditPredictionDelegate: 'static + Sized {
buffer: Entity<Buffer>,
cursor_position: language::Anchor,
debounce: bool,
trigger: EditPredictionRequestTrigger,
cx: &mut Context<Self>,
);
fn accept(&mut self, cx: &mut Context<Self>);
@@ -221,6 +235,7 @@ pub trait EditPredictionDelegateHandle {
buffer: Entity<Buffer>,
cursor_position: language::Anchor,
debounce: bool,
trigger: EditPredictionRequestTrigger,
cx: &mut App,
);
fn did_show(&self, display_type: SuggestionDisplayType, cx: &mut App);
@@ -296,10 +311,11 @@ where
buffer: Entity<Buffer>,
cursor_position: language::Anchor,
debounce: bool,
trigger: EditPredictionRequestTrigger,
cx: &mut App,
) {
self.update(cx, |this, cx| {
this.refresh(buffer, cursor_position, debounce, cx)
this.refresh(buffer, cursor_position, debounce, trigger, cx)
})
}
+7 -1
View File
@@ -910,7 +910,13 @@ impl Editor {
});
}
linked_edits.apply(cx);
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::LSPCompletionAccepted,
window,
cx,
);
});
self.invalidate_autoclose_regions(
&self.selections.disjoint_anchors_arc(),
+7 -1
View File
@@ -191,7 +191,13 @@ impl Editor {
s.select_ranges(vec![diagnostic.range.start..diagnostic.range.start])
});
self.activate_diagnostics(buffer_id, diagnostic, window, cx);
self.refresh_edit_prediction(false, true, window, cx);
self.refresh_edit_prediction(
false,
true,
EditPredictionRequestTrigger::DiagnosticNavigation,
window,
cx,
);
}
pub fn go_to_diagnostic_in_direction(
+50 -8
View File
@@ -166,7 +166,13 @@ impl Editor {
provider: Arc::new(provider),
});
self.update_edit_prediction_settings(cx);
self.refresh_edit_prediction(false, false, window, cx);
self.refresh_edit_prediction(
false,
false,
EditPredictionRequestTrigger::Other,
window,
cx,
);
}
pub fn set_edit_predictions_hidden_for_vim_mode(
@@ -180,7 +186,13 @@ impl Editor {
if hidden {
self.update_visible_edit_prediction(window, cx);
} else {
self.refresh_edit_prediction(true, false, window, cx);
self.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::Other,
window,
cx,
);
}
}
}
@@ -211,7 +223,13 @@ impl Editor {
if let Some(false) = show_edit_predictions {
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
} else {
self.refresh_edit_prediction(false, true, window, cx);
self.refresh_edit_prediction(
false,
true,
EditPredictionRequestTrigger::Explicit,
window,
cx,
);
}
}
@@ -219,6 +237,7 @@ impl Editor {
&mut self,
debounce: bool,
user_requested: bool,
trigger: EditPredictionRequestTrigger,
window: &mut Window,
cx: &mut Context<Self>,
) -> Option<()> {
@@ -251,8 +270,13 @@ impl Editor {
return None;
}
self.edit_prediction_provider()?
.refresh(buffer, cursor_buffer_position, debounce, cx);
self.edit_prediction_provider()?.refresh(
buffer,
cursor_buffer_position,
debounce,
trigger,
cx,
);
Some(())
}
@@ -311,7 +335,13 @@ impl Editor {
cx: &mut Context<Self>,
) {
if !self.has_active_edit_prediction() {
self.refresh_edit_prediction(false, true, window, cx);
self.refresh_edit_prediction(
false,
true,
EditPredictionRequestTrigger::Explicit,
window,
cx,
);
return;
}
@@ -457,7 +487,13 @@ impl Editor {
self.update_visible_edit_prediction(window, cx);
if self.active_edit_prediction.is_none() {
self.refresh_edit_prediction(true, true, window, cx);
self.refresh_edit_prediction(
true,
true,
EditPredictionRequestTrigger::PredictionAccepted,
window,
cx,
);
}
cx.notify();
}
@@ -510,7 +546,13 @@ impl Editor {
});
self.replace_selections(&text_to_insert, None, window, cx, false);
self.refresh_edit_prediction(true, true, window, cx);
self.refresh_edit_prediction(
true,
true,
EditPredictionRequestTrigger::PredictionPartiallyAccepted,
window,
cx,
);
cx.notify();
} else {
self.accept_partial_edit_prediction(
+25 -4
View File
@@ -1,5 +1,6 @@
use edit_prediction_types::{
EditPredictionDelegate, EditPredictionIconSet, PredictedCursorPosition,
EditPredictionDelegate, EditPredictionIconSet, EditPredictionRequestTrigger,
PredictedCursorPosition,
};
use futures::StreamExt;
use gpui::{
@@ -532,7 +533,13 @@ async fn test_edit_prediction_refresh_suppressed_while_following(cx: &mut gpui::
propose_edits(&provider, vec![(8..8, "42")], &mut cx);
cx.update_editor(|editor, window, cx| {
editor.refresh_edit_prediction(false, false, window, cx);
editor.refresh_edit_prediction(
false,
false,
EditPredictionRequestTrigger::Other,
window,
cx,
);
editor.update_visible_edit_prediction(window, cx);
});
@@ -548,7 +555,13 @@ async fn test_edit_prediction_refresh_suppressed_while_following(cx: &mut gpui::
cx.update_editor(|editor, window, cx| {
editor.leader_id = Some(CollaboratorId::PeerId(PeerId::default()));
editor.refresh_edit_prediction(false, false, window, cx);
editor.refresh_edit_prediction(
false,
false,
EditPredictionRequestTrigger::Other,
window,
cx,
);
});
assert_eq!(
@@ -563,7 +576,13 @@ async fn test_edit_prediction_refresh_suppressed_while_following(cx: &mut gpui::
cx.update_editor(|editor, window, cx| {
editor.leader_id = None;
editor.refresh_edit_prediction(false, false, window, cx);
editor.refresh_edit_prediction(
false,
false,
EditPredictionRequestTrigger::Other,
window,
cx,
);
});
assert_eq!(
@@ -1763,6 +1782,7 @@ impl EditPredictionDelegate for FakeEditPredictionDelegate {
_buffer: gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_debounce: bool,
_trigger: edit_prediction_types::EditPredictionRequestTrigger,
_cx: &mut gpui::Context<Self>,
) {
self.refresh_count.fetch_add(1, atomic::Ordering::SeqCst);
@@ -1841,6 +1861,7 @@ impl EditPredictionDelegate for FakeNonZedEditPredictionDelegate {
_buffer: gpui::Entity<language::Buffer>,
_cursor_position: language::Anchor,
_debounce: bool,
_trigger: edit_prediction_types::EditPredictionRequestTrigger,
_cx: &mut gpui::Context<Self>,
) {
}
+44 -7
View File
@@ -93,6 +93,7 @@ pub(crate) use edit_prediction::{
EditPredictionKeybindAction, EditPredictionKeybindSurface, edit_prediction_edit_text,
};
pub use edit_prediction_types::Direction;
pub use edit_prediction_types::EditPredictionRequestTrigger;
pub use editor_settings::{
CompletionDetailAlignment, CompletionMenuItemKind, CurrentLineHighlight, DiffViewStyle,
DocumentColorsRenderMode, EditorSettings, EditorSettingsScrollbarProxy, ScrollBeyondLastLine,
@@ -4807,7 +4808,13 @@ impl Editor {
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
this.insert("", window, cx);
linked_edits.apply_with_left_expansion(cx);
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
refresh_linked_ranges(this, window, cx);
});
}
@@ -4830,7 +4837,13 @@ impl Editor {
let linked_edits = this.linked_edits_for_selections(Arc::from(""), cx);
this.insert("", window, cx);
linked_edits.apply(cx);
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
refresh_linked_ranges(this, window, cx);
});
}
@@ -5015,7 +5028,13 @@ impl Editor {
self.transact(window, cx, |this, window, cx| {
this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
}
@@ -7326,7 +7345,13 @@ impl Editor {
}
self.request_autoscroll(Autoscroll::fit(), cx);
self.unmark_text(window, cx);
self.refresh_edit_prediction(true, false, window, cx);
self.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
cx.emit(EditorEvent::Edited { transaction_id });
cx.emit(EditorEvent::TransactionUndone { transaction_id });
}
@@ -7354,7 +7379,13 @@ impl Editor {
}
self.request_autoscroll(Autoscroll::fit(), cx);
self.unmark_text(window, cx);
self.refresh_edit_prediction(true, false, window, cx);
self.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
cx.emit(EditorEvent::Edited { transaction_id });
}
}
@@ -8472,7 +8503,13 @@ impl Editor {
(selection.range(), uuid.to_string())
});
this.edit(edits, cx);
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
}
@@ -9491,7 +9528,7 @@ impl Editor {
}
self.refresh_runnables(None, window, cx);
self.update_edit_prediction_settings(cx);
self.refresh_edit_prediction(true, false, window, cx);
self.refresh_edit_prediction(true, false, EditPredictionRequestTrigger::Other, window, cx);
self.refresh_inline_values(cx);
let old_cursor_shape = self.cursor_shape;
+14 -2
View File
@@ -523,7 +523,13 @@ impl Editor {
}
this.trigger_completion_on_input(&text, trigger_in_words, window, cx);
refresh_linked_ranges(this, window, cx);
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
jsx_tag_auto_close::handle_from(this, initial_buffer_versions, window, cx);
});
}
@@ -759,7 +765,13 @@ impl Editor {
.collect();
this.change_selections(Default::default(), window, cx, |s| s.select(new_selections));
this.refresh_edit_prediction(true, false, window, cx);
this.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
if let Some(task) = this.trigger_on_type_formatting("\n".to_owned(), window, cx) {
task.detach_and_log_err(cx);
}
+15 -3
View File
@@ -5,7 +5,7 @@ use crate::{
state::Mode,
};
use editor::{
Bias, DisplayPoint,
Bias, DisplayPoint, EditPredictionRequestTrigger,
display_map::{DisplaySnapshot, ToDisplayPoint},
movement::TextLayoutDetails,
};
@@ -90,7 +90,13 @@ impl Vim {
if let Some(kind) = motion_kind {
vim.copy_selections_content(editor, kind, window, cx);
editor.delete_selections_with_linked_edits(window, cx);
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
}
});
});
@@ -127,7 +133,13 @@ impl Vim {
};
vim.copy_selections_content(editor, kind, window, cx);
editor.delete_selections_with_linked_edits(window, cx);
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
}
});
});
+15 -3
View File
@@ -6,7 +6,7 @@ use crate::{
};
use collections::{HashMap, HashSet};
use editor::{
Bias, DisplayPoint,
Bias, DisplayPoint, EditPredictionRequestTrigger,
display_map::{DisplaySnapshot, ToDisplayPoint},
};
use gpui::{Context, Window};
@@ -84,7 +84,13 @@ impl Vim {
selection.collapse_to(cursor, selection.goal)
});
});
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
});
}
@@ -192,7 +198,13 @@ impl Vim {
selection.collapse_to(cursor, selection.goal)
});
});
editor.refresh_edit_prediction(true, false, window, cx);
editor.refresh_edit_prediction(
true,
false,
EditPredictionRequestTrigger::BufferEdit,
window,
cx,
);
});
});
}