Skip to content

Commit

Permalink
feat: mvp zed extension going (#75)
Browse files Browse the repository at this point in the history
Get's a Zed Extension impl going. Where the LSP is downloaded from
GitHub release assets.

Even though Zed extensions are Rust projects, we shouldn't include that
as part of our `hdx` workspace. Furthermore, we should treat the lsp as
external, and not try to compile our lsp directly within the extension
wasm.

The `lsp` location is resolved through either;

1. env: `HDX_SERVER_PATH` (which is the same as the VSCode one)
1. we download it from GitHub's release assets

![CleanShot 2024-12-17 at 18 00
26](https://github.com/user-attachments/assets/d2d0ca5e-6724-4faf-b526-150661637b5e)
  • Loading branch information
maraisr authored Dec 18, 2024
1 parent 7065ed9 commit c7fab07
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 6 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -fa canary -m "Latest Continuous Release" ${GITHUB_SHA}
git push --force-with-lease origin canaray:refs/tags/canary
git push --force-with-lease origin canary:refs/tags/canary
build:
if: |
Expand Down Expand Up @@ -96,13 +96,14 @@ jobs:
BIN_NAME=hdx-${{ matrix.code-target }}
mv target/${{ matrix.target }}/release/hdx $BIN_NAME
- run: chmod +x hdx-*

- name: Upload Binary
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: binary-${{ matrix.code-target }}
path: |
hdx-*
path: hdx-*

deploy:
env:
Expand All @@ -121,7 +122,7 @@ jobs:
cache: "npm"
- name: Download Artifacts
uses: actions/download-artifact@v4
- run: cp binary-*/* packages/hdx/bin && chmod +x packages/hdx/bin/*
- run: cp binary-*/* packages/hdx/bin
- run: tree
- run: npm i
working-directory: ./packages/hdx
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = ["crates/*"]
exclude = ["packages/hdx_zed"]

[workspace.package]
authors = ["Keith Cirkel (https://keithcirkel.co.uk)"]
Expand All @@ -24,7 +25,7 @@ hdx_transform = { version = "0.0.0", path = "crates/hdx_transform" }
hdx_highlight = { version = "0.0.0", path = "crates/hdx_highlight" }
hdx_lsp = { version = "0.0.0", path = "crates/hdx_lsp" }

# Memory
# Memory
bumpalo = { version = "3.16.0" }

# Data structure libraries/helpers
Expand Down
2 changes: 1 addition & 1 deletion packages/hdx_vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"url": "https://github.com/sponsors/keithamus"
},
"license": "MIT",
"author": "Keith Cirkel (https://keithcirke.co.uk)",
"author": "Keith Cirkel (https://keithcirkel.co.uk)",
"type": "commonjs",
"main": "./src/main.js",
"files": [
Expand Down
1 change: 1 addition & 0 deletions packages/hdx_zed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cargo.lock
10 changes: 10 additions & 0 deletions packages/hdx_zed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "hdx_zed"
version = "0.0.1"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
zed_extension_api = "0.1"
12 changes: 12 additions & 0 deletions packages/hdx_zed/dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
To install the dev version of the zed extension:

1. `rustup target add wasm32-wasip1`
2. Extensions > Install Dev Extension > Select the `pacakges/hdx_zed` folder
3. You may wish to disable the default css LSP's:
```json
"language_servers": [
"!vscode-css-language-server",
"!tailwindcss-language-server",
"..."
]
```
11 changes: 11 additions & 0 deletions packages/hdx_zed/extension.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
id = "hdx"
name = "hdx"
version = "0.0.1"
schema_version = 1
authors = ["Keith Cirkel (https://keithcirkel.co.uk)", "Marais Rossouw (https://marais.io)"]
description = "Refreshing CSS!"
repository = "https://github.com/keithamus/hdx"

[language_servers.hdx]
language = "CSS"
name = "hdx Language Server"
103 changes: 103 additions & 0 deletions packages/hdx_zed/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::env;
use std::fs;
use zed_extension_api::{self as zed, Result};

// The bin at ~Library/Application Support/Zed/extensions/work/{NAME}
// this does not need to be a constant, and may choose to resolve it in the #language_server_binary_path method
const HDX_BIN_PATH: &str = "hdx";

struct HdxExtension;

impl HdxExtension {
fn language_server_binary_path(
&mut self,
language_server_id: &zed_extension_api::LanguageServerId,
worktree: &zed::Worktree,
) -> Result<String> {
if let Ok(path) = env::var("HDX_SERVER_PATH") {
if fs::metadata(&path).map_or(false, |stat| stat.is_file()) {
return Ok(path.to_string());
}
}

if let Some(path) = worktree.which("hdx") {
return Ok(path);
}

zed::set_language_server_installation_status(
language_server_id,
&zed::LanguageServerInstallationStatus::CheckingForUpdate,
);

let release = zed::github_release_by_tag_name("keithamus/hdx", "canary")?;

let (platform, arch) = zed::current_platform();
let asset_name = format!(
"hdx-{platform}-{arch}",
platform = match platform {
zed::Os::Mac => "darwin",
zed::Os::Linux => "linux",
zed::Os::Windows => "win32",
},
arch = match arch {
zed::Architecture::Aarch64 => "arm64",
zed::Architecture::X8664 => "x64",
_ => return Err(format!("unsupported architecture: {arch:?}")),
},
);

let asset = release
.assets
.iter()
.find(|asset| asset.name == asset_name)
.ok_or_else(|| format!("no asset found matching {:?}", asset_name))?;

if !fs::metadata(&asset_name).map_or(false, |stat| stat.is_file()) {
zed::set_language_server_installation_status(
language_server_id,
&zed::LanguageServerInstallationStatus::Downloading,
);

zed::download_file(&asset.download_url, HDX_BIN_PATH, zed::DownloadedFileType::Uncompressed)
.map_err(|e| format!("failed to download file: {e}"))?;

zed::make_file_executable(HDX_BIN_PATH).map_err(|e| format!("failed to make file executable: {e}"))?;
}

Ok(HDX_BIN_PATH.to_string())
}
}

impl zed::Extension for HdxExtension {
fn new() -> Self {
Self
}

fn language_server_command(
&mut self,
language_server_id: &zed_extension_api::LanguageServerId,
worktree: &zed_extension_api::Worktree,
) -> zed_extension_api::Result<zed_extension_api::Command> {
let settings = zed_extension_api::settings::LspSettings::for_worktree(language_server_id.as_ref(), worktree)?;

let mut args = vec![];

if let Some(settings) = settings.settings {
let is_debug = settings.get("debug").and_then(|value| value.as_bool()).unwrap_or(false);

if is_debug {
args.push("--debug".to_string());
}
}

args.push("lsp".to_string());

Ok(zed::Command {
command: self.language_server_binary_path(language_server_id, worktree)?,
args,
env: Default::default(),
})
}
}

zed::register_extension!(HdxExtension);

0 comments on commit c7fab07

Please sign in to comment.