@@ -206,6 +206,17 @@ pub enum InlineCompletionProvider {
Zed,
}
+impl InlineCompletionProvider {
+ pub fn is_zed(&self) -> bool {
+ match self {
+ InlineCompletionProvider::Zed => true,
+ InlineCompletionProvider::None
+ | InlineCompletionProvider::Copilot
+ | InlineCompletionProvider::Supermaven => false,
+ }
+ }
+}
+
/// The settings for edit predictions, such as [GitHub Copilot](https://github.com/features/copilot)
/// or [Supermaven](https://supermaven.com).
#[derive(Clone, Debug, Default)]
@@ -4,11 +4,16 @@ use command_palette_hooks::CommandPaletteFilter;
use feature_flags::{
FeatureFlagAppExt as _, PredictEditsFeatureFlag, PredictEditsRateCompletionsFeatureFlag,
};
+use gpui::actions;
+use language::language_settings::{AllLanguageSettings, InlineCompletionProvider};
+use settings::update_settings_file;
use ui::App;
use workspace::Workspace;
use crate::{onboarding_modal::ZedPredictModal, RateCompletionModal, RateCompletions};
+actions!(edit_predictions, [ResetOnboarding]);
+
pub fn init(cx: &mut App) {
cx.observe_new(move |workspace: &mut Workspace, _, _cx| {
workspace.register_action(|workspace, _: &RateCompletions, window, cx| {
@@ -31,6 +36,20 @@ pub fn init(cx: &mut App) {
}
},
);
+
+ workspace.register_action(|workspace, _: &ResetOnboarding, _window, cx| {
+ update_settings_file::<AllLanguageSettings>(
+ workspace.app_state().fs.clone(),
+ cx,
+ move |file, _| {
+ file.features
+ .get_or_insert(Default::default())
+ .inline_completion_provider = Some(InlineCompletionProvider::None)
+ },
+ );
+
+ crate::onboarding_banner::clear_dismissed(cx);
+ });
})
.detach();
@@ -11,6 +11,7 @@ use crate::onboarding_event;
/// Prompts the user to try Zed's Edit Prediction feature
pub struct ZedPredictBanner {
dismissed: bool,
+ provider: InlineCompletionProvider,
_subscription: Subscription,
}
@@ -18,40 +19,30 @@ impl ZedPredictBanner {
pub fn new(cx: &mut Context<Self>) -> Self {
Self {
dismissed: get_dismissed(),
+ provider: all_language_settings(None, cx).inline_completions.provider,
_subscription: cx.observe_global::<SettingsStore>(Self::handle_settings_changed),
}
}
fn should_show(&self, cx: &mut App) -> bool {
- if !cx.has_flag::<PredictEditsFeatureFlag>() || self.dismissed {
- return false;
- }
-
- let provider = all_language_settings(None, cx).inline_completions.provider;
-
- match provider {
- InlineCompletionProvider::None
- | InlineCompletionProvider::Copilot
- | InlineCompletionProvider::Supermaven => true,
- InlineCompletionProvider::Zed => false,
- }
+ cx.has_flag::<PredictEditsFeatureFlag>() && !self.dismissed && !self.provider.is_zed()
}
fn handle_settings_changed(&mut self, cx: &mut Context<Self>) {
- if self.dismissed {
+ let new_provider = all_language_settings(None, cx).inline_completions.provider;
+
+ if new_provider == self.provider {
return;
}
- let provider = all_language_settings(None, cx).inline_completions.provider;
-
- match provider {
- InlineCompletionProvider::None
- | InlineCompletionProvider::Copilot
- | InlineCompletionProvider::Supermaven => {}
- InlineCompletionProvider::Zed => {
- self.dismiss(cx);
- }
+ if new_provider.is_zed() {
+ self.dismiss(cx);
+ } else {
+ self.dismissed = get_dismissed();
}
+
+ self.provider = new_provider;
+ cx.notify();
}
fn dismiss(&mut self, cx: &mut Context<Self>) {
@@ -64,14 +55,14 @@ impl ZedPredictBanner {
const DISMISSED_AT_KEY: &str = "zed_predict_banner_dismissed_at";
-pub(crate) fn get_dismissed() -> bool {
+fn get_dismissed() -> bool {
db::kvp::KEY_VALUE_STORE
.read_kvp(DISMISSED_AT_KEY)
.log_err()
.map_or(false, |dismissed| dismissed.is_some())
}
-pub(crate) fn persist_dismissed(cx: &mut App) {
+fn persist_dismissed(cx: &mut App) {
cx.spawn(|_| {
let time = Utc::now().to_rfc3339();
db::kvp::KEY_VALUE_STORE.write_kvp(DISMISSED_AT_KEY.into(), time)
@@ -79,6 +70,11 @@ pub(crate) fn persist_dismissed(cx: &mut App) {
.detach_and_log_err(cx);
}
+pub(crate) fn clear_dismissed(cx: &mut App) {
+ cx.spawn(|_| db::kvp::KEY_VALUE_STORE.delete_kvp(DISMISSED_AT_KEY.into()))
+ .detach_and_log_err(cx);
+}
+
impl Render for ZedPredictBanner {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
if !self.should_show(cx) {