From ce3b1b5d1488d4968f772aacd6caca792d274a92 Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 02:05:54 +0000 Subject: [PATCH] Migrate `features.edit_prediction_provider` to `edit_predictions.provider` (#48224) (cherry-pick to preview) (#48232) Cherry-pick of #48224 to preview ---- Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... Co-authored-by: Ben Kunkle --- assets/settings/default.json | 7 +- crates/agent_ui/src/agent_ui.rs | 8 +- crates/edit_prediction/src/edit_prediction.rs | 4 +- .../edit_prediction/src/onboarding_modal.rs | 4 +- .../src/edit_prediction_button.rs | 8 +- crates/language/src/language_settings.rs | 4 +- crates/migrator/src/migrations.rs | 6 + .../src/migrations/m_2026_02_02/settings.rs | 40 ++++++ crates/migrator/src/migrator.rs | 134 ++++++++++++++++-- crates/settings/src/vscode_import.rs | 1 - crates/settings_content/src/language.rs | 14 +- 11 files changed, 186 insertions(+), 44 deletions(-) create mode 100644 crates/migrator/src/migrations/m_2026_02_02/settings.rs diff --git a/assets/settings/default.json b/assets/settings/default.json index bebb1f18d58e192f69a709a1362e3aa8490759ac..04f8d65fed340d1fcec09c3287586c41a31156b2 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -26,11 +26,6 @@ // 5. "SublimeText" // 6. "TextMate" "base_keymap": "VSCode", - // Features that can be globally enabled or disabled - "features": { - // Which edit prediction provider to use. - "edit_prediction_provider": "zed", - }, // The name of a font to use for rendering text in the editor // ".ZedMono" currently aliases to Lilex // but this may change in the future. @@ -1501,6 +1496,8 @@ // "load_direnv": "disabled" "load_direnv": "direct", "edit_predictions": { + // Which edit prediction provider to use. + "provider": "zed", // A list of globs representing files that edit predictions should be disabled for. // There's a sensible default list of globs already included. // Any addition to this list will be merged with the default list. diff --git a/crates/agent_ui/src/agent_ui.rs b/crates/agent_ui/src/agent_ui.rs index bb39ce96c343d96b81331957d478ed5fccedd026..36b17b514fe10aa952ae976b92b78389d1556923 100644 --- a/crates/agent_ui/src/agent_ui.rs +++ b/crates/agent_ui/src/agent_ui.rs @@ -590,9 +590,9 @@ mod tests { store.update_user_settings(cx, |s| { s.project .all_languages - .features + .edit_predictions .get_or_insert(Default::default()) - .edit_prediction_provider = Some(EditPredictionProvider::Copilot); + .provider = Some(EditPredictionProvider::Copilot); }); }); update_command_palette_filter(cx); @@ -612,9 +612,9 @@ mod tests { store.update_user_settings(cx, |s| { s.project .all_languages - .features + .edit_predictions .get_or_insert(Default::default()) - .edit_prediction_provider = Some(EditPredictionProvider::None); + .provider = Some(EditPredictionProvider::None); }); }); update_command_palette_filter(cx); diff --git a/crates/edit_prediction/src/edit_prediction.rs b/crates/edit_prediction/src/edit_prediction.rs index 74c749ac193a0077f64adbe3277a691f20499ab4..87a0052f6cc2fee879dacf40f0ce18404575c460 100644 --- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -2333,9 +2333,9 @@ pub fn init(cx: &mut App) { settings .project .all_languages - .features + .edit_predictions .get_or_insert_default() - .edit_prediction_provider = Some(EditPredictionProvider::None) + .provider = Some(EditPredictionProvider::None) }); }); fn copilot_for_project(project: &Entity, cx: &mut App) -> Option> { diff --git a/crates/edit_prediction/src/onboarding_modal.rs b/crates/edit_prediction/src/onboarding_modal.rs index e4c4b2c973457665b2df5288ff71533d0aa1edef..a09310d3df20b40cbd1b3ce6a52b2cbf376f7216 100644 --- a/crates/edit_prediction/src/onboarding_modal.rs +++ b/crates/edit_prediction/src/onboarding_modal.rs @@ -36,9 +36,9 @@ pub(crate) fn set_edit_prediction_provider(provider: EditPredictionProvider, cx: settings .project .all_languages - .features + .edit_predictions .get_or_insert(Default::default()) - .edit_prediction_provider = Some(provider); + .provider = Some(provider); }); } diff --git a/crates/edit_prediction_ui/src/edit_prediction_button.rs b/crates/edit_prediction_ui/src/edit_prediction_button.rs index 6668df82aea5ac8d7515dbdb94a4c40ddd0c95cf..d38d93eab1f52f1a08174a994f039edb09c8810a 100644 --- a/crates/edit_prediction_ui/src/edit_prediction_button.rs +++ b/crates/edit_prediction_ui/src/edit_prediction_button.rs @@ -1276,9 +1276,9 @@ pub fn set_completion_provider(fs: Arc, cx: &mut App, provider: EditPred settings .project .all_languages - .features + .edit_predictions .get_or_insert_default() - .edit_prediction_provider = Some(provider); + .provider = Some(provider); }); } @@ -1359,9 +1359,9 @@ fn hide_copilot(fs: Arc, cx: &mut App) { settings .project .all_languages - .features + .edit_predictions .get_or_insert(Default::default()) - .edit_prediction_provider = Some(EditPredictionProvider::None); + .provider = Some(EditPredictionProvider::None); }); } diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index a7e678e6ee43a3cac0a4ea388923f8341adbb86e..e81124ed6d85f544295bb15db3296ba2621fdb7d 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -645,9 +645,9 @@ impl settings::Settings for AllLanguageSettings { } let edit_prediction_provider = all_languages - .features + .edit_predictions .as_ref() - .and_then(|f| f.edit_prediction_provider); + .and_then(|ep| ep.provider); let edit_predictions = all_languages.edit_predictions.clone().unwrap(); let edit_predictions_mode = edit_predictions.mode.unwrap(); diff --git a/crates/migrator/src/migrations.rs b/crates/migrator/src/migrations.rs index c25e240b358132074efca4d79ada3c0819263fd2..de22132176e508a027287a48d868d30aab51a495 100644 --- a/crates/migrator/src/migrations.rs +++ b/crates/migrator/src/migrations.rs @@ -165,3 +165,9 @@ pub(crate) mod m_2025_12_15 { pub(crate) use settings::SETTINGS_PATTERNS; } + +pub(crate) mod m_2026_02_02 { + mod settings; + + pub(crate) use settings::move_edit_prediction_provider_to_edit_predictions; +} diff --git a/crates/migrator/src/migrations/m_2026_02_02/settings.rs b/crates/migrator/src/migrations/m_2026_02_02/settings.rs new file mode 100644 index 0000000000000000000000000000000000000000..f28f34969172201245f2d20349855c0e2b8e54ae --- /dev/null +++ b/crates/migrator/src/migrations/m_2026_02_02/settings.rs @@ -0,0 +1,40 @@ +use anyhow::Result; +use serde_json::Value; + +pub fn move_edit_prediction_provider_to_edit_predictions(value: &mut Value) -> Result<()> { + let Some(obj) = value.as_object_mut() else { + return Ok(()); + }; + + let Some(features) = obj.get_mut("features") else { + return Ok(()); + }; + + let Some(features_obj) = features.as_object_mut() else { + return Ok(()); + }; + + let Some(provider) = features_obj.remove("edit_prediction_provider") else { + return Ok(()); + }; + + let features_is_empty = features_obj.is_empty(); + + if features_is_empty { + obj.remove("features"); + } + + let edit_predictions = obj + .entry("edit_predictions") + .or_insert_with(|| Value::Object(Default::default())); + + let Some(edit_predictions_obj) = edit_predictions.as_object_mut() else { + anyhow::bail!("Expected edit_predictions to be an object"); + }; + + if !edit_predictions_obj.contains_key("provider") { + edit_predictions_obj.insert("provider".to_string(), provider); + } + + Ok(()) +} diff --git a/crates/migrator/src/migrator.rs b/crates/migrator/src/migrator.rs index 01772569d5a70c8acfdae04f228516cd0740139a..cb0560dd40e49e91df32ce194944dc5b5d4df5e0 100644 --- a/crates/migrator/src/migrator.rs +++ b/crates/migrator/src/migrator.rs @@ -232,6 +232,9 @@ pub fn migrate_settings(text: &str) -> Result> { migrations::m_2025_12_15::SETTINGS_PATTERNS, &SETTINGS_QUERY_2025_12_15, ), + MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + ), ]; run_migrations(text, migrations) } @@ -650,21 +653,23 @@ mod tests { #[test] fn test_nested_string_replace_for_settings() { assert_migrate_settings( - r#" - { - "features": { - "inline_completion_provider": "zed" - }, - } - "#, + &r#" + { + "features": { + "inline_completion_provider": "zed" + }, + } + "# + .unindent(), Some( - r#" + &r#" { - "features": { - "edit_prediction_provider": "zed" - }, + "edit_predictions": { + "provider": "zed" + } } - "#, + "# + .unindent(), ), ) } @@ -2360,4 +2365,109 @@ mod tests { ), ); } + + #[test] + fn test_move_edit_prediction_provider_to_edit_predictions() { + assert_migrate_settings_with_migrations( + &[MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + )], + &r#"{ }"#.unindent(), + None, + ); + + assert_migrate_settings_with_migrations( + &[MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + )], + &r#" + { + "features": { + "edit_prediction_provider": "copilot" + } + } + "# + .unindent(), + Some( + &r#" + { + "edit_predictions": { + "provider": "copilot" + } + } + "# + .unindent(), + ), + ); + + assert_migrate_settings_with_migrations( + &[MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + )], + &r#" + { + "features": { + "edit_prediction_provider": "zed" + }, + "edit_predictions": { + "mode": "eager" + } + } + "# + .unindent(), + Some( + &r#" + { + "edit_predictions": { + "provider": "zed", + "mode": "eager" + } + } + "# + .unindent(), + ), + ); + + assert_migrate_settings_with_migrations( + &[MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + )], + &r#" + { + "features": { + "edit_prediction_provider": "supermaven" + }, + "edit_predictions": { + "provider": "copilot" + } + } + "# + .unindent(), + Some( + &r#" + { + "edit_predictions": { + "provider": "copilot" + } + } + "# + .unindent(), + ), + ); + + assert_migrate_settings_with_migrations( + &[MigrationType::Json( + migrations::m_2026_02_02::move_edit_prediction_provider_to_edit_predictions, + )], + &r#" + { + "edit_predictions": { + "provider": "zed" + } + } + "# + .unindent(), + None, + ); + } } diff --git a/crates/settings/src/vscode_import.rs b/crates/settings/src/vscode_import.rs index de8e266dd5581c60ff9f655dc73afec3f0173d4b..a686b8ca127045701c8003532d249ed6a5ff78e6 100644 --- a/crates/settings/src/vscode_import.rs +++ b/crates/settings/src/vscode_import.rs @@ -392,7 +392,6 @@ impl VsCodeSettings { fn project_settings_content(&self) -> ProjectSettingsContent { ProjectSettingsContent { all_languages: AllLanguageSettingsContent { - features: None, edit_predictions: self.edit_predictions_settings_content(), defaults: self.default_language_settings_content(), languages: Default::default(), diff --git a/crates/settings_content/src/language.rs b/crates/settings_content/src/language.rs index aad7a27879de3219ce5d7734068ec6feb1796983..c16deacc520eb87a5be6eaee05233de365a183bb 100644 --- a/crates/settings_content/src/language.rs +++ b/crates/settings_content/src/language.rs @@ -34,8 +34,6 @@ pub struct ModifiersContent { #[with_fallible_options] #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct AllLanguageSettingsContent { - /// The settings for enabling/disabling features. - pub features: Option, /// The edit prediction settings. pub edit_predictions: Option, /// The default language settings. @@ -52,7 +50,6 @@ pub struct AllLanguageSettingsContent { impl merge_from::MergeFrom for AllLanguageSettingsContent { fn merge_from(&mut self, other: &Self) { self.file_types.merge_from(&other.file_types); - self.features.merge_from(&other.features); self.edit_predictions.merge_from(&other.edit_predictions); // A user's global settings override the default global settings and @@ -77,15 +74,6 @@ impl merge_from::MergeFrom for AllLanguageSettingsContent { } } -/// The settings for enabling/disabling features. -#[with_fallible_options] -#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)] -#[serde(rename_all = "snake_case")] -pub struct FeaturesContent { - /// Determines which edit prediction provider to use. - pub edit_prediction_provider: Option, -} - /// The provider that supplies edit predictions. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, JsonSchema, MergeFrom)] #[serde(rename_all = "snake_case")] @@ -192,6 +180,8 @@ impl EditPredictionProvider { #[with_fallible_options] #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] pub struct EditPredictionSettingsContent { + /// Determines which edit prediction provider to use. + pub provider: Option, /// A list of globs representing files that edit predictions should be disabled for. /// This list adds to a pre-existing, sensible default set of globs. /// Any additional ones you add are combined with them.