Eager / subtle now working

This commit is contained in:
Oliver Azevedo Barnes 2025-07-09 19:51:16 +01:00
parent 9c8a75d3df
commit 2942f4aace
No known key found for this signature in database
4 changed files with 121 additions and 16 deletions

View file

@ -8957,6 +8957,19 @@ impl Editor {
editor_bg_color.blend(accent_color.opacity(0.6)) editor_bg_color.blend(accent_color.opacity(0.6))
} }
fn edit_prediction_icon_for_provider(&self) -> IconName {
if let Some(provider) = &self.edit_prediction_provider {
match provider.provider.name() {
"ollama" => IconName::AiOllama,
"copilot" => IconName::Copilot,
"supermaven" => IconName::Supermaven,
_ => IconName::ZedPredict,
}
} else {
IconName::ZedPredict
}
}
fn render_edit_prediction_cursor_popover( fn render_edit_prediction_cursor_popover(
&self, &self,
min_width: Pixels, min_width: Pixels,
@ -8994,7 +9007,7 @@ impl Editor {
h_flex() h_flex()
.flex_1() .flex_1()
.gap_2() .gap_2()
.child(Icon::new(IconName::ZedPredict)) .child(Icon::new(self.edit_prediction_icon_for_provider()))
.child(Label::new("Accept Terms of Service")) .child(Label::new("Accept Terms of Service"))
.child(div().w_full()) .child(div().w_full())
.child( .child(
@ -9010,12 +9023,10 @@ impl Editor {
let is_refreshing = provider.provider.is_refreshing(cx); let is_refreshing = provider.provider.is_refreshing(cx);
fn pending_completion_container() -> Div { let provider_icon = self.edit_prediction_icon_for_provider();
h_flex()
.h_full() fn pending_completion_container(icon: IconName) -> Div {
.flex_1() h_flex().h_full().flex_1().gap_2().child(Icon::new(icon))
.gap_2()
.child(Icon::new(IconName::ZedPredict))
} }
let completion = match &self.active_inline_completion { let completion = match &self.active_inline_completion {
@ -9040,12 +9051,15 @@ impl Editor {
use text::ToPoint as _; use text::ToPoint as _;
if target.text_anchor.to_point(&snapshot).row > cursor_point.row if target.text_anchor.to_point(&snapshot).row > cursor_point.row
{ {
// For move predictions, still use directional icons
Icon::new(IconName::ZedPredictDown) Icon::new(IconName::ZedPredictDown)
} else { } else {
Icon::new(IconName::ZedPredictUp) Icon::new(IconName::ZedPredictUp)
} }
} }
InlineCompletion::Edit { .. } => Icon::new(IconName::ZedPredict), InlineCompletion::Edit { .. } => {
Icon::new(self.edit_prediction_icon_for_provider())
}
})) }))
.child( .child(
h_flex() h_flex()
@ -9112,12 +9126,11 @@ impl Editor {
cx, cx,
)?, )?,
None => { None => pending_completion_container(provider_icon)
pending_completion_container().child(Label::new("...").size(LabelSize::Small)) .child(Label::new("...").size(LabelSize::Small)),
}
}, },
None => pending_completion_container().child(Label::new("No Prediction")), None => pending_completion_container(provider_icon).child(Label::new("No Prediction")),
}; };
let completion = if is_refreshing { let completion = if is_refreshing {
@ -9268,7 +9281,7 @@ impl Editor {
render_relative_row_jump("", cursor_point.row, first_edit_row) render_relative_row_jump("", cursor_point.row, first_edit_row)
.into_any_element() .into_any_element()
} else { } else {
Icon::new(IconName::ZedPredict).into_any_element() Icon::new(self.edit_prediction_icon_for_provider()).into_any_element()
}; };
Some( Some(

View file

@ -22904,3 +22904,29 @@ fn extract_color_inlays(editor: &Editor, cx: &App) -> Vec<Rgba> {
.map(Rgba::from) .map(Rgba::from)
.collect() .collect()
} }
#[gpui::test]
async fn test_edit_prediction_icon_for_provider(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let editor = cx.add_window(|window, cx| {
let buffer = MultiBuffer::build_simple("test", cx);
build_editor(buffer, window, cx)
});
// Test with no provider - should default to ZedPredict
let _ = editor.update(cx, |editor, _window, _cx| {
let icon = editor.edit_prediction_icon_for_provider();
assert_eq!(icon, IconName::ZedPredict);
});
// Test with fake inline completion provider - should still default to ZedPredict
// since the fake provider name is "fake-completion-provider"
let fake_provider = cx.new(|_| FakeInlineCompletionProvider::default());
let _ = editor.update(cx, |editor, window, cx| {
editor.set_edit_prediction_provider(Some(fake_provider), window, cx);
let icon = editor.edit_prediction_icon_for_provider();
assert_eq!(icon, IconName::ZedPredict);
});
}

View file

@ -519,7 +519,10 @@ impl InlineCompletionButton {
let subtle_mode = matches!(current_mode, EditPredictionsMode::Subtle); let subtle_mode = matches!(current_mode, EditPredictionsMode::Subtle);
let eager_mode = matches!(current_mode, EditPredictionsMode::Eager); let eager_mode = matches!(current_mode, EditPredictionsMode::Eager);
if matches!(provider, EditPredictionProvider::Zed) { if matches!(
provider,
EditPredictionProvider::Zed | EditPredictionProvider::Ollama
) {
menu = menu menu = menu
.separator() .separator()
.header("Display Modes") .header("Display Modes")
@ -1472,6 +1475,63 @@ mod tests {
}); });
} }
#[gpui::test]
async fn test_ollama_eager_subtle_options_visibility(cx: &mut TestAppContext) {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
AllLanguageModelSettings::register(cx);
AllLanguageSettings::register(cx);
language_model::LanguageModelRegistry::test(cx);
// Test that eager/subtle options are available for Ollama provider
// Verify that when provider is Ollama, the eager/subtle logic should be triggered
// This tests the condition: matches!(provider, EditPredictionProvider::Zed | EditPredictionProvider::Ollama)
assert!(matches!(
EditPredictionProvider::Ollama,
EditPredictionProvider::Zed | EditPredictionProvider::Ollama
));
// Verify that when provider is NOT Zed or Ollama, the eager/subtle logic should NOT be triggered
assert!(!matches!(
EditPredictionProvider::Copilot,
EditPredictionProvider::Zed | EditPredictionProvider::Ollama
));
assert!(!matches!(
EditPredictionProvider::Supermaven,
EditPredictionProvider::Zed | EditPredictionProvider::Ollama
));
});
}
#[gpui::test]
async fn test_ollama_edit_predictions_mode_setting(cx: &mut TestAppContext) {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
AllLanguageModelSettings::register(cx);
AllLanguageSettings::register(cx);
language_model::LanguageModelRegistry::test(cx);
// Test that edit predictions mode setting is read correctly
let settings = AllLanguageSettings::get_global(cx);
// Default mode should be Eager
assert_eq!(settings.edit_predictions_mode(), EditPredictionsMode::Eager);
// Test that the setting affects the preview_requires_modifier flag
let preview_requires_modifier_eager =
settings.edit_predictions_mode() == EditPredictionsMode::Subtle;
assert!(!preview_requires_modifier_eager);
// Simulate changing to subtle mode by checking the condition
let subtle_mode_check = EditPredictionsMode::Subtle == EditPredictionsMode::Subtle;
assert!(subtle_mode_check);
});
}
#[gpui::test] #[gpui::test]
async fn test_ollama_model_switching_logic(cx: &mut TestAppContext) { async fn test_ollama_model_switching_logic(cx: &mut TestAppContext) {
let _fs: Arc<dyn Fs> = FakeFs::new(cx.executor()); let _fs: Arc<dyn Fs> = FakeFs::new(cx.executor());

View file

@ -80,7 +80,7 @@ impl EditPredictionProvider for OllamaCompletionProvider {
} }
fn show_completions_in_menu() -> bool { fn show_completions_in_menu() -> bool {
false true
} }
fn is_enabled(&self, _buffer: &Entity<Buffer>, _cursor_position: Anchor, _cx: &App) -> bool { fn is_enabled(&self, _buffer: &Entity<Buffer>, _cursor_position: Anchor, _cx: &App) -> bool {
@ -404,7 +404,7 @@ mod tests {
let prefix = "def test():"; let prefix = "def test():";
let suffix = " pass"; let suffix = " pass";
let request_with_key = GenerateRequest { let _request_with_key = GenerateRequest {
model: provider_with_key.model.clone(), model: provider_with_key.model.clone(),
prompt: prefix.to_string(), prompt: prefix.to_string(),
suffix: Some(suffix.to_string()), suffix: Some(suffix.to_string()),
@ -423,4 +423,10 @@ mod tests {
// but we can verify the provider stores it correctly // but we can verify the provider stores it correctly
assert_eq!(provider_with_key.api_key, Some("test-api-key".to_string())); assert_eq!(provider_with_key.api_key, Some("test-api-key".to_string()));
} }
#[gpui::test]
async fn test_show_completions_in_menu(_cx: &mut TestAppContext) {
// Test that Ollama provider shows completions in menu to enable hover icon
assert!(OllamaCompletionProvider::show_completions_in_menu());
}
} }