astro: Extract to zed-extensions/astro repository (#22623)

Marshall Bowers created

This PR extracts the Astro extension to the
[zed-extensions/astro](https://github.com/zed-extensions/astro)
repository.

Release Notes:

- N/A

Change summary

Cargo.lock                                      |   8 
Cargo.toml                                      |   1 
docs/src/languages/astro.md                     |   2 
extensions/astro/Cargo.toml                     |  17 -
extensions/astro/LICENSE-APACHE                 |   1 
extensions/astro/extension.toml                 |  15 -
extensions/astro/languages/astro/brackets.scm   |   3 
extensions/astro/languages/astro/config.toml    |  23 --
extensions/astro/languages/astro/highlights.scm |  25 --
extensions/astro/languages/astro/injections.scm |  21 --
extensions/astro/languages/astro/overrides.scm  |   6 
extensions/astro/src/astro.rs                   | 168 ------------------
12 files changed, 1 insertion(+), 289 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -16324,14 +16324,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "zed_astro"
-version = "0.1.2"
-dependencies = [
- "serde",
- "zed_extension_api 0.1.0",
-]
-
 [[package]]
 name = "zed_clojure"
 version = "0.0.3"

Cargo.toml 🔗

@@ -149,7 +149,6 @@ members = [
     # Extensions
     #
 
-    "extensions/astro",
     "extensions/clojure",
     "extensions/csharp",
     "extensions/deno",

docs/src/languages/astro.md 🔗

@@ -1,6 +1,6 @@
 # Astro
 
-Astro support is available through the [Astro extension](https://github.com/zed-industries/zed/tree/main/extensions/astro).
+Astro support is available through the [Astro extension](https://github.com/zed-extensions/astro).
 
 - Tree Sitter: [virchau13/tree-sitter-astro](https://github.com/virchau13/tree-sitter-astro)
 - Language Server: [withastro/language-tools](https://github.com/withastro/language-tools)

extensions/astro/Cargo.toml 🔗

@@ -1,17 +0,0 @@
-[package]
-name = "zed_astro"
-version = "0.1.2"
-edition = "2021"
-publish = false
-license = "Apache-2.0"
-
-[lints]
-workspace = true
-
-[lib]
-path = "src/astro.rs"
-crate-type = ["cdylib"]
-
-[dependencies]
-serde = { version = "1.0", features = ["derive"] }
-zed_extension_api = "0.1.0"

extensions/astro/extension.toml 🔗

@@ -1,15 +0,0 @@
-id = "astro"
-name = "Astro"
-description = "Astro support."
-version = "0.1.2"
-schema_version = 1
-authors = ["Alvaro Gaona <alvgaona@gmail.com>", "0xk1f0 <dev@k1f0.dev>"]
-repository = "https://github.com/zed-industries/zed"
-
-[language_servers.astro-language-server]
-name = "Astro Language Server"
-language = "Astro"
-
-[grammars.astro]
-repository = "https://github.com/virchau13/tree-sitter-astro"
-commit = "4be180759ec13651f72bacee65fa477c64222a1a"

extensions/astro/languages/astro/config.toml 🔗

@@ -1,23 +0,0 @@
-name = "Astro"
-grammar = "astro"
-path_suffixes = ["astro"]
-block_comment = ["<!-- ", " -->"]
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]
-word_characters = ["#", "$", "-"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-prettier_parser_name = "astro"
-prettier_plugins = ["prettier-plugin-astro"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

extensions/astro/languages/astro/highlights.scm 🔗

@@ -1,25 +0,0 @@
-(tag_name) @tag
-(erroneous_end_tag_name) @keyword
-(doctype) @tag.doctype
-(attribute_name) @property
-(attribute_value) @string
-(comment) @comment
-
-[
-  (attribute_value)
-  (quoted_attribute_value)
-] @string
-
-"=" @operator
-
-[
-  "{"
-  "}"
-] @punctuation.bracket
-
-[
-  "<"
-  ">"
-  "</"
-  "/>"
-] @tag.delimiter

extensions/astro/languages/astro/injections.scm 🔗

@@ -1,21 +0,0 @@
-(frontmatter
-  (frontmatter_js_block) @content
-  (#set! "language" "typescript"))
-
-(attribute_interpolation
-  (attribute_js_expr) @content
-  (#set! "language" "typescript"))
-
-(html_interpolation
-  (permissible_text) @content
-  (#set! "language" "typescript"))
-
-(script_element
-  (raw_text) @content
-  (#set! "language" "typescript"))
-
-; TODO: add scss/less or more injections
-; https://github.com/virchau13/tree-sitter-astro/blob/4be180759ec13651f72bacee65fa477c64222a1a/queries/injections.scm#L18-L27
-(style_element
-  (raw_text) @content
-  (#set! "language" "css"))

extensions/astro/src/astro.rs 🔗

@@ -1,168 +0,0 @@
-use std::collections::HashMap;
-use std::{env, fs};
-
-use serde::Deserialize;
-use zed_extension_api::{self as zed, serde_json, Result};
-
-const SERVER_PATH: &str = "node_modules/@astrojs/language-server/bin/nodeServer.js";
-const PACKAGE_NAME: &str = "@astrojs/language-server";
-
-const TYPESCRIPT_PACKAGE_NAME: &str = "typescript";
-
-/// The relative path to TypeScript's SDK.
-const TYPESCRIPT_TSDK_PATH: &str = "node_modules/typescript/lib";
-
-#[derive(Debug, Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct PackageJson {
-    #[serde(default)]
-    dependencies: HashMap<String, String>,
-    #[serde(default)]
-    dev_dependencies: HashMap<String, String>,
-}
-
-struct AstroExtension {
-    did_find_server: bool,
-    typescript_tsdk_path: String,
-}
-
-impl AstroExtension {
-    fn server_exists(&self) -> bool {
-        fs::metadata(SERVER_PATH).map_or(false, |stat| stat.is_file())
-    }
-
-    fn server_script_path(
-        &mut self,
-        language_server_id: &zed::LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<String> {
-        let server_exists = self.server_exists();
-        if self.did_find_server && server_exists {
-            self.install_typescript_if_needed(worktree)?;
-            return Ok(SERVER_PATH.to_string());
-        }
-
-        zed::set_language_server_installation_status(
-            language_server_id,
-            &zed::LanguageServerInstallationStatus::CheckingForUpdate,
-        );
-        let version = zed::npm_package_latest_version(PACKAGE_NAME)?;
-
-        if !server_exists
-            || zed::npm_package_installed_version(PACKAGE_NAME)?.as_ref() != Some(&version)
-        {
-            zed::set_language_server_installation_status(
-                language_server_id,
-                &zed::LanguageServerInstallationStatus::Downloading,
-            );
-            let result = zed::npm_install_package(PACKAGE_NAME, &version);
-            match result {
-                Ok(()) => {
-                    if !self.server_exists() {
-                        Err(format!(
-                            "installed package '{PACKAGE_NAME}' did not contain expected path '{SERVER_PATH}'",
-                        ))?;
-                    }
-                }
-                Err(error) => {
-                    if !self.server_exists() {
-                        Err(error)?;
-                    }
-                }
-            }
-        }
-
-        self.install_typescript_if_needed(worktree)?;
-        self.did_find_server = true;
-        Ok(SERVER_PATH.to_string())
-    }
-
-    /// Returns whether a local copy of TypeScript exists in the worktree.
-    fn typescript_exists_for_worktree(&self, worktree: &zed::Worktree) -> Result<bool> {
-        let package_json = worktree.read_text_file("package.json")?;
-        let package_json: PackageJson = serde_json::from_str(&package_json)
-            .map_err(|err| format!("failed to parse package.json: {err}"))?;
-
-        let dev_dependencies = &package_json.dev_dependencies;
-        let dependencies = &package_json.dependencies;
-
-        // Since the extension is not allowed to read the filesystem within the project
-        // except through the worktree (which does not contains `node_modules`), we check
-        // the `package.json` to see if `typescript` is listed in the dependencies.
-        Ok(dev_dependencies.contains_key(TYPESCRIPT_PACKAGE_NAME)
-            || dependencies.contains_key(TYPESCRIPT_PACKAGE_NAME))
-    }
-
-    fn install_typescript_if_needed(&mut self, worktree: &zed::Worktree) -> Result<()> {
-        if self
-            .typescript_exists_for_worktree(worktree)
-            .unwrap_or_default()
-        {
-            println!("found local TypeScript installation at '{TYPESCRIPT_TSDK_PATH}'");
-            return Ok(());
-        }
-
-        let installed_typescript_version =
-            zed::npm_package_installed_version(TYPESCRIPT_PACKAGE_NAME)?;
-        let latest_typescript_version = zed::npm_package_latest_version(TYPESCRIPT_PACKAGE_NAME)?;
-
-        if installed_typescript_version.as_ref() != Some(&latest_typescript_version) {
-            println!("installing {TYPESCRIPT_PACKAGE_NAME}@{latest_typescript_version}");
-            zed::npm_install_package(TYPESCRIPT_PACKAGE_NAME, &latest_typescript_version)?;
-        } else {
-            println!("typescript already installed");
-        }
-
-        self.typescript_tsdk_path = env::current_dir()
-            .unwrap()
-            .join(TYPESCRIPT_TSDK_PATH)
-            .to_string_lossy()
-            .to_string();
-
-        Ok(())
-    }
-}
-
-impl zed::Extension for AstroExtension {
-    fn new() -> Self {
-        Self {
-            did_find_server: false,
-            typescript_tsdk_path: TYPESCRIPT_TSDK_PATH.to_owned(),
-        }
-    }
-
-    fn language_server_command(
-        &mut self,
-        language_server_id: &zed::LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        let server_path = self.server_script_path(language_server_id, worktree)?;
-        Ok(zed::Command {
-            command: zed::node_binary_path()?,
-            args: vec![
-                env::current_dir()
-                    .unwrap()
-                    .join(&server_path)
-                    .to_string_lossy()
-                    .to_string(),
-                "--stdio".to_string(),
-            ],
-            env: Default::default(),
-        })
-    }
-
-    fn language_server_initialization_options(
-        &mut self,
-        _language_server_id: &zed::LanguageServerId,
-        _worktree: &zed::Worktree,
-    ) -> Result<Option<serde_json::Value>> {
-        Ok(Some(serde_json::json!({
-            "provideFormatter": true,
-            "typescript": {
-                "tsdk": self.typescript_tsdk_path
-            }
-        })))
-    }
-}
-
-zed::register_extension!(AstroExtension);