Skip to content

Commit

Permalink
feat(lsp): add download lsp system
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioRibera committed Sep 26, 2024
1 parent 1eb1af5 commit 31b8ae9
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
9 changes: 8 additions & 1 deletion extension.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ repository = "https://github.com/RustLangES/zed-dotenv"

[language_servers.dotenv-lsp]
name = "dotenv-lsp"
language = "envfile"
languages = [
"Python",
"Shell Script",
"env",
"ini",
"Rust",
"JavaScript"
]

[grammars.env]
repository = "https://github.com/zarifpour/tree-sitter-dotenv"
Expand Down
80 changes: 74 additions & 6 deletions src/dotenv-lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ impl DotEnvEntension {
fn language_server_binary_path(
&mut self,
language_server_id: &LanguageServerId,
worktree: &zed::Worktree,
) -> Result<String> {
if let Some(path) = worktree.which("dotenv-lsp") {
return Ok(path);
}

if let Some(path) = &self.cached_binary_path {
if fs::metadata(path).map_or(false, |stat| stat.is_file()) {
return Ok(path.clone());
Expand All @@ -19,12 +24,75 @@ impl DotEnvEntension {

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

// TODO: Implement logic to find or install the language server binary
self.cached_binary_path = Some("path/to/dotenv-lsp".to_string());
Ok(self.cached_binary_path.clone().unwrap())
let release = zed::latest_github_release(
"RustLangES/zed-dotenv",
zed::GithubReleaseOptions {
require_assets: true,
pre_release: false,
},
)?;

let (platform, arch) = zed::current_platform();
let asset_name = format!(
"dotenv-lsp-{arch}-{os}.{extension}",
arch = match arch {
zed::Architecture::Aarch64 => "aarch64",
zed::Architecture::X8664 => "x86_64",
_ => return Err(format!("unsupported architecture: {arch:?}")),
},
os = match platform {
zed::Os::Mac => "apple-darwin",
zed::Os::Linux => "unknown-linux-gnu",
zed::Os::Windows => "pc-windows-msvc",
},
extension = match platform {
zed::Os::Mac | zed::Os::Linux => "tar.gz",
zed::Os::Windows => "zip",
}
);

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!("dotenv-lsp-{}", release.version);
let binary_path: String = format!("{version_dir}/dotenv-lsp");

if !fs::metadata(&binary_path).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,
&version_dir,
match platform {
zed::Os::Mac | zed::Os::Linux => zed::DownloadedFileType::GzipTar,
zed::Os::Windows => zed::DownloadedFileType::Zip,
},
)
.map_err(|e| format!("failed to download file: {e}"))?;

zed::make_file_executable(&binary_path).expect("failed to make file executable");

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)
}
}

Expand All @@ -38,10 +106,10 @@ impl zed::Extension for DotEnvEntension {
fn language_server_command(
&mut self,
language_server_id: &LanguageServerId,
_worktree: &zed::Worktree,
worktree: &zed::Worktree,
) -> Result<zed::Command> {
Ok(zed::Command {
command: self.language_server_binary_path(language_server_id)?,
command: self.language_server_binary_path(language_server_id, worktree)?,
args: vec!["--stdio".to_string()],
env: Default::default(),
})
Expand Down

0 comments on commit 31b8ae9

Please sign in to comment.