Detailed changes
@@ -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 }}
@@ -17073,6 +17073,8 @@ dependencies = [
"language_models",
"log",
"menu",
+ "migrator",
+ "paths",
"postage",
"project",
"regex",
@@ -1,4 +1,4 @@
-<svg width="480" height="128" xmlns="http://www.w3.org/2000/svg">
+<svg width="550" height="128" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="tilePattern" width="23" height="23" patternUnits="userSpaceOnUse">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -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",
)))
}
}
@@ -68,6 +68,17 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
)
}
+pub fn migrate_edit_prediction_provider_settings(text: &str) -> Result<Option<String>> {
+ 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<usize>, String)>,
@@ -550,7 +561,10 @@ pub static CONTEXT_REPLACE: LazyLock<HashMap<&str, &str>> = 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<Query> = LazyLock::new(|| {
.unwrap()
});
+static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock<Query> = 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
@@ -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
@@ -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::<AllLanguageSettings>(this.fs.clone(), cx, move |file, _| {
file.features
@@ -168,7 +184,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 +217,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 +301,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 +345,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 +369,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 +411,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 +443,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()