From a13c2baa7fbf57b0555a7b787342d69c2d6626b4 Mon Sep 17 00:00:00 2001 From: Michael Sloan Date: Wed, 12 Feb 2025 17:46:53 -0700 Subject: [PATCH 1/4] Improve error message for `AcceptEditPredictions` - add docs link (#24772) The docs have not been updated yet, this is anticipating their presence soon. ![image](https://github.com/user-attachments/assets/bbcf56f2-6d5b-460b-8ed0-36bef3b4f12f) Release Notes: - N/A --- crates/editor/src/element.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index c6e55f483b352e5cd2872551ea154033011e6ea9..7b9585f30f9aaabc0ff114da9c4fa13cbb9a4877 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -5857,18 +5857,23 @@ impl KeyBindingValidator for AcceptEditPredictionsBindingValidator { } _ => {} } + let negated_requires_modifier_key_context = MarkdownString::inline_code(&format!( + "!{}", + EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT + )); Err(MarkdownString(format!( "{} can only be bound to a single keystroke with modifiers, so \ - that holding down these modifiers can be used to preview \ - completions inline when the completions menu is open.\n\n\ + that pressing these modifiers can be used for prediction \ + preview.\n\n\ This restriction does not apply when the context requires {}, \ - since these bindings will not be used when the completions menu \ - is open.", + since these bindings are not used for prediction preview. For \ + example, in the default keymap `tab` requires {}, and `alt-tab` \ + is used otherwise.\n\n\ + See [the documentation]({}) for more details.", MarkdownString::inline_code(AcceptEditPrediction.name()), - MarkdownString::inline_code(&format!( - "!{}", - EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT - )), + negated_requires_modifier_key_context.clone(), + negated_requires_modifier_key_context, + "https://zed.dev/docs/completions#edit-predictions", ))) } } From f0cd71e43c0254bac25c05b3c8ac56a7d1ab05d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 20:01:42 -0500 Subject: [PATCH 2/4] Update cloudflare/wrangler-action digest to 392082e (#24753) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [cloudflare/wrangler-action](https://redirect.github.com/cloudflare/wrangler-action) | action | digest | `7a5f8bb` -> `392082e` | --- ### Configuration 📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone America/New_York, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- Release Notes: - N/A Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/deploy_cloudflare.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy_cloudflare.yml b/.github/workflows/deploy_cloudflare.yml index b48b4c9a7af01ead14bc05bd053fbaab7ac9adfe..a155e65e4cd5529c5d96895c62b8235814794ebf 100644 --- a/.github/workflows/deploy_cloudflare.yml +++ b/.github/workflows/deploy_cloudflare.yml @@ -37,28 +37,28 @@ jobs: mdbook build ./docs --dest-dir=../target/deploy/docs/ - name: Deploy Docs - uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3 + uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: pages deploy target/deploy --project-name=docs - name: Deploy Install - uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3 + uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: r2 object put -f script/install.sh zed-open-source-website-assets/install.sh - name: Deploy Docs Workers - uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3 + uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: deploy .cloudflare/docs-proxy/src/worker.js - name: Deploy Install Workers - uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3 + uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} From 3d68dba696232658ae036f54a9507fc9e4484381 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:07:20 -0300 Subject: [PATCH 3/4] edit predictions: Iterate on onboarding modal copywriting (#24779) Release Notes: - N/A --------- Co-authored-by: Nathan Sobo <1789+nathansobo@users.noreply.github.com> --- assets/icons/zed_predict_bg.svg | 2 +- crates/zeta/src/onboarding_modal.rs | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/assets/icons/zed_predict_bg.svg b/assets/icons/zed_predict_bg.svg index 1332b2fdeceb0e43e84890a8237dac40d7e6eb5a..1dccbb51af0e61106318568898e626dbeea07ff6 100644 --- a/assets/icons/zed_predict_bg.svg +++ b/assets/icons/zed_predict_bg.svg @@ -1,4 +1,4 @@ - + diff --git a/crates/zeta/src/onboarding_modal.rs b/crates/zeta/src/onboarding_modal.rs index 9d7ad41a05aa0e29769cddf9a42734cad73e80cd..63aaa2b67200ce9843ce182223e42112748f9ca6 100644 --- a/crates/zeta/src/onboarding_modal.rs +++ b/crates/zeta/src/onboarding_modal.rs @@ -168,7 +168,7 @@ impl Render for ZedPredictModal { .id("edit-prediction-onboarding") .key_context("ZedPredictModal") .relative() - .w(px(480.)) + .w(px(550.)) .h_full() .max_h(max_height) .p_4() @@ -201,7 +201,7 @@ impl Render for ZedPredictModal { svg() .path("icons/zed_predict_bg.svg") .text_color(cx.theme().colors().icon_disabled) - .w(px(460.)) + .w(px(530.)) .h(px(128.)) .overflow_hidden(), ), @@ -285,7 +285,9 @@ impl Render for ZedPredictModal { if self.user_store.read(cx).current_user().is_some() { let copy = match self.sign_in_status { - SignInStatus::Idle => "Get accurate and instant edit predictions at every keystroke. Before setting Zed as your edit prediction provider:", + SignInStatus::Idle => { + "Zed can now predict your next edit on every keystroke. Powered by Zeta, our open-source, open-dataset language model." + } SignInStatus::SignedIn => "Almost there! Ensure you:", SignInStatus::Waiting => unreachable!(), }; @@ -327,7 +329,7 @@ impl Render for ZedPredictModal { .child( Checkbox::new("tos-checkbox", self.terms_of_service.into()) .fill() - .label("Read and accept the") + .label("I have read and accept the") .on_click(cx.listener(move |this, state, _window, cx| { this.terms_of_service = *state == ToggleState::Selected; cx.notify(); @@ -351,7 +353,7 @@ impl Render for ZedPredictModal { "training-data-checkbox", self.data_collection_opted_in.into(), ) - .label("Open source repos: optionally share training data.") + .label("Contribute to the open dataset when editing open source.") .fill() .on_click(cx.listener( move |this, state, _window, cx| { @@ -393,14 +395,14 @@ impl Render for ZedPredictModal { ) ) .child(info_item( - "We ask this exclusively for open source projects.", + "We collect data exclusively from open source projects.", )) .child(info_item( "Zed automatically detects if your project is open source.", )) - .child(info_item("Toggle it anytime via the status bar menu.")) + .child(info_item("Toggle participation at any time via the status bar menu.")) .child(multiline_info_item( - "If turned on, this setting is valid for all open source projects", + "If turned on, this setting applies for all open source repositories", label_item("you open in Zed.") )) .child(multiline_info_item( @@ -425,7 +427,7 @@ impl Render for ZedPredictModal { .gap_2() .w_full() .child( - Button::new("accept-tos", "Enable Edit Predictions") + Button::new("accept-tos", "Enable Edit Prediction") .disabled(!self.terms_of_service) .style(ButtonStyle::Tinted(TintColor::Accent)) .full_width() From 71867096c88a70dc1609005baa4389bba9e5f548 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 12 Feb 2025 18:35:25 -0800 Subject: [PATCH 4/4] Migrate edit_prediction_provider setting before updating its value to 'zed' during onboarding (#24781) This fixes a bug where we'd update your settings to an invalid state if you were using the old `inline_completion_provider` setting, then onboarded to Zeta, then migrated your settings. Release Notes: - N/A Co-authored-by: Michael Sloan Co-authored-by: Agus Zubiaga --- Cargo.lock | 2 ++ crates/migrator/src/migrator.rs | 48 +++++++++++++++++------------ crates/zeta/Cargo.toml | 2 ++ crates/zeta/src/onboarding_modal.rs | 16 ++++++++++ 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9653529d7ecf80679b66b7b97f32026b9430559d..a5661b189d9f4a0534d5fa99dbd1f2c0b592719b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17073,6 +17073,8 @@ dependencies = [ "language_models", "log", "menu", + "migrator", + "paths", "postage", "project", "regex", diff --git a/crates/migrator/src/migrator.rs b/crates/migrator/src/migrator.rs index c4eca930093df3c2707833b17ef3bb2a85419dd1..72576241f935825171678db8d9c6230f53693b3b 100644 --- a/crates/migrator/src/migrator.rs +++ b/crates/migrator/src/migrator.rs @@ -68,6 +68,17 @@ pub fn migrate_settings(text: &str) -> Result> { ) } +pub fn migrate_edit_prediction_provider_settings(text: &str) -> Result> { + migrate( + &text, + &[( + SETTINGS_REPLACE_NESTED_KEY, + replace_edit_prediction_provider_setting, + )], + &EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY, + ) +} + type MigrationPatterns = &'static [( &'static str, fn(&str, &QueryMatch, &Query) -> Option<(Range, String)>, @@ -550,7 +561,10 @@ pub static CONTEXT_REPLACE: LazyLock> = LazyLock::new(|| { const SETTINGS_MIGRATION_PATTERNS: MigrationPatterns = &[ (SETTINGS_STRING_REPLACE_QUERY, replace_setting_name), - (SETTINGS_REPLACE_NESTED_KEY, replace_setting_nested_key), + ( + SETTINGS_REPLACE_NESTED_KEY, + replace_edit_prediction_provider_setting, + ), ( SETTINGS_REPLACE_IN_LANGUAGES_QUERY, replace_setting_in_languages, @@ -568,6 +582,14 @@ static SETTINGS_MIGRATION_QUERY: LazyLock = LazyLock::new(|| { .unwrap() }); +static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock = LazyLock::new(|| { + Query::new( + &tree_sitter_json::LANGUAGE.into(), + SETTINGS_REPLACE_NESTED_KEY, + ) + .unwrap() +}); + const SETTINGS_STRING_REPLACE_QUERY: &str = r#"(document (object (pair @@ -622,7 +644,7 @@ const SETTINGS_REPLACE_NESTED_KEY: &str = r#" ) "#; -fn replace_setting_nested_key( +fn replace_edit_prediction_provider_setting( contents: &str, mat: &QueryMatch, query: &Query, @@ -641,27 +663,13 @@ fn replace_setting_nested_key( .byte_range(); let setting_name = contents.get(setting_range.clone())?; - let new_setting_name = SETTINGS_NESTED_STRING_REPLACE - .get(&parent_object_name)? - .get(setting_name)?; + if parent_object_name == "features" && setting_name == "inline_completion_provider" { + return Some((setting_range, "edit_prediction_provider".into())); + } - Some((setting_range, new_setting_name.to_string())) + None } -/// ```json -/// "features": { -/// "inline_completion_provider": "copilot" -/// }, -/// ``` -pub static SETTINGS_NESTED_STRING_REPLACE: LazyLock< - HashMap<&'static str, HashMap<&'static str, &'static str>>, -> = LazyLock::new(|| { - HashMap::from_iter([( - "features", - HashMap::from_iter([("inline_completion_provider", "edit_prediction_provider")]), - )]) -}); - const SETTINGS_REPLACE_IN_LANGUAGES_QUERY: &str = r#" (object (pair diff --git a/crates/zeta/Cargo.toml b/crates/zeta/Cargo.toml index 7e1f46c5fefa9ea6e1c21250a7971029be7b833b..f8f0bb4da3d4946b743d25c547ca6bc59eb1d099 100644 --- a/crates/zeta/Cargo.toml +++ b/crates/zeta/Cargo.toml @@ -36,6 +36,8 @@ language.workspace = true language_models.workspace = true log.workspace = true menu.workspace = true +migrator.workspace = true +paths.workspace = true postage.workspace = true project.workspace = true regex.workspace = true diff --git a/crates/zeta/src/onboarding_modal.rs b/crates/zeta/src/onboarding_modal.rs index 63aaa2b67200ce9843ce182223e42112748f9ca6..a9ad7469e049edc7f0a5cf39887726c4153e0554 100644 --- a/crates/zeta/src/onboarding_modal.rs +++ b/crates/zeta/src/onboarding_modal.rs @@ -1,6 +1,7 @@ use std::{sync::Arc, time::Duration}; use crate::{onboarding_event, ZED_PREDICT_DATA_COLLECTION_CHOICE}; +use anyhow::Context as _; use client::{Client, UserStore}; use db::kvp::KEY_VALUE_STORE; use feature_flags::FeatureFlagAppExt as _; @@ -83,6 +84,7 @@ impl ZedPredictModal { let task = self .user_store .update(cx, |this, cx| this.accept_terms_of_service(cx)); + let fs = self.fs.clone(); cx.spawn(|this, mut cx| async move { task.await?; @@ -101,6 +103,20 @@ impl ZedPredictModal { .await .log_err(); + // Make sure edit prediction provider setting is using the new key + let settings_path = paths::settings_file().as_path(); + let settings_path = fs.canonicalize(settings_path).await.with_context(|| { + format!("Failed to canonicalize settings path {:?}", settings_path) + })?; + + if let Some(settings) = fs.load(&settings_path).await.log_err() { + if let Some(new_settings) = + migrator::migrate_edit_prediction_provider_settings(&settings)? + { + fs.atomic_write(settings_path, new_settings).await?; + } + } + this.update(&mut cx, |this, cx| { update_settings_file::(this.fs.clone(), cx, move |file, _| { file.features