From 4940e53d23d750e9bfd1958fc11f4512e70740e6 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 1 Oct 2025 08:42:51 -0700 Subject: [PATCH] Remove obsolete extensions and avoid loading or downloading them (#39254) Release Notes: - N/A --- .config/hakari.toml | 2 - Cargo.lock | 15 -- Cargo.toml | 2 - crates/extension_host/src/extension_host.rs | 23 ++- extensions/ruff/Cargo.toml | 16 -- extensions/ruff/LICENSE-APACHE | 1 - extensions/ruff/README.md | 3 - extensions/ruff/extension.toml | 11 -- extensions/ruff/src/ruff.rs | 172 -------------------- extensions/snippets/Cargo.toml | 17 -- extensions/snippets/LICENSE-APACHE | 1 - extensions/snippets/extension.toml | 15 -- extensions/snippets/src/snippets.rs | 132 --------------- 13 files changed, 21 insertions(+), 389 deletions(-) delete mode 100644 extensions/ruff/Cargo.toml delete mode 120000 extensions/ruff/LICENSE-APACHE delete mode 100644 extensions/ruff/README.md delete mode 100644 extensions/ruff/extension.toml delete mode 100644 extensions/ruff/src/ruff.rs delete mode 100644 extensions/snippets/Cargo.toml delete mode 120000 extensions/snippets/LICENSE-APACHE delete mode 100644 extensions/snippets/extension.toml delete mode 100644 extensions/snippets/src/snippets.rs diff --git a/.config/hakari.toml b/.config/hakari.toml index 9cc9c1e4eea246b3bbf13d09e7206ee44c31468b..57bb73cf54aeb14be5a594cdf61c836dd7c74f46 100644 --- a/.config/hakari.toml +++ b/.config/hakari.toml @@ -37,8 +37,6 @@ workspace-members = [ "zed_glsl", "zed_html", "zed_proto", - "zed_ruff", "slash_commands_example", - "zed_snippets", "zed_test_extension", ] diff --git a/Cargo.lock b/Cargo.lock index 5f933af61d1b13c186e6c72a10b1a5daa42651fe..30ebc9aa66ccf4caaf9c82dfd6a465d221a5540e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20420,21 +20420,6 @@ dependencies = [ "zed_extension_api 0.1.0", ] -[[package]] -name = "zed_ruff" -version = "0.1.1" -dependencies = [ - "zed_extension_api 0.1.0", -] - -[[package]] -name = "zed_snippets" -version = "0.0.6" -dependencies = [ - "serde_json", - "zed_extension_api 0.1.0", -] - [[package]] name = "zed_test_extension" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 4c12d819014e9cb04d9c08038ebb10940fd8f54e..762a223c68a7a3b34c6f59570d2f4bc69d81e04f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -212,9 +212,7 @@ members = [ "extensions/glsl", "extensions/html", "extensions/proto", - "extensions/ruff", "extensions/slash-commands-example", - "extensions/snippets", "extensions/test-extension", # diff --git a/crates/extension_host/src/extension_host.rs b/crates/extension_host/src/extension_host.rs index cd1eaa9855351630e13185962738b1e0d5fb9489..3397f770c241ab0b29deab661e014811fed7f852 100644 --- a/crates/extension_host/src/extension_host.rs +++ b/crates/extension_host/src/extension_host.rs @@ -73,6 +73,12 @@ const FS_WATCH_LATENCY: Duration = Duration::from_millis(100); /// The current extension [`SchemaVersion`] supported by Zed. const CURRENT_SCHEMA_VERSION: SchemaVersion = SchemaVersion(1); +/// Extensions that should no longer be loaded or downloaded. +/// +/// These snippets should no longer be downloaded or loaded, because their +/// functionality has been integrated into the core editor. +const SUPPRESSED_EXTENSIONS: &[&str] = &["snippets", "ruff", "ty", "basedpyright"]; + /// Returns the [`SchemaVersion`] range that is compatible with this version of Zed. pub fn schema_version_range() -> RangeInclusive { SchemaVersion::ZERO..=CURRENT_SCHEMA_VERSION @@ -682,7 +688,12 @@ impl ExtensionStore { ); } - let response: GetExtensionsResponse = serde_json::from_slice(&body)?; + let mut response: GetExtensionsResponse = serde_json::from_slice(&body)?; + + response + .data + .retain(|extension| !SUPPRESSED_EXTENSIONS.contains(&extension.id.as_ref())); + Ok(response.data) }) } @@ -1076,6 +1087,10 @@ impl ExtensionStore { ) -> Task<()> { let old_index = &self.extension_index; + new_index + .extensions + .retain(|extension_id, _| !SUPPRESSED_EXTENSIONS.contains(&extension_id.as_ref())); + // Determine which extensions need to be loaded and unloaded, based // on the changes to the manifest and the extensions that we know have been // modified. @@ -1256,7 +1271,7 @@ impl ExtensionStore { self.proxy.register_grammars(grammars_to_add); let languages_to_add = new_index .languages - .iter_mut() + .iter() .filter(|(_, entry)| extensions_to_load.contains(&entry.extension)) .collect::>(); for (language_name, language) in languages_to_add { @@ -1506,6 +1521,10 @@ impl ExtensionStore { let mut extension_manifest = ExtensionManifest::load(fs.clone(), &extension_dir).await?; let extension_id = extension_manifest.id.clone(); + if SUPPRESSED_EXTENSIONS.contains(&extension_id.as_ref()) { + return Ok(()); + } + // TODO: distinguish dev extensions more explicitly, by the absence // of a checksum file that we'll create when downloading normal extensions. let is_dev = fs diff --git a/extensions/ruff/Cargo.toml b/extensions/ruff/Cargo.toml deleted file mode 100644 index 24616f963b0258bfaca01b7399a4b466eb5d9709..0000000000000000000000000000000000000000 --- a/extensions/ruff/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "zed_ruff" -version = "0.1.1" -edition.workspace = true -publish.workspace = true -license = "Apache-2.0" - -[lints] -workspace = true - -[lib] -path = "src/ruff.rs" -crate-type = ["cdylib"] - -[dependencies] -zed_extension_api = "0.1.0" diff --git a/extensions/ruff/LICENSE-APACHE b/extensions/ruff/LICENSE-APACHE deleted file mode 120000 index 1cd601d0a3affae83854be02a0afdec3b7a9ec4d..0000000000000000000000000000000000000000 --- a/extensions/ruff/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-APACHE \ No newline at end of file diff --git a/extensions/ruff/README.md b/extensions/ruff/README.md deleted file mode 100644 index f315e0ad044290f1e64f892a39c07d74aedb8046..0000000000000000000000000000000000000000 --- a/extensions/ruff/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ruff - -Documentation for configuring Zed to use the Ruff extension can be found [here](https://docs.astral.sh/ruff/editors/setup/#zed). diff --git a/extensions/ruff/extension.toml b/extensions/ruff/extension.toml deleted file mode 100644 index 1f5a7314f4a477679ce606626c9dc06fa6fea7b5..0000000000000000000000000000000000000000 --- a/extensions/ruff/extension.toml +++ /dev/null @@ -1,11 +0,0 @@ -id = "ruff" -name = "Ruff" -description = "Support for Ruff, the Python linter and formatter" -version = "0.1.1" -schema_version = 1 -authors = [] -repository = "https://github.com/zed-industries/zed" - -[language_servers.ruff] -name = "Ruff" -languages = ["Python"] diff --git a/extensions/ruff/src/ruff.rs b/extensions/ruff/src/ruff.rs deleted file mode 100644 index cc3c3f65504390ed96248217cc2dfa6e2124081f..0000000000000000000000000000000000000000 --- a/extensions/ruff/src/ruff.rs +++ /dev/null @@ -1,172 +0,0 @@ -use std::fs; -use zed::LanguageServerId; -use zed_extension_api::{self as zed, Result, settings::LspSettings}; - -struct RuffBinary { - path: String, - args: Option>, -} - -struct RuffExtension { - cached_binary_path: Option, -} - -impl RuffExtension { - fn language_server_binary( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - let binary_settings = LspSettings::for_worktree("ruff", worktree) - .ok() - .and_then(|lsp_settings| lsp_settings.binary); - let binary_args = binary_settings - .as_ref() - .and_then(|binary_settings| binary_settings.arguments.clone()); - - if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) { - return Ok(RuffBinary { - path, - args: binary_args, - }); - } - - if let Some(path) = worktree.which("ruff") { - return Ok(RuffBinary { - path, - args: binary_args, - }); - } - - if let Some(path) = &self.cached_binary_path - && fs::metadata(path).is_ok_and(|stat| stat.is_file()) - { - return Ok(RuffBinary { - path: path.clone(), - args: binary_args, - }); - } - - zed::set_language_server_installation_status( - language_server_id, - &zed::LanguageServerInstallationStatus::CheckingForUpdate, - ); - let release = zed::latest_github_release( - "astral-sh/ruff", - zed::GithubReleaseOptions { - require_assets: true, - pre_release: false, - }, - )?; - - let (platform, arch) = zed::current_platform(); - - let asset_stem = format!( - "ruff-{arch}-{os}", - arch = match arch { - zed::Architecture::Aarch64 => "aarch64", - zed::Architecture::X86 => "x86", - zed::Architecture::X8664 => "x86_64", - }, - os = match platform { - zed::Os::Mac => "apple-darwin", - zed::Os::Linux => "unknown-linux-gnu", - zed::Os::Windows => "pc-windows-msvc", - } - ); - let asset_name = format!( - "{asset_stem}.{suffix}", - suffix = match platform { - zed::Os::Windows => "zip", - _ => "tar.gz", - } - ); - - let asset = release - .assets - .iter() - .find(|asset| asset.name == asset_name) - .ok_or_else(|| format!("no asset found matching {:?}", asset_name))?; - - let version_dir = format!("ruff-{}", release.version); - let binary_path = match platform { - zed::Os::Windows => format!("{version_dir}/ruff.exe"), - _ => format!("{version_dir}/{asset_stem}/ruff"), - }; - - if !fs::metadata(&binary_path).is_ok_and(|stat| stat.is_file()) { - zed::set_language_server_installation_status( - language_server_id, - &zed::LanguageServerInstallationStatus::Downloading, - ); - let file_kind = match platform { - zed::Os::Windows => zed::DownloadedFileType::Zip, - _ => zed::DownloadedFileType::GzipTar, - }; - zed::download_file(&asset.download_url, &version_dir, file_kind) - .map_err(|e| format!("failed to download file: {e}"))?; - - let entries = - fs::read_dir(".").map_err(|e| format!("failed to list working directory {e}"))?; - for entry in entries { - let entry = entry.map_err(|e| format!("failed to load directory entry {e}"))?; - if entry.file_name().to_str() != Some(&version_dir) { - fs::remove_dir_all(entry.path()).ok(); - } - } - } - - self.cached_binary_path = Some(binary_path.clone()); - Ok(RuffBinary { - path: binary_path, - args: binary_args, - }) - } -} - -impl zed::Extension for RuffExtension { - fn new() -> Self { - Self { - cached_binary_path: None, - } - } - - fn language_server_command( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - let ruff_binary = self.language_server_binary(language_server_id, worktree)?; - Ok(zed::Command { - command: ruff_binary.path, - args: ruff_binary.args.unwrap_or_else(|| vec!["server".into()]), - env: vec![], - }) - } - - fn language_server_initialization_options( - &mut self, - server_id: &LanguageServerId, - worktree: &zed_extension_api::Worktree, - ) -> Result> { - let settings = LspSettings::for_worktree(server_id.as_ref(), worktree) - .ok() - .and_then(|lsp_settings| lsp_settings.initialization_options) - .unwrap_or_default(); - Ok(Some(settings)) - } - - fn language_server_workspace_configuration( - &mut self, - server_id: &LanguageServerId, - worktree: &zed_extension_api::Worktree, - ) -> Result> { - let settings = LspSettings::for_worktree(server_id.as_ref(), worktree) - .ok() - .and_then(|lsp_settings| lsp_settings.settings) - .unwrap_or_default(); - Ok(Some(settings)) - } -} - -zed::register_extension!(RuffExtension); diff --git a/extensions/snippets/Cargo.toml b/extensions/snippets/Cargo.toml deleted file mode 100644 index ab5ac7244a3acbe25246588f4fe4ad1a35f1964f..0000000000000000000000000000000000000000 --- a/extensions/snippets/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "zed_snippets" -version = "0.0.6" -edition.workspace = true -publish.workspace = true -license = "Apache-2.0" - -[lints] -workspace = true - -[lib] -path = "src/snippets.rs" -crate-type = ["cdylib"] - -[dependencies] -zed_extension_api = "0.1.0" -serde_json = "1.0" diff --git a/extensions/snippets/LICENSE-APACHE b/extensions/snippets/LICENSE-APACHE deleted file mode 120000 index 1cd601d0a3affae83854be02a0afdec3b7a9ec4d..0000000000000000000000000000000000000000 --- a/extensions/snippets/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-APACHE \ No newline at end of file diff --git a/extensions/snippets/extension.toml b/extensions/snippets/extension.toml deleted file mode 100644 index 01dc587d77af8a9ca074b49a247ef8f6cfffb516..0000000000000000000000000000000000000000 --- a/extensions/snippets/extension.toml +++ /dev/null @@ -1,15 +0,0 @@ -id = "snippets" -name = "Snippets" -description = "Support for language-agnostic snippets, provided by simple-completion-language-server" -version = "0.0.6" -schema_version = 1 -authors = ["Zed Industries "] -repository = "https://github.com/zed-industries/zed" - -[language_servers.snippet-completion-server] -name = "Snippet Completion Server" -languages = ["Astro", "Clojure", "C", "C++", "C#", "Dart", "Dockerfile", "Elixir", "Elm", "ERB", "Erlang", - "Gleam","GLSL", "Go", "Haskell", "HCL", "HEEX", "HTML", "JavaScript","JSDoc", "JSON", "Lua", - "Markdown","OCaml", "PHP", "Python", "Prisma", "PureScript", "Racket", "Ruby", "Rust", "Scheme", - "Shell Script", "Svelte", "Terraform", "TOML", "TypeScript", "TSX", "Uiua", "Vue.js", "Zig"] -language_ids = { TypeScript = "typescript", TSX = "typescriptreact", JavaScript = "javascript", "Vue.js" = "vue", Terraform = "terraform", "Terraform Vars" = "terraform-vars", PHP = "php", HTML = "html", CSS = "css" } diff --git a/extensions/snippets/src/snippets.rs b/extensions/snippets/src/snippets.rs deleted file mode 100644 index 1efe4c234002b5c8b3d26b9bdb0b30095e212ea6..0000000000000000000000000000000000000000 --- a/extensions/snippets/src/snippets.rs +++ /dev/null @@ -1,132 +0,0 @@ -use serde_json::json; -use std::fs; -use zed::LanguageServerId; -use zed_extension_api::{self as zed, Result, settings::LspSettings}; - -struct SnippetExtension { - cached_binary_path: Option, -} - -impl SnippetExtension { - fn language_server_binary_path( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - if let Some(path) = worktree.which("simple-completion-language-server") { - return Ok(path); - } - - if let Some(path) = &self.cached_binary_path - && fs::metadata(path).is_ok_and(|stat| stat.is_file()) - { - return Ok(path.clone()); - } - - zed::set_language_server_installation_status( - language_server_id, - &zed::LanguageServerInstallationStatus::CheckingForUpdate, - ); - let release = zed::latest_github_release( - "zed-industries/simple-completion-language-server", - zed::GithubReleaseOptions { - require_assets: true, - pre_release: false, - }, - )?; - - let (platform, arch) = zed::current_platform(); - let asset_name = format!( - "simple-completion-language-server-{arch}-{os}.tar.gz", - arch = match arch { - zed::Architecture::Aarch64 => "aarch64", - zed::Architecture::X86 => "x86", - zed::Architecture::X8664 => "x86_64", - }, - os = match platform { - zed::Os::Mac => "apple-darwin", - zed::Os::Linux => "unknown-linux-gnu", - zed::Os::Windows => "pc-windows-msvc", - }, - ); - - let asset = release - .assets - .iter() - .find(|asset| asset.name == asset_name) - .ok_or_else(|| format!("no asset found matching {:?}", asset_name))?; - - let version_dir = format!("simple-completion-language-server-{}", release.version); - let binary_path = format!("{version_dir}/simple-completion-language-server"); - - if !fs::metadata(&binary_path).is_ok_and(|stat| stat.is_file()) { - zed::set_language_server_installation_status( - language_server_id, - &zed::LanguageServerInstallationStatus::Downloading, - ); - - zed::download_file( - &asset.download_url, - &version_dir, - zed::DownloadedFileType::GzipTar, - ) - .map_err(|e| format!("failed to download file: {e}"))?; - - let entries = - fs::read_dir(".").map_err(|e| format!("failed to list working directory {e}"))?; - for entry in entries { - let entry = entry.map_err(|e| format!("failed to load directory entry {e}"))?; - if entry.file_name().to_str() != Some(&version_dir) { - fs::remove_dir_all(entry.path()).ok(); - } - } - } - - self.cached_binary_path = Some(binary_path.clone()); - Ok(binary_path) - } -} - -impl zed::Extension for SnippetExtension { - fn new() -> Self { - Self { - cached_binary_path: None, - } - } - - fn language_server_command( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - Ok(zed::Command { - command: self.language_server_binary_path(language_server_id, worktree)?, - args: vec![], - env: vec![("SCLS_CONFIG_SUBDIRECTORY".to_owned(), "zed".to_owned())], - }) - } - - fn language_server_workspace_configuration( - &mut self, - server_id: &LanguageServerId, - worktree: &zed_extension_api::Worktree, - ) -> Result> { - let settings = LspSettings::for_worktree(server_id.as_ref(), worktree) - .ok() - .and_then(|lsp_settings| lsp_settings.settings) - .unwrap_or_else(|| { - json!({ - "max_completion_items": 20, - "snippets_first": true, - "feature_words": false, - "feature_snippets": true, - // We disable `feature_paths` by default, because it's bad UX to assume that any `/` that is typed - // is the start of a path. - "feature_paths": false - }) - }); - Ok(Some(settings)) - } -} - -zed::register_extension!(SnippetExtension);