diff --git a/.github/actions/check_formatting/action.yml b/.github/actions/check_formatting/action.yml
new file mode 100644
index 0000000000..7fef26407b
--- /dev/null
+++ b/.github/actions/check_formatting/action.yml
@@ -0,0 +1,15 @@
+name: 'Check formatting'
+description: 'Checks code formatting use cargo fmt'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Install Rust
+ shell: bash -euxo pipefail {0}
+ run: |
+ rustup set profile minimal
+ rustup update stable
+
+ - name: cargo fmt
+ shell: bash -euxo pipefail {0}
+ run: cargo fmt --all -- --check
diff --git a/.github/actions/run_tests/action.yml b/.github/actions/run_tests/action.yml
new file mode 100644
index 0000000000..de5eadb61a
--- /dev/null
+++ b/.github/actions/run_tests/action.yml
@@ -0,0 +1,34 @@
+name: "Run tests"
+description: "Runs the tests"
+
+runs:
+ using: "composite"
+ steps:
+ - name: Install Rust
+ shell: bash -euxo pipefail {0}
+ run: |
+ rustup set profile minimal
+ rustup update stable
+ rustup target add wasm32-wasi
+ cargo install cargo-nextest
+
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+
+ - name: Limit target directory size
+ shell: bash -euxo pipefail {0}
+ run: script/clear-target-dir-if-larger-than 70
+
+ - name: Run check
+ env:
+ RUSTFLAGS: -D warnings
+ shell: bash -euxo pipefail {0}
+ run: cargo check --tests --workspace
+
+ - name: Run tests
+ env:
+ RUSTFLAGS: -D warnings
+ shell: bash -euxo pipefail {0}
+ run: cargo nextest run --workspace --no-fail-fast
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 60dc4c1f52..65475a41b9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,19 +23,14 @@ jobs:
- self-hosted
- test
steps:
- - name: Install Rust
- run: |
- rustup set profile minimal
- rustup update stable
-
- name: Checkout repo
uses: actions/checkout@v3
with:
clean: false
submodules: "recursive"
- - name: cargo fmt
- run: cargo fmt --all -- --check
+ - name: Run rustfmt
+ uses: ./.github/actions/check_formatting
tests:
name: Run tests
@@ -43,35 +38,15 @@ jobs:
- self-hosted
- test
needs: rustfmt
- env:
- RUSTFLAGS: -D warnings
steps:
- - name: Install Rust
- run: |
- rustup set profile minimal
- rustup update stable
- rustup target add wasm32-wasi
- cargo install cargo-nextest
-
- - name: Install Node
- uses: actions/setup-node@v3
- with:
- node-version: "18"
-
- name: Checkout repo
uses: actions/checkout@v3
with:
clean: false
submodules: "recursive"
- - name: Limit target directory size
- run: script/clear-target-dir-if-larger-than 70
-
- - name: Run check
- run: cargo check --workspace
-
- name: Run tests
- run: cargo nextest run --workspace --no-fail-fast
+ uses: ./.github/actions/run_tests
- name: Build collab
run: cargo build -p collab
@@ -130,6 +105,8 @@ jobs:
expected_tag_name="v${version}";;
preview)
expected_tag_name="v${version}-pre";;
+ nightly)
+ expected_tag_name="v${version}-nightly";;
*)
echo "can't publish a release on channel ${channel}"
exit 1;;
@@ -154,7 +131,9 @@ jobs:
- uses: softprops/action-gh-release@v1
name: Upload app bundle to release
- if: ${{ env.RELEASE_CHANNEL }}
+ # TODO kb seems that zed.dev relies on GitHub releases for release version tracking.
+ # Find alternatives for `nightly` or just go on with more releases?
+ if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml
new file mode 100644
index 0000000000..447e928866
--- /dev/null
+++ b/.github/workflows/release_nightly.yml
@@ -0,0 +1,98 @@
+name: Release Nightly
+
+on:
+ schedule:
+ # Fire every night at 1:00am
+ - cron: "0 1 * * *"
+ push:
+ tags:
+ - "nightly"
+
+env:
+ CARGO_TERM_COLOR: always
+ CARGO_INCREMENTAL: 0
+ RUST_BACKTRACE: 1
+
+jobs:
+ rustfmt:
+ name: Check formatting
+ runs-on:
+ - self-hosted
+ - test
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v3
+ with:
+ clean: false
+ submodules: "recursive"
+
+ - name: Run rustfmt
+ uses: ./.github/actions/check_formatting
+
+ tests:
+ name: Run tests
+ runs-on:
+ - self-hosted
+ - test
+ needs: rustfmt
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v3
+ with:
+ clean: false
+ submodules: "recursive"
+
+ - name: Run tests
+ uses: ./.github/actions/run_tests
+
+ bundle:
+ name: Bundle app
+ runs-on:
+ - self-hosted
+ - bundle
+ needs: tests
+ env:
+ MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
+ MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
+ APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
+ APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
+ DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
+ DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
+ steps:
+ - name: Install Rust
+ run: |
+ rustup set profile minimal
+ rustup update stable
+ rustup target add aarch64-apple-darwin
+ rustup target add x86_64-apple-darwin
+ rustup target add wasm32-wasi
+
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+
+ - name: Checkout repo
+ uses: actions/checkout@v3
+ with:
+ clean: false
+ submodules: "recursive"
+
+ - name: Limit target directory size
+ run: script/clear-target-dir-if-larger-than 70
+
+ - name: Set release channel to nightly
+ run: |
+ set -eu
+ version=$(git rev-parse --short HEAD)
+ echo "Publishing version: ${version} on release channel nightly"
+ echo "nightly" > crates/zed/RELEASE_CHANNEL
+
+ - name: Generate license file
+ run: script/generate-licenses
+
+ - name: Create app bundle
+ run: script/bundle -2
+
+ - name: Upload Zed Nightly
+ run: script/upload-nightly
diff --git a/Cargo.lock b/Cargo.lock
index f359702b57..cc1034b9fb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -724,6 +724,30 @@ dependencies = [
"workspace",
]
+[[package]]
+name = "auto_update2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "client2",
+ "db2",
+ "gpui2",
+ "isahc",
+ "lazy_static",
+ "log",
+ "menu2",
+ "project2",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "settings2",
+ "smol",
+ "tempdir",
+ "theme2",
+ "util",
+ "workspace2",
+]
+
[[package]]
name = "autocfg"
version = "1.1.0"
@@ -1526,6 +1550,7 @@ dependencies = [
"anyhow",
"async-recursion 0.3.2",
"async-tungstenite",
+ "chrono",
"collections",
"db",
"feature_flags",
@@ -1562,6 +1587,7 @@ dependencies = [
"anyhow",
"async-recursion 0.3.2",
"async-tungstenite",
+ "chrono",
"collections",
"db2",
"feature_flags2",
@@ -2614,6 +2640,34 @@ dependencies = [
"workspace",
]
+[[package]]
+name = "diagnostics2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "client2",
+ "collections",
+ "editor2",
+ "futures 0.3.28",
+ "gpui2",
+ "language2",
+ "log",
+ "lsp2",
+ "postage",
+ "project2",
+ "schemars",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "settings2",
+ "smallvec",
+ "theme2",
+ "ui2",
+ "unindent",
+ "util",
+ "workspace2",
+]
+
[[package]]
name = "diff"
version = "0.1.13"
@@ -3759,7 +3813,7 @@ dependencies = [
"smol",
"sqlez",
"sum_tree",
- "taffy",
+ "taffy 0.3.11 (git+https://github.com/DioxusLabs/taffy?rev=4fb530bdd71609bb1d3f76c6a8bde1ba82805d5e)",
"thiserror",
"time",
"tiny-skia",
@@ -3824,7 +3878,7 @@ dependencies = [
"smol",
"sqlez",
"sum_tree",
- "taffy",
+ "taffy 0.3.11 (git+https://github.com/DioxusLabs/taffy?rev=1876f72bee5e376023eaa518aa7b8a34c769bd1b)",
"thiserror",
"time",
"tiny-skia",
@@ -3859,6 +3913,12 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eec1c01eb1de97451ee0d60de7d81cf1e72aabefb021616027f3d1c3ec1c723c"
+[[package]]
+name = "grid"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df00eed8d1f0db937f6be10e46e8072b0671accb504cf0f959c5c52c679f5b9"
+
[[package]]
name = "h2"
version = "0.3.21"
@@ -4486,7 +4546,7 @@ dependencies = [
"anyhow",
"chrono",
"dirs 4.0.0",
- "editor",
+ "editor2",
"gpui2",
"log",
"schemars",
@@ -9082,13 +9142,24 @@ dependencies = [
"winx",
]
+[[package]]
+name = "taffy"
+version = "0.3.11"
+source = "git+https://github.com/DioxusLabs/taffy?rev=1876f72bee5e376023eaa518aa7b8a34c769bd1b#1876f72bee5e376023eaa518aa7b8a34c769bd1b"
+dependencies = [
+ "arrayvec 0.7.4",
+ "grid 0.11.0",
+ "num-traits",
+ "slotmap",
+]
+
[[package]]
name = "taffy"
version = "0.3.11"
source = "git+https://github.com/DioxusLabs/taffy?rev=4fb530bdd71609bb1d3f76c6a8bde1ba82805d5e#4fb530bdd71609bb1d3f76c6a8bde1ba82805d5e"
dependencies = [
"arrayvec 0.7.4",
- "grid",
+ "grid 0.10.0",
"num-traits",
"slotmap",
]
@@ -11572,6 +11643,7 @@ dependencies = [
"async-recursion 0.3.2",
"async-tar",
"async-trait",
+ "auto_update2",
"backtrace",
"call2",
"chrono",
@@ -11583,6 +11655,7 @@ dependencies = [
"copilot2",
"ctor",
"db2",
+ "diagnostics2",
"editor2",
"env_logger 0.9.3",
"feature_flags2",
@@ -11600,7 +11673,6 @@ dependencies = [
"isahc",
"journal2",
"language2",
- "language_tools",
"lazy_static",
"libc",
"log",
diff --git a/Cargo.toml b/Cargo.toml
index 792a3ada56..50728c0a8f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,6 +6,7 @@ members = [
"crates/audio",
"crates/audio2",
"crates/auto_update",
+ "crates/auto_update2",
"crates/breadcrumbs",
"crates/call",
"crates/call2",
@@ -32,6 +33,7 @@ members = [
"crates/refineable",
"crates/refineable/derive_refineable",
"crates/diagnostics",
+ "crates/diagnostics2",
"crates/drag_and_drop",
"crates/editor",
"crates/feature_flags",
diff --git a/assets/icons/warning.svg b/assets/icons/warning.svg
index e581def0d0..c48a575a90 100644
--- a/assets/icons/warning.svg
+++ b/assets/icons/warning.svg
@@ -1,6 +1 @@
-
+
diff --git a/assets/settings/default.json b/assets/settings/default.json
index 08d85dd723..bf2acc708e 100644
--- a/assets/settings/default.json
+++ b/assets/settings/default.json
@@ -268,6 +268,19 @@
// Whether to show warnings or not by default.
"include_warnings": true
},
+ // Add files or globs of files that will be excluded by Zed entirely:
+ // they will be skipped during FS scan(s), file tree and file search
+ // will lack the corresponding file entries.
+ "file_scan_exclusions": [
+ "**/.git",
+ "**/.svn",
+ "**/.hg",
+ "**/CVS",
+ "**/.DS_Store",
+ "**/Thumbs.db",
+ "**/.classpath",
+ "**/.settings"
+ ],
// Git gutter behavior configuration.
"git": {
// Control whether the git gutter is shown. May take 2 values:
diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs
index 6ab96093a7..cac8bf6c54 100644
--- a/crates/assistant/src/assistant_panel.rs
+++ b/crates/assistant/src/assistant_panel.rs
@@ -15,7 +15,7 @@ use ai::{
use ai::prompts::repository_context::PromptCodeSnippet;
use anyhow::{anyhow, Result};
use chrono::{DateTime, Local};
-use client::{telemetry::AssistantKind, ClickhouseEvent, TelemetrySettings};
+use client::{telemetry::AssistantKind, TelemetrySettings};
use collections::{hash_map, HashMap, HashSet, VecDeque};
use editor::{
display_map::{
@@ -3803,12 +3803,12 @@ fn report_assistant_event(
.default_open_ai_model
.clone();
- let event = ClickhouseEvent::Assistant {
- conversation_id,
- kind: assistant_kind,
- model: model.full_name(),
- };
let telemetry_settings = *settings::get::(cx);
- telemetry.report_clickhouse_event(event, telemetry_settings)
+ telemetry.report_assistant_event(
+ telemetry_settings,
+ conversation_id,
+ assistant_kind,
+ model.full_name(),
+ )
}
diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs
index 0d537b882a..cf285ac7cf 100644
--- a/crates/auto_update/src/auto_update.rs
+++ b/crates/auto_update/src/auto_update.rs
@@ -118,14 +118,18 @@ fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) {
let auto_updater = auto_updater.read(cx);
let server_url = &auto_updater.server_url;
let current_version = auto_updater.current_version;
- let latest_release_url = if cx.has_global::()
- && *cx.global::() == ReleaseChannel::Preview
- {
- format!("{server_url}/releases/preview/{current_version}")
- } else {
- format!("{server_url}/releases/stable/{current_version}")
- };
- cx.platform().open_url(&latest_release_url);
+ if cx.has_global::() {
+ match cx.global::() {
+ ReleaseChannel::Dev => {}
+ ReleaseChannel::Nightly => {}
+ ReleaseChannel::Preview => cx
+ .platform()
+ .open_url(&format!("{server_url}/releases/preview/{current_version}")),
+ ReleaseChannel::Stable => cx
+ .platform()
+ .open_url(&format!("{server_url}/releases/stable/{current_version}")),
+ }
+ }
}
}
@@ -224,22 +228,19 @@ impl AutoUpdater {
)
});
- let preview_param = cx.read(|cx| {
+ let mut url_string = format!(
+ "{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg"
+ );
+ cx.read(|cx| {
if cx.has_global::() {
- if *cx.global::() == ReleaseChannel::Preview {
- return "&preview=1";
+ if let Some(param) = cx.global::().release_query_param() {
+ url_string += "&";
+ url_string += param;
}
}
- ""
});
- let mut response = client
- .get(
- &format!("{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg{preview_param}"),
- Default::default(),
- true,
- )
- .await?;
+ let mut response = client.get(&url_string, Default::default(), true).await?;
let mut body = Vec::new();
response
diff --git a/crates/auto_update2/Cargo.toml b/crates/auto_update2/Cargo.toml
new file mode 100644
index 0000000000..20eb129746
--- /dev/null
+++ b/crates/auto_update2/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "auto_update2"
+version = "0.1.0"
+edition = "2021"
+publish = false
+
+[lib]
+path = "src/auto_update.rs"
+doctest = false
+
+[dependencies]
+db = { package = "db2", path = "../db2" }
+client = { package = "client2", path = "../client2" }
+gpui = { package = "gpui2", path = "../gpui2" }
+menu = { package = "menu2", path = "../menu2" }
+project = { package = "project2", path = "../project2" }
+settings = { package = "settings2", path = "../settings2" }
+theme = { package = "theme2", path = "../theme2" }
+workspace = { package = "workspace2", path = "../workspace2" }
+util = { path = "../util" }
+anyhow.workspace = true
+isahc.workspace = true
+lazy_static.workspace = true
+log.workspace = true
+serde.workspace = true
+serde_derive.workspace = true
+serde_json.workspace = true
+smol.workspace = true
+tempdir.workspace = true
diff --git a/crates/auto_update2/src/auto_update.rs b/crates/auto_update2/src/auto_update.rs
new file mode 100644
index 0000000000..aeff68965f
--- /dev/null
+++ b/crates/auto_update2/src/auto_update.rs
@@ -0,0 +1,406 @@
+mod update_notification;
+
+use anyhow::{anyhow, Context, Result};
+use client::{Client, TelemetrySettings, ZED_APP_PATH, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN};
+use db::kvp::KEY_VALUE_STORE;
+use db::RELEASE_CHANNEL;
+use gpui::{
+ actions, AppContext, AsyncAppContext, Context as _, Model, ModelContext, SemanticVersion, Task,
+ ViewContext, VisualContext,
+};
+use isahc::AsyncBody;
+use serde::Deserialize;
+use serde_derive::Serialize;
+use smol::io::AsyncReadExt;
+
+use settings::{Settings, SettingsStore};
+use smol::{fs::File, process::Command};
+use std::{ffi::OsString, sync::Arc, time::Duration};
+use update_notification::UpdateNotification;
+use util::channel::{AppCommitSha, ReleaseChannel};
+use util::http::HttpClient;
+use workspace::Workspace;
+
+const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
+const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
+
+//todo!(remove CheckThatAutoUpdaterWorks)
+actions!(
+ Check,
+ DismissErrorMessage,
+ ViewReleaseNotes,
+ CheckThatAutoUpdaterWorks
+);
+
+#[derive(Serialize)]
+struct UpdateRequestBody {
+ installation_id: Option>,
+ release_channel: Option<&'static str>,
+ telemetry: bool,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum AutoUpdateStatus {
+ Idle,
+ Checking,
+ Downloading,
+ Installing,
+ Updated,
+ Errored,
+}
+
+pub struct AutoUpdater {
+ status: AutoUpdateStatus,
+ current_version: SemanticVersion,
+ http_client: Arc,
+ pending_poll: Option>>,
+ server_url: String,
+}
+
+#[derive(Deserialize)]
+struct JsonRelease {
+ version: String,
+ url: String,
+}
+
+struct AutoUpdateSetting(bool);
+
+impl Settings for AutoUpdateSetting {
+ const KEY: Option<&'static str> = Some("auto_update");
+
+ type FileContent = Option;
+
+ fn load(
+ default_value: &Option,
+ user_values: &[&Option],
+ _: &mut AppContext,
+ ) -> Result {
+ Ok(Self(
+ Self::json_merge(default_value, user_values)?.ok_or_else(Self::missing_default)?,
+ ))
+ }
+}
+
+pub fn init(http_client: Arc, server_url: String, cx: &mut AppContext) {
+ AutoUpdateSetting::register(cx);
+
+ cx.observe_new_views(|wokrspace: &mut Workspace, _cx| {
+ wokrspace
+ .register_action(|_, action: &Check, cx| check(action, cx))
+ .register_action(|_, _action: &CheckThatAutoUpdaterWorks, cx| {
+ let prompt = cx.prompt(gpui::PromptLevel::Info, "It does!", &["Ok"]);
+ cx.spawn(|_, _cx| async move {
+ prompt.await.ok();
+ })
+ .detach();
+ });
+ })
+ .detach();
+
+ if let Some(version) = *ZED_APP_VERSION {
+ let auto_updater = cx.build_model(|cx| {
+ let updater = AutoUpdater::new(version, http_client, server_url);
+
+ let mut update_subscription = AutoUpdateSetting::get_global(cx)
+ .0
+ .then(|| updater.start_polling(cx));
+
+ cx.observe_global::(move |updater, cx| {
+ if AutoUpdateSetting::get_global(cx).0 {
+ if update_subscription.is_none() {
+ update_subscription = Some(updater.start_polling(cx))
+ }
+ } else {
+ update_subscription.take();
+ }
+ })
+ .detach();
+
+ updater
+ });
+ cx.set_global(Some(auto_updater));
+ //todo!(action)
+ // cx.add_global_action(view_release_notes);
+ // cx.add_action(UpdateNotification::dismiss);
+ }
+}
+
+pub fn check(_: &Check, cx: &mut AppContext) {
+ if let Some(updater) = AutoUpdater::get(cx) {
+ updater.update(cx, |updater, cx| updater.poll(cx));
+ }
+}
+
+fn _view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) {
+ if let Some(auto_updater) = AutoUpdater::get(cx) {
+ let auto_updater = auto_updater.read(cx);
+ let server_url = &auto_updater.server_url;
+ let current_version = auto_updater.current_version;
+ if cx.has_global::() {
+ match cx.global::() {
+ ReleaseChannel::Dev => {}
+ ReleaseChannel::Nightly => {}
+ ReleaseChannel::Preview => {
+ cx.open_url(&format!("{server_url}/releases/preview/{current_version}"))
+ }
+ ReleaseChannel::Stable => {
+ cx.open_url(&format!("{server_url}/releases/stable/{current_version}"))
+ }
+ }
+ }
+ }
+}
+
+pub fn notify_of_any_new_update(cx: &mut ViewContext) -> Option<()> {
+ let updater = AutoUpdater::get(cx)?;
+ let version = updater.read(cx).current_version;
+ let should_show_notification = updater.read(cx).should_show_update_notification(cx);
+
+ cx.spawn(|workspace, mut cx| async move {
+ let should_show_notification = should_show_notification.await?;
+ if should_show_notification {
+ workspace.update(&mut cx, |workspace, cx| {
+ workspace.show_notification(0, cx, |cx| {
+ cx.build_view(|_| UpdateNotification::new(version))
+ });
+ updater
+ .read(cx)
+ .set_should_show_update_notification(false, cx)
+ .detach_and_log_err(cx);
+ })?;
+ }
+ anyhow::Ok(())
+ })
+ .detach();
+
+ None
+}
+
+impl AutoUpdater {
+ pub fn get(cx: &mut AppContext) -> Option> {
+ cx.default_global::