completions: Add subtle/eager behavior to Supermaven and Copilot (#35548)
This pull request introduces changes to improve the behavior and consistency of multiple completion providers (`CopilotCompletionProvider`, `SupermavenCompletionProvider`) and their integration with UI elements like menus and inline completion buttons. It now allows to see the prediction with the completion menu open whilst pressing `opt` and also enables the subtle/eager setting that was introduced with zeta. Edit: I managed to get the preview working with correct icons! <img width="909" height="232" alt="image" src="https://github.com/user-attachments/assets/65800e67-4bc4-40f8-be78-806fcfe74ad9" /> <img width="1460" height="318" alt="CleanShot 2025-08-04 at 01 36 31@2x" src="https://github.com/user-attachments/assets/15651405-720f-465f-a13c-c7470817810a" /> Correct icons are also displayed: <img width="244" height="96" alt="image" src="https://github.com/user-attachments/assets/0b8a687f-73e3-452d-aefb-784c52831b73" /> Edit2: I added some comments, would be very happy to receive feedback (still learning rust) Release Notes: - Added Subtle and Eager edit prediction modes to Copilot and Supermaven
This commit is contained in:
parent
dd840e4b27
commit
2234220618
7 changed files with 372 additions and 63 deletions
|
@ -228,6 +228,49 @@ async fn test_edit_prediction_invalidation_range(cx: &mut gpui::TestAppContext)
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_edit_prediction_jump_disabled_for_non_zed_providers(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
let provider = cx.new(|_| FakeNonZedEditPredictionProvider::default());
|
||||
assign_editor_completion_provider_non_zed(provider.clone(), &mut cx);
|
||||
|
||||
// Cursor is 2+ lines above the proposed edit
|
||||
cx.set_state(indoc! {"
|
||||
line 0
|
||||
line ˇ1
|
||||
line 2
|
||||
line 3
|
||||
line
|
||||
"});
|
||||
|
||||
propose_edits_non_zed(
|
||||
&provider,
|
||||
vec![(Point::new(4, 3)..Point::new(4, 3), " 4")],
|
||||
&mut cx,
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, window, cx| editor.update_visible_edit_prediction(window, cx));
|
||||
|
||||
// For non-Zed providers, there should be no move completion (jump functionality disabled)
|
||||
cx.editor(|editor, _, _| {
|
||||
if let Some(completion_state) = &editor.active_edit_prediction {
|
||||
// Should be an Edit prediction, not a Move prediction
|
||||
match &completion_state.completion {
|
||||
EditPrediction::Edit { .. } => {
|
||||
// This is expected for non-Zed providers
|
||||
}
|
||||
EditPrediction::Move { .. } => {
|
||||
panic!(
|
||||
"Non-Zed providers should not show Move predictions (jump functionality)"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn assert_editor_active_edit_completion(
|
||||
cx: &mut EditorTestContext,
|
||||
assert: impl FnOnce(MultiBufferSnapshot, &Vec<(Range<Anchor>, String)>),
|
||||
|
@ -301,6 +344,37 @@ fn assign_editor_completion_provider(
|
|||
})
|
||||
}
|
||||
|
||||
fn propose_edits_non_zed<T: ToOffset>(
|
||||
provider: &Entity<FakeNonZedEditPredictionProvider>,
|
||||
edits: Vec<(Range<T>, &str)>,
|
||||
cx: &mut EditorTestContext,
|
||||
) {
|
||||
let snapshot = cx.buffer_snapshot();
|
||||
let edits = edits.into_iter().map(|(range, text)| {
|
||||
let range = snapshot.anchor_after(range.start)..snapshot.anchor_before(range.end);
|
||||
(range, text.into())
|
||||
});
|
||||
|
||||
cx.update(|_, cx| {
|
||||
provider.update(cx, |provider, _| {
|
||||
provider.set_edit_prediction(Some(edit_prediction::EditPrediction {
|
||||
id: None,
|
||||
edits: edits.collect(),
|
||||
edit_preview: None,
|
||||
}))
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn assign_editor_completion_provider_non_zed(
|
||||
provider: Entity<FakeNonZedEditPredictionProvider>,
|
||||
cx: &mut EditorTestContext,
|
||||
) {
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
editor.set_edit_prediction_provider(Some(provider), window, cx);
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct FakeEditPredictionProvider {
|
||||
pub completion: Option<edit_prediction::EditPrediction>,
|
||||
|
@ -325,6 +399,84 @@ impl EditPredictionProvider for FakeEditPredictionProvider {
|
|||
false
|
||||
}
|
||||
|
||||
fn supports_jump_to_edit() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_enabled(
|
||||
&self,
|
||||
_buffer: &gpui::Entity<language::Buffer>,
|
||||
_cursor_position: language::Anchor,
|
||||
_cx: &gpui::App,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_refreshing(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn refresh(
|
||||
&mut self,
|
||||
_project: Option<Entity<Project>>,
|
||||
_buffer: gpui::Entity<language::Buffer>,
|
||||
_cursor_position: language::Anchor,
|
||||
_debounce: bool,
|
||||
_cx: &mut gpui::Context<Self>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn cycle(
|
||||
&mut self,
|
||||
_buffer: gpui::Entity<language::Buffer>,
|
||||
_cursor_position: language::Anchor,
|
||||
_direction: edit_prediction::Direction,
|
||||
_cx: &mut gpui::Context<Self>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn accept(&mut self, _cx: &mut gpui::Context<Self>) {}
|
||||
|
||||
fn discard(&mut self, _cx: &mut gpui::Context<Self>) {}
|
||||
|
||||
fn suggest<'a>(
|
||||
&mut self,
|
||||
_buffer: &gpui::Entity<language::Buffer>,
|
||||
_cursor_position: language::Anchor,
|
||||
_cx: &mut gpui::Context<Self>,
|
||||
) -> Option<edit_prediction::EditPrediction> {
|
||||
self.completion.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct FakeNonZedEditPredictionProvider {
|
||||
pub completion: Option<edit_prediction::EditPrediction>,
|
||||
}
|
||||
|
||||
impl FakeNonZedEditPredictionProvider {
|
||||
pub fn set_edit_prediction(&mut self, completion: Option<edit_prediction::EditPrediction>) {
|
||||
self.completion = completion;
|
||||
}
|
||||
}
|
||||
|
||||
impl EditPredictionProvider for FakeNonZedEditPredictionProvider {
|
||||
fn name() -> &'static str {
|
||||
"fake-non-zed-provider"
|
||||
}
|
||||
|
||||
fn display_name() -> &'static str {
|
||||
"Fake Non-Zed Provider"
|
||||
}
|
||||
|
||||
fn show_completions_in_menu() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn supports_jump_to_edit() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_enabled(
|
||||
&self,
|
||||
_buffer: &gpui::Entity<language::Buffer>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue