diff --git a/Cargo.lock b/Cargo.lock index e969208a047a8b1e477b01bde0014d390cba1eec..142ec58ed40097529cfcebb4853ae3956eee47c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3302,6 +3302,7 @@ dependencies = [ "futures 0.3.31", "gpui", "http_client", + "icons", "language", "language_models", "log", @@ -3734,6 +3735,7 @@ dependencies = [ "futures 0.3.31", "gpui", "http_client", + "icons", "indoc", "language", "log", @@ -5444,6 +5446,7 @@ version = "0.1.0" dependencies = [ "client", "gpui", + "icons", "language", "text", ] diff --git a/assets/icons/sweep_ai.svg b/assets/icons/sweep_ai.svg index bf3459c7ea9896bc6c1d2297d1f7671cfc8a4d46..9c63c810dd9e164c14c1ad1a1bca9c6ec68fc95e 100644 --- a/assets/icons/sweep_ai.svg +++ b/assets/icons/sweep_ai.svg @@ -1,32 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/assets/icons/sweep_ai_disabled.svg b/assets/icons/sweep_ai_disabled.svg new file mode 100644 index 0000000000000000000000000000000000000000..b15a8d8526f36f312482effefd3d7538ce5f7a04 --- /dev/null +++ b/assets/icons/sweep_ai_disabled.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/sweep_ai_down.svg b/assets/icons/sweep_ai_down.svg new file mode 100644 index 0000000000000000000000000000000000000000..f08dcb171811c761cd13c4efd0ef0acdc78f9951 --- /dev/null +++ b/assets/icons/sweep_ai_down.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/sweep_ai_error.svg b/assets/icons/sweep_ai_error.svg new file mode 100644 index 0000000000000000000000000000000000000000..95285a1273e72ec4f02cb23e3c2fb39460f42761 --- /dev/null +++ b/assets/icons/sweep_ai_error.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/sweep_ai_up.svg b/assets/icons/sweep_ai_up.svg new file mode 100644 index 0000000000000000000000000000000000000000..7c28282a6a14c47561a50ab456c0bec2e05b07cc --- /dev/null +++ b/assets/icons/sweep_ai_up.svg @@ -0,0 +1 @@ + diff --git a/crates/codestral/Cargo.toml b/crates/codestral/Cargo.toml index 7da3bed75a9f175b49b3b11f00fd1d1583743f5e..0036e9df0f89bef0e4fec6ca48951549a5d55bb4 100644 --- a/crates/codestral/Cargo.toml +++ b/crates/codestral/Cargo.toml @@ -15,6 +15,7 @@ edit_prediction.workspace = true futures.workspace = true gpui.workspace = true http_client.workspace = true +icons.workspace = true language.workspace = true language_models.workspace = true log.workspace = true diff --git a/crates/codestral/src/codestral.rs b/crates/codestral/src/codestral.rs index d5fc8d53b7e24b64598bc9b717fa043080f99680..8c1b0e65c07cc5d8f275f4e3dc71b08a18bfa1b3 100644 --- a/crates/codestral/src/codestral.rs +++ b/crates/codestral/src/codestral.rs @@ -1,9 +1,10 @@ use anyhow::Result; use edit_prediction::cursor_excerpt; -use edit_prediction_types::{EditPrediction, EditPredictionDelegate}; +use edit_prediction_types::{EditPrediction, EditPredictionDelegate, EditPredictionIconSet}; use futures::AsyncReadExt; use gpui::{App, Context, Entity, Task}; use http_client::HttpClient; +use icons::IconName; use language::{ language_settings::all_language_settings, Anchor, Buffer, BufferSnapshot, EditPreview, ToPoint, }; @@ -172,6 +173,10 @@ impl EditPredictionDelegate for CodestralEditPredictionDelegate { true } + fn icons(&self, _cx: &App) -> EditPredictionIconSet { + EditPredictionIconSet::new(IconName::AiMistral) + } + fn is_enabled(&self, _buffer: &Entity, _cursor_position: Anchor, cx: &App) -> bool { Self::api_key(cx).is_some() } diff --git a/crates/copilot/Cargo.toml b/crates/copilot/Cargo.toml index a07811cd2e3a6b17a1bf23c24ae7af376ef9b37a..6e5144ff6346375e90ea368074b5da7c4e7a5d87 100644 --- a/crates/copilot/Cargo.toml +++ b/crates/copilot/Cargo.toml @@ -32,6 +32,7 @@ fs.workspace = true futures.workspace = true gpui.workspace = true edit_prediction_types.workspace = true +icons.workspace = true language.workspace = true log.workspace = true lsp.workspace = true diff --git a/crates/copilot/src/copilot_edit_prediction_delegate.rs b/crates/copilot/src/copilot_edit_prediction_delegate.rs index a8e8e231baa94397b72205ee90a86e80dad8ca80..6bc2da37f1799e32532e558c4943232598ee1f5d 100644 --- a/crates/copilot/src/copilot_edit_prediction_delegate.rs +++ b/crates/copilot/src/copilot_edit_prediction_delegate.rs @@ -6,8 +6,11 @@ use crate::{ }, }; use anyhow::Result; -use edit_prediction_types::{EditPrediction, EditPredictionDelegate, interpolate_edits}; +use edit_prediction_types::{ + EditPrediction, EditPredictionDelegate, EditPredictionIconSet, interpolate_edits, +}; use gpui::{App, Context, Entity, Task}; +use icons::IconName; use language::{Anchor, Buffer, BufferSnapshot, EditPreview, OffsetRangeExt, ToPointUtf16}; use std::{ops::Range, sync::Arc, time::Duration}; @@ -50,6 +53,12 @@ impl EditPredictionDelegate for CopilotEditPredictionDelegate { true } + fn icons(&self, _cx: &App) -> EditPredictionIconSet { + EditPredictionIconSet::new(IconName::Copilot) + .with_disabled(IconName::CopilotDisabled) + .with_error(IconName::CopilotError) + } + fn is_refreshing(&self, _cx: &App) -> bool { self.pending_refresh.is_some() && self.completion.is_none() } diff --git a/crates/edit_prediction/src/edit_prediction.rs b/crates/edit_prediction/src/edit_prediction.rs index 4adfa2f5f6201b03fe522b6a43963c00ba101cfc..f64e5ac4143cccbcc53ad006b715ee05d75f6916 100644 --- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -655,6 +655,29 @@ impl EditPredictionStore { self.edit_prediction_model = model; } + pub fn icons(&self) -> edit_prediction_types::EditPredictionIconSet { + use ui::IconName; + match self.edit_prediction_model { + EditPredictionModel::Sweep => { + edit_prediction_types::EditPredictionIconSet::new(IconName::SweepAi) + .with_disabled(IconName::SweepAiDisabled) + .with_up(IconName::SweepAiUp) + .with_down(IconName::SweepAiDown) + .with_error(IconName::SweepAiError) + } + EditPredictionModel::Mercury => { + edit_prediction_types::EditPredictionIconSet::new(IconName::Inception) + } + EditPredictionModel::Zeta1 | EditPredictionModel::Zeta2 { .. } => { + edit_prediction_types::EditPredictionIconSet::new(IconName::ZedPredict) + .with_disabled(IconName::ZedPredictDisabled) + .with_up(IconName::ZedPredictUp) + .with_down(IconName::ZedPredictDown) + .with_error(IconName::ZedPredictError) + } + } + } + pub fn has_sweep_api_token(&self, cx: &App) -> bool { self.sweep_ai.api_token.read(cx).has_key() } diff --git a/crates/edit_prediction/src/zed_edit_prediction_delegate.rs b/crates/edit_prediction/src/zed_edit_prediction_delegate.rs index b2a7f34c73b37eabee51d91f1bed2b6735936239..f0936bc5f38d364c5728a75807134433ecadcc52 100644 --- a/crates/edit_prediction/src/zed_edit_prediction_delegate.rs +++ b/crates/edit_prediction/src/zed_edit_prediction_delegate.rs @@ -2,10 +2,13 @@ use std::{cmp, sync::Arc}; use client::{Client, UserStore}; use cloud_llm_client::EditPredictionRejectReason; -use edit_prediction_types::{DataCollectionState, EditPredictionDelegate, SuggestionDisplayType}; +use edit_prediction_types::{ + DataCollectionState, EditPredictionDelegate, EditPredictionIconSet, SuggestionDisplayType, +}; use gpui::{App, Entity, prelude::*}; use language::{Buffer, ToPoint as _}; use project::Project; +use ui::prelude::*; use crate::{BufferEditPrediction, EditPredictionModel, EditPredictionStore}; @@ -58,6 +61,24 @@ impl EditPredictionDelegate for ZedEditPredictionDelegate { true } + fn icons(&self, cx: &App) -> EditPredictionIconSet { + match self.store.read(cx).edit_prediction_model { + EditPredictionModel::Sweep => EditPredictionIconSet::new(IconName::SweepAi) + .with_disabled(IconName::SweepAiDisabled) + .with_up(IconName::SweepAiUp) + .with_down(IconName::SweepAiDown) + .with_error(IconName::SweepAiError), + EditPredictionModel::Mercury => EditPredictionIconSet::new(IconName::Inception), + EditPredictionModel::Zeta1 | EditPredictionModel::Zeta2 { .. } => { + EditPredictionIconSet::new(IconName::ZedPredict) + .with_disabled(IconName::ZedPredictDisabled) + .with_up(IconName::ZedPredictUp) + .with_down(IconName::ZedPredictDown) + .with_error(IconName::ZedPredictError) + } + } + } + fn data_collection_state(&self, cx: &App) -> DataCollectionState { if let Some(buffer) = &self.singleton_buffer && let Some(file) = buffer.read(cx).file() diff --git a/crates/edit_prediction_types/Cargo.toml b/crates/edit_prediction_types/Cargo.toml index 00a8577911af0afd012535fd324a68af8fd70391..4de0c9f62c5e556d20fe55ef69513cb807ff8164 100644 --- a/crates/edit_prediction_types/Cargo.toml +++ b/crates/edit_prediction_types/Cargo.toml @@ -14,5 +14,6 @@ path = "src/edit_prediction_types.rs" [dependencies] client.workspace = true gpui.workspace = true +icons.workspace = true language.workspace = true text.workspace = true diff --git a/crates/edit_prediction_types/src/edit_prediction_types.rs b/crates/edit_prediction_types/src/edit_prediction_types.rs index a077e43ff7850c0c4c5f0fe460664d6b642a4a14..eff4cfcc3beea9f9d1c82ca3ab9a457efdca78b8 100644 --- a/crates/edit_prediction_types/src/edit_prediction_types.rs +++ b/crates/edit_prediction_types/src/edit_prediction_types.rs @@ -2,8 +2,50 @@ use std::{ops::Range, sync::Arc}; use client::EditPredictionUsage; use gpui::{App, Context, Entity, SharedString}; +use icons::IconName; use language::{Anchor, Buffer, OffsetRangeExt}; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct EditPredictionIconSet { + pub base: IconName, + pub disabled: IconName, + pub up: IconName, + pub down: IconName, + pub error: IconName, +} + +impl EditPredictionIconSet { + pub fn new(base: IconName) -> Self { + Self { + base, + disabled: IconName::ZedPredictDisabled, + up: IconName::ZedPredictUp, + down: IconName::ZedPredictDown, + error: IconName::ZedPredictError, + } + } + + pub fn with_disabled(mut self, disabled: IconName) -> Self { + self.disabled = disabled; + self + } + + pub fn with_up(mut self, up: IconName) -> Self { + self.up = up; + self + } + + pub fn with_down(mut self, down: IconName) -> Self { + self.down = down; + self + } + + pub fn with_error(mut self, error: IconName) -> Self { + self.error = error; + self + } +} + /// Represents a predicted cursor position after an edit is applied. /// /// Since the cursor may be positioned inside newly inserted text that doesn't @@ -110,6 +152,8 @@ pub trait EditPredictionDelegate: 'static + Sized { true } + fn icons(&self, cx: &App) -> EditPredictionIconSet; + fn data_collection_state(&self, _cx: &App) -> DataCollectionState { DataCollectionState::Unsupported } @@ -156,6 +200,7 @@ pub trait EditPredictionDelegateHandle { fn show_predictions_in_menu(&self) -> bool; fn show_tab_accept_marker(&self) -> bool; fn supports_jump_to_edit(&self) -> bool; + fn icons(&self, cx: &App) -> EditPredictionIconSet; fn data_collection_state(&self, cx: &App) -> DataCollectionState; fn usage(&self, cx: &App) -> Option; fn toggle_data_collection(&self, cx: &mut App); @@ -202,6 +247,10 @@ where T::supports_jump_to_edit() } + fn icons(&self, cx: &App) -> EditPredictionIconSet { + self.read(cx).icons(cx) + } + fn data_collection_state(&self, cx: &App) -> DataCollectionState { self.read(cx).data_collection_state(cx) } diff --git a/crates/edit_prediction_ui/src/edit_prediction_button.rs b/crates/edit_prediction_ui/src/edit_prediction_button.rs index 94e408cf67e11e30190a82e41d4a7e403ea94f42..f864940e082f4e2256b8662a89ff8d10b5c6280d 100644 --- a/crates/edit_prediction_ui/src/edit_prediction_button.rs +++ b/crates/edit_prediction_ui/src/edit_prediction_button.rs @@ -308,6 +308,13 @@ impl Render for EditPredictionButton { } provider @ (EditPredictionProvider::Experimental(_) | EditPredictionProvider::Zed) => { let enabled = self.editor_enabled.unwrap_or(true); + let icons = self + .edit_prediction_provider + .as_ref() + .map(|p| p.icons(cx)) + .unwrap_or_else(|| { + edit_prediction_types::EditPredictionIconSet::new(IconName::ZedPredict) + }); let ep_icon; let tooltip_meta; @@ -317,19 +324,19 @@ impl Render for EditPredictionButton { EditPredictionProvider::Experimental( EXPERIMENTAL_SWEEP_EDIT_PREDICTION_PROVIDER_NAME, ) => { - ep_icon = IconName::SweepAi; + missing_token = edit_prediction::EditPredictionStore::try_global(cx) + .is_some_and(|ep_store| !ep_store.read(cx).has_sweep_api_token(cx)); + ep_icon = if enabled { icons.base } else { icons.disabled }; tooltip_meta = if missing_token { "Missing API key for Sweep" } else { "Powered by Sweep" }; - missing_token = edit_prediction::EditPredictionStore::try_global(cx) - .is_some_and(|ep_store| !ep_store.read(cx).has_sweep_api_token(cx)); } EditPredictionProvider::Experimental( EXPERIMENTAL_MERCURY_EDIT_PREDICTION_PROVIDER_NAME, ) => { - ep_icon = IconName::Inception; + ep_icon = if enabled { icons.base } else { icons.disabled }; missing_token = edit_prediction::EditPredictionStore::try_global(cx) .is_some_and(|ep_store| !ep_store.read(cx).has_mercury_api_token(cx)); tooltip_meta = if missing_token { @@ -339,11 +346,7 @@ impl Render for EditPredictionButton { }; } _ => { - ep_icon = if enabled { - IconName::ZedPredict - } else { - IconName::ZedPredictDisabled - }; + ep_icon = if enabled { icons.base } else { icons.disabled }; tooltip_meta = "Powered by Zeta" } }; @@ -849,10 +852,17 @@ impl EditPredictionButton { ); if !self.editor_enabled.unwrap_or(true) { + let icons = self + .edit_prediction_provider + .as_ref() + .map(|p| p.icons(cx)) + .unwrap_or_else(|| { + edit_prediction_types::EditPredictionIconSet::new(IconName::ZedPredict) + }); menu = menu.item( ContextMenuEntry::new("This file is excluded.") .disabled(true) - .icon(IconName::ZedPredictDisabled) + .icon(icons.disabled) .icon_size(IconSize::Small), ); } diff --git a/crates/edit_prediction_ui/src/rate_prediction_modal.rs b/crates/edit_prediction_ui/src/rate_prediction_modal.rs index 936c51a2ae9bc5f8b72578f2adf022ecb8a9d6b9..65ce7ec8761541d886f272baa3934af58884524d 100644 --- a/crates/edit_prediction_ui/src/rate_prediction_modal.rs +++ b/crates/edit_prediction_ui/src/rate_prediction_modal.rs @@ -839,20 +839,21 @@ impl Render for RatePredictionsModal { .border_color(border_color) .flex_shrink_0() .overflow_hidden() - .child( + .child({ + let icons = self.ep_store.read(cx).icons(); h_flex() .h_8() .px_2() .justify_between() .border_b_1() .border_color(border_color) - .child(Icon::new(IconName::ZedPredict).size(IconSize::Small)) + .child(Icon::new(icons.base).size(IconSize::Small)) .child( Label::new("From most recent to oldest") .color(Color::Muted) .size(LabelSize::Small), - ), - ) + ) + }) .child( div() .id("completion_list") diff --git a/crates/editor/src/edit_prediction_tests.rs b/crates/editor/src/edit_prediction_tests.rs index 45cae0ef956e8fc05aeef84099cddedff343f4e9..434f296f15abbcec474b5577e6aba8d32e70ac70 100644 --- a/crates/editor/src/edit_prediction_tests.rs +++ b/crates/editor/src/edit_prediction_tests.rs @@ -1,9 +1,12 @@ -use edit_prediction_types::{EditPredictionDelegate, PredictedCursorPosition}; +use edit_prediction_types::{ + EditPredictionDelegate, EditPredictionIconSet, PredictedCursorPosition, +}; use gpui::{Entity, KeyBinding, Modifiers, prelude::*}; use indoc::indoc; use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint}; use std::{ops::Range, sync::Arc}; use text::{Point, ToOffset}; +use ui::prelude::*; use crate::{ AcceptEditPrediction, EditPrediction, MenuEditPredictionsPolicy, editor_tests::init_test, @@ -589,6 +592,10 @@ impl EditPredictionDelegate for FakeEditPredictionDelegate { true } + fn icons(&self, _cx: &gpui::App) -> EditPredictionIconSet { + EditPredictionIconSet::new(IconName::ZedPredict) + } + fn is_enabled( &self, _buffer: &gpui::Entity, @@ -656,6 +663,10 @@ impl EditPredictionDelegate for FakeNonZedEditPredictionDelegate { false } + fn icons(&self, _cx: &gpui::App) -> EditPredictionIconSet { + EditPredictionIconSet::new(IconName::ZedPredict) + } + fn is_enabled( &self, _buffer: &gpui::Entity, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 624383d8b9fd95b2e135c5269deddaaee02bd391..7d937866b89b4b3ed3b615ae661f566777b146a5 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -9765,6 +9765,7 @@ impl Editor { let keybind = self.render_edit_prediction_accept_keybind(window, cx); let has_keybind = keybind.is_some(); + let icons = Self::get_prediction_provider_icons(&self.edit_prediction_provider, cx); h_flex() .id("ep-line-popover") @@ -9783,7 +9784,7 @@ impl Editor { el.bg(status_colors.error_background) .border_color(status_colors.error.opacity(0.6)) .pl_2() - .child(Icon::new(IconName::ZedPredictError).color(Color::Error)) + .child(Icon::new(icons.error).color(Color::Error)) .cursor_default() .hoverable_tooltip(move |_window, cx| { cx.new(|_| MissingEditPredictionKeybindingTooltip).into() @@ -9823,6 +9824,7 @@ impl Editor { ) -> Stateful
{ let keybind = self.render_edit_prediction_accept_keybind(window, cx); let has_keybind = keybind.is_some(); + let icons = Self::get_prediction_provider_icons(&self.edit_prediction_provider, cx); let file_name = snapshot .file() @@ -9845,7 +9847,7 @@ impl Editor { el.bg(status_colors.error_background) .border_color(status_colors.error.opacity(0.6)) .pl_2() - .child(Icon::new(IconName::ZedPredictError).color(Color::Error)) + .child(Icon::new(icons.error).color(Color::Error)) .cursor_default() .hoverable_tooltip(move |_window, cx| { cx.new(|_| MissingEditPredictionKeybindingTooltip).into() @@ -9887,16 +9889,13 @@ impl Editor { let editor_bg_color = cx.theme().colors().editor_background; editor_bg_color.blend(accent_color.opacity(0.6)) } - fn get_prediction_provider_icon_name( + fn get_prediction_provider_icons( provider: &Option, - ) -> IconName { + cx: &App, + ) -> edit_prediction_types::EditPredictionIconSet { match provider { - Some(provider) => match provider.provider.name() { - "copilot" => IconName::Copilot, - "supermaven" => IconName::Supermaven, - _ => IconName::ZedPredict, - }, - None => IconName::ZedPredict, + Some(provider) => provider.provider.icons(cx), + None => edit_prediction_types::EditPredictionIconSet::new(IconName::ZedPredict), } } @@ -9911,7 +9910,7 @@ impl Editor { cx: &mut Context, ) -> Option { let provider = self.edit_prediction_provider.as_ref()?; - let provider_icon = Self::get_prediction_provider_icon_name(&self.edit_prediction_provider); + let icons = Self::get_prediction_provider_icons(&self.edit_prediction_provider, cx); let is_refreshing = provider.provider.is_refreshing(cx); @@ -9941,16 +9940,16 @@ impl Editor { use text::ToPoint as _; if target.text_anchor.to_point(snapshot).row > cursor_point.row { - Icon::new(IconName::ZedPredictDown) + Icon::new(icons.down) } else { - Icon::new(IconName::ZedPredictUp) + Icon::new(icons.up) } } EditPrediction::MoveOutside { .. } => { // TODO [zeta2] custom icon for external jump? - Icon::new(provider_icon) + Icon::new(icons.base) } - EditPrediction::Edit { .. } => Icon::new(provider_icon), + EditPrediction::Edit { .. } => Icon::new(icons.base), })) .child( h_flex() @@ -10017,11 +10016,11 @@ impl Editor { cx, )?, - None => pending_completion_container(provider_icon) + None => pending_completion_container(icons.base) .child(Label::new("...").size(LabelSize::Small)), }, - None => pending_completion_container(provider_icon) + None => pending_completion_container(icons.base) .child(Label::new("...").size(LabelSize::Small)), }; @@ -10131,6 +10130,8 @@ impl Editor { .map(|provider| provider.provider.supports_jump_to_edit()) .unwrap_or(true); + let icons = Self::get_prediction_provider_icons(&self.edit_prediction_provider, cx); + match &completion.completion { EditPrediction::MoveWithin { target, snapshot, .. @@ -10146,9 +10147,9 @@ impl Editor { .flex_1() .child( if target.text_anchor.to_point(snapshot).row > cursor_point.row { - Icon::new(IconName::ZedPredictDown) + Icon::new(icons.down) } else { - Icon::new(IconName::ZedPredictUp) + Icon::new(icons.up) }, ) .child(Label::new("Jump to Edit")), @@ -10164,7 +10165,7 @@ impl Editor { .px_2() .gap_2() .flex_1() - .child(Icon::new(IconName::ZedPredict)) + .child(Icon::new(icons.base)) .child(Label::new(format!("Jump to {file_name}"))), ) } @@ -10197,9 +10198,7 @@ impl Editor { render_relative_row_jump("", cursor_point.row, first_edit_row) .into_any_element() } else { - let icon_name = - Editor::get_prediction_provider_icon_name(&self.edit_prediction_provider); - Icon::new(icon_name).into_any_element() + Icon::new(icons.base).into_any_element() }; Some( diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs index 93866f625899f1c81600745b875c1fd68d1e947d..f716fcc1c60f691b32549670acc6cc669617b525 100644 --- a/crates/icons/src/icons.rs +++ b/crates/icons/src/icons.rs @@ -222,6 +222,10 @@ pub enum IconName { SupermavenInit, SwatchBook, SweepAi, + SweepAiDisabled, + SweepAiDown, + SweepAiError, + SweepAiUp, Tab, Terminal, TerminalAlt, diff --git a/crates/supermaven/src/supermaven_edit_prediction_delegate.rs b/crates/supermaven/src/supermaven_edit_prediction_delegate.rs index 4c3216f2e283dd3cc0d1f54a4dfd39d510e72e08..f97fe9edfe0408f464caf2a6b5d5ed652e4c5db1 100644 --- a/crates/supermaven/src/supermaven_edit_prediction_delegate.rs +++ b/crates/supermaven/src/supermaven_edit_prediction_delegate.rs @@ -1,6 +1,6 @@ use crate::{Supermaven, SupermavenCompletionStateId}; use anyhow::Result; -use edit_prediction_types::{EditPrediction, EditPredictionDelegate}; +use edit_prediction_types::{EditPrediction, EditPredictionDelegate, EditPredictionIconSet}; use futures::StreamExt as _; use gpui::{App, Context, Entity, EntityId, Task}; use language::{Anchor, Buffer, BufferSnapshot}; @@ -11,6 +11,7 @@ use std::{ time::Duration, }; use text::{ToOffset, ToPoint}; +use ui::prelude::*; use unicode_segmentation::UnicodeSegmentation; pub const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75); @@ -126,6 +127,12 @@ impl EditPredictionDelegate for SupermavenEditPredictionDelegate { false } + fn icons(&self, _cx: &App) -> EditPredictionIconSet { + EditPredictionIconSet::new(IconName::Supermaven) + .with_disabled(IconName::SupermavenDisabled) + .with_error(IconName::SupermavenError) + } + fn is_enabled(&self, _buffer: &Entity, _cursor_position: Anchor, cx: &App) -> bool { self.supermaven.read(cx).is_enabled() }