Cargo.lock 🔗
@@ -12490,6 +12490,13 @@ dependencies = [
"zed_extension_api 0.0.4",
]
+[[package]]
+name = "zed_emmet"
+version = "0.0.1"
+dependencies = [
+ "zed_extension_api 0.0.4",
+]
+
[[package]]
name = "zed_erlang"
version = "0.0.1"
Piotr Osiewicz created
Note that I want to move this into an extension before merging.
Fixes: #4992
Release Notes:
- Added Emmet snippets support
Cargo.lock | 7 ++
Cargo.toml | 1
extensions/emmet/.gitignore | 3 +
extensions/emmet/Cargo.toml | 16 ++++++
extensions/emmet/LICENSE-APACHE | 1
extensions/emmet/extension.toml | 11 ++++
extensions/emmet/src/emmet.rs | 93 +++++++++++++++++++++++++++++++++++
7 files changed, 132 insertions(+)
@@ -12490,6 +12490,13 @@ dependencies = [
"zed_extension_api 0.0.4",
]
+[[package]]
+name = "zed_emmet"
+version = "0.0.1"
+dependencies = [
+ "zed_extension_api 0.0.4",
+]
+
[[package]]
name = "zed_erlang"
version = "0.0.1"
@@ -102,6 +102,7 @@ members = [
"extensions/astro",
"extensions/clojure",
"extensions/csharp",
+ "extensions/emmet",
"extensions/erlang",
"extensions/gleam",
"extensions/haskell",
@@ -0,0 +1,3 @@
+target
+*.wasm
+grammars
@@ -0,0 +1,16 @@
+[package]
+name = "zed_emmet"
+version = "0.0.1"
+edition = "2021"
+publish = false
+license = "Apache-2.0"
+
+[lints]
+workspace = true
+
+[lib]
+path = "src/emmet.rs"
+crate-type = ["cdylib"]
+
+[dependencies]
+zed_extension_api = "0.0.4"
@@ -0,0 +1 @@
+../../LICENSE-APACHE
@@ -0,0 +1,11 @@
+id = "emmet"
+name = "Emmet"
+description = "Emmet support"
+version = "0.0.1"
+schema_version = 1
+authors = []
+repository = "https://github.com/zed-industries/zed"
+
+[language_servers.emmet-language-server]
+name = "Emmet Language Server"
+language = "HTML"
@@ -0,0 +1,93 @@
+use std::{env, fs};
+use zed_extension_api::{self as zed, Result};
+
+struct EmmetExtension {
+ did_find_server: bool,
+}
+
+const SERVER_PATH: &str = "node_modules/.bin/emmet-language-server";
+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, config: zed::LanguageServerConfig) -> 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(
+ &config.name,
+ &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(
+ &config.name,
+ &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,
+ config: zed::LanguageServerConfig,
+ _: &zed::Worktree,
+ ) -> Result<zed::Command> {
+ let server_path = self.server_script_path(config)?;
+ 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,
+ _: zed::LanguageServerConfig,
+ _: &zed::Worktree,
+ ) -> Result<Option<String>> {
+ Ok(None)
+ }
+}
+
+zed::register_extension!(EmmetExtension);