Update global ai setting

Nate Butler created

Change summary

Cargo.lock                                |  1 
crates/language/src/language_settings.rs  | 27 ++++++++++++++++++++
crates/onboarding_ui/Cargo.toml           |  5 ++-
crates/onboarding_ui/src/onboarding_ui.rs | 32 ++++++++++++++----------
crates/zed/src/zed.rs                     | 20 +--------------
5 files changed, 50 insertions(+), 35 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -10827,6 +10827,7 @@ dependencies = [
  "feature_flags",
  "gpui",
  "language",
+ "log",
  "menu",
  "project",
  "serde_json",

crates/language/src/language_settings.rs 🔗

@@ -16,8 +16,10 @@ use serde::{
     de::{self, IntoDeserializer, MapAccess, SeqAccess, Visitor},
 };
 
+use fs::Fs;
 use settings::{
     ParameterizedJsonSchema, Settings, SettingsLocation, SettingsSources, SettingsStore,
+    update_settings_file,
 };
 use shellexpand;
 use std::{borrow::Cow, num::NonZeroU32, path::Path, slice, sync::Arc};
@@ -1136,6 +1138,21 @@ impl AllLanguageSettings {
     pub fn is_ai_assistance_enabled(&self) -> bool {
         self.ai_assistance
     }
+
+    /// Sets AI assistance to the specified state and updates the settings file.
+    pub fn set_ai_assistance(enabled: bool, fs: Arc<dyn Fs>, cx: &mut App) {
+        let current_state = Self::get_global(cx).ai_assistance;
+
+        if current_state == enabled {
+            return;
+        }
+
+        update_settings_file::<Self>(fs, cx, move |file, _| {
+            file.features
+                .get_or_insert(Default::default())
+                .ai_assistance = Some(enabled);
+        });
+    }
 }
 
 fn merge_with_editorconfig(settings: &mut LanguageSettings, cfg: &EditorconfigProperties) {
@@ -1261,7 +1278,7 @@ impl settings::Settings for AllLanguageSettings {
             .map(|settings| settings.enabled_in_text_threads)
             .unwrap_or(true);
 
-        let ai_assistance = default_value
+        let mut ai_assistance = default_value
             .features
             .as_ref()
             .and_then(|f| f.ai_assistance)
@@ -1288,6 +1305,14 @@ impl settings::Settings for AllLanguageSettings {
                 edit_prediction_provider = Some(provider);
             }
 
+            if let Some(user_ai_assistance) = user_settings
+                .features
+                .as_ref()
+                .and_then(|f| f.ai_assistance)
+            {
+                ai_assistance = user_ai_assistance;
+            }
+
             if let Some(edit_predictions) = user_settings.edit_predictions.as_ref() {
                 edit_predictions_mode = edit_predictions.mode;
                 enabled_in_text_threads = edit_predictions.enabled_in_text_threads;

crates/onboarding_ui/Cargo.toml 🔗

@@ -16,7 +16,6 @@ test-support = []
 
 [dependencies]
 anyhow.workspace = true
-welcome.workspace = true
 client.workspace = true
 command_palette_hooks.workspace = true
 component.workspace = true
@@ -24,18 +23,20 @@ db.workspace = true
 feature_flags.workspace = true
 gpui.workspace = true
 language.workspace = true
+log.workspace = true
 menu.workspace = true
 project.workspace = true
 serde_json.workspace = true
 settings.workspace = true
 settings_ui.workspace = true
+smallvec.workspace = true
 theme.workspace = true
 ui.workspace = true
 util.workspace = true
 vim_mode_setting.workspace = true
+welcome.workspace = true
 workspace.workspace = true
 zed_actions.workspace = true
-smallvec.workspace = true
 
 [dev-dependencies]
 editor = { workspace = true, features = ["test-support"] }

crates/onboarding_ui/src/onboarding_ui.rs 🔗

@@ -495,6 +495,22 @@ impl OnboardingUI {
         cx.notify();
     }
 
+    fn set_ai_assistance(
+        &mut self,
+        selection: &ToggleState,
+        _: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
+        let enabled = selection == &ToggleState::Selected;
+
+        if let Some(workspace) = self.workspace.upgrade() {
+            let fs = workspace.read(cx).app_state().fs.clone();
+            AllLanguageSettings::set_ai_assistance(enabled, fs, cx);
+
+            cx.notify();
+        }
+    }
+
     fn handle_jump_to_basics(
         &mut self,
         _: &JumpToBasics,
@@ -1083,9 +1099,7 @@ impl OnboardingUI {
         let focused_item = self.page_focus[page_index].0;
         let is_page_focused = self.focus_area == FocusArea::PageContent;
 
-        let ai_enabled = ai_enabled(cx);
-
-        let workspace = self.workspace.clone();
+        let ai_enabled = all_language_settings(None, cx).is_ai_assistance_enabled();
 
         v_flex()
             .h_full()
@@ -1103,17 +1117,7 @@ impl OnboardingUI {
                 } else {
                     ToggleState::Unselected
                 },
-                move |state, _, cx| {
-                    let enabled = state == &ToggleState::Selected;
-                    if let Some(workspace) = workspace.upgrade() {
-                        let fs = workspace.read(cx).app_state().fs.clone();
-                        update_settings_file::<AllLanguageSettings>(fs, cx, move |file, _| {
-                            file.features
-                                .get_or_insert(Default::default())
-                                .ai_assistance = Some(enabled);
-                        });
-                    }
-                },
+                cx.listener(Self::set_ai_assistance),
             )))
             .child(
                 CalloutRow::new("We don't use your code to train AI models")

crates/zed/src/zed.rs 🔗

@@ -221,29 +221,13 @@ pub fn init(cx: &mut App) {
     cx.on_action(|_: &EnableAiAssistance, cx| {
         with_active_or_new_workspace(cx, |workspace, _, cx| {
             let fs = workspace.app_state().fs.clone();
-            update_settings_file::<language::language_settings::AllLanguageSettings>(
-                fs,
-                cx,
-                move |file, _| {
-                    file.features
-                        .get_or_insert(Default::default())
-                        .ai_assistance = Some(true);
-                },
-            );
+            language::language_settings::AllLanguageSettings::set_ai_assistance(true, fs, cx);
         });
     });
     cx.on_action(|_: &DisableAiAssistance, cx| {
         with_active_or_new_workspace(cx, |workspace, _, cx| {
             let fs = workspace.app_state().fs.clone();
-            update_settings_file::<language::language_settings::AllLanguageSettings>(
-                fs,
-                cx,
-                move |file, _| {
-                    file.features
-                        .get_or_insert(Default::default())
-                        .ai_assistance = Some(false);
-                },
-            );
+            language::language_settings::AllLanguageSettings::set_ai_assistance(false, fs, cx);
         });
     });