emmet: Extract to zed-extensions/emmet repository (#36323)

Marshall Bowers created

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

Release Notes:

- N/A

Change summary

.config/hakari.toml             |   1 
Cargo.lock                      |   7 --
Cargo.toml                      |   1 
docs/src/languages/emmet.md     |   2 
extensions/emmet/.gitignore     |   3 
extensions/emmet/Cargo.toml     |  16 -----
extensions/emmet/LICENSE-APACHE |   1 
extensions/emmet/extension.toml |  24 -------
extensions/emmet/src/emmet.rs   | 106 -----------------------------------
9 files changed, 2 insertions(+), 159 deletions(-)

Detailed changes

.config/hakari.toml πŸ”—

@@ -34,7 +34,6 @@ workspace-members = [
     "zed_extension_api",
 
     # exclude all extensions
-    "zed_emmet",
     "zed_glsl",
     "zed_html",
     "zed_proto",

Cargo.lock πŸ”—

@@ -20520,13 +20520,6 @@ dependencies = [
  "workspace-hack",
 ]
 
-[[package]]
-name = "zed_emmet"
-version = "0.0.6"
-dependencies = [
- "zed_extension_api 0.1.0",
-]
-
 [[package]]
 name = "zed_extension_api"
 version = "0.1.0"

Cargo.toml πŸ”—

@@ -199,7 +199,6 @@ members = [
     # Extensions
     #
 
-    "extensions/emmet",
     "extensions/glsl",
     "extensions/html",
     "extensions/proto",

docs/src/languages/emmet.md πŸ”—

@@ -1,5 +1,7 @@
 # Emmet
 
+Emmet support is available through the [Emmet extension](https://github.com/zed-extensions/emmet).
+
 [Emmet](https://emmet.io/) is a web-developer’s toolkit that can greatly improve your HTML & CSS workflow.
 
 - Language Server: [olrtg/emmet-language-server](https://github.com/olrtg/emmet-language-server)

extensions/emmet/Cargo.toml πŸ”—

@@ -1,16 +0,0 @@
-[package]
-name = "zed_emmet"
-version = "0.0.6"
-edition.workspace = true
-publish.workspace = true
-license = "Apache-2.0"
-
-[lints]
-workspace = true
-
-[lib]
-path = "src/emmet.rs"
-crate-type = ["cdylib"]
-
-[dependencies]
-zed_extension_api = "0.1.0"

extensions/emmet/extension.toml πŸ”—

@@ -1,24 +0,0 @@
-id = "emmet"
-name = "Emmet"
-description = "Emmet support"
-version = "0.0.6"
-schema_version = 1
-authors = ["Piotr Osiewicz <piotr@zed.dev>"]
-repository = "https://github.com/zed-industries/zed"
-
-[language_servers.emmet-language-server]
-name = "Emmet Language Server"
-language = "HTML"
-languages = ["HTML", "PHP", "ERB", "HTML/ERB", "JavaScript", "TSX", "CSS", "HEEX", "Elixir", "Vue.js"]
-
-[language_servers.emmet-language-server.language_ids]
-"HTML" = "html"
-"PHP" = "php"
-"ERB" = "eruby"
-"HTML/ERB" = "eruby"
-"JavaScript" = "javascriptreact"
-"TSX" = "typescriptreact"
-"CSS" = "css"
-"HEEX" = "heex"
-"Elixir" = "heex"
-"Vue.js" = "vue"

extensions/emmet/src/emmet.rs πŸ”—

@@ -1,106 +0,0 @@
-use std::{env, fs};
-use zed_extension_api::{self as zed, Result};
-
-struct EmmetExtension {
-    did_find_server: bool,
-}
-
-const SERVER_PATH: &str = "node_modules/@olrtg/emmet-language-server/dist/index.js";
-const PACKAGE_NAME: &str = "@olrtg/emmet-language-server";
-
-impl EmmetExtension {
-    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) -> Result<String> {
-        let server_exists = self.server_exists();
-        if self.did_find_server && server_exists {
-            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.did_find_server = true;
-        Ok(SERVER_PATH.to_string())
-    }
-}
-
-impl zed::Extension for EmmetExtension {
-    fn new() -> Self {
-        Self {
-            did_find_server: false,
-        }
-    }
-
-    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)?;
-        Ok(zed::Command {
-            command: zed::node_binary_path()?,
-            args: vec![
-                zed_ext::sanitize_windows_path(env::current_dir().unwrap())
-                    .join(&server_path)
-                    .to_string_lossy()
-                    .to_string(),
-                "--stdio".to_string(),
-            ],
-            env: Default::default(),
-        })
-    }
-}
-
-zed::register_extension!(EmmetExtension);
-
-/// Extensions to the Zed extension API that have not yet stabilized.
-mod zed_ext {
-    /// Sanitizes the given path to remove the leading `/` on Windows.
-    ///
-    /// On macOS and Linux this is a no-op.
-    ///
-    /// This is a workaround for https://github.com/bytecodealliance/wasmtime/issues/10415.
-    pub fn sanitize_windows_path(path: std::path::PathBuf) -> std::path::PathBuf {
-        use zed_extension_api::{Os, current_platform};
-
-        let (os, _arch) = current_platform();
-        match os {
-            Os::Mac | Os::Linux => path,
-            Os::Windows => path
-                .to_string_lossy()
-                .to_string()
-                .trim_start_matches('/')
-                .into(),
-        }
-    }
-}