Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "zed_php"
version = "0.4.10"
version = "0.4.11"
edition = "2021"
publish = false
license = "Apache-2.0"
Expand Down
7 changes: 6 additions & 1 deletion extension.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id = "php"
name = "PHP"
description = "PHP support."
version = "0.4.10"
version = "0.4.11"
schema_version = 1
authors = ["Piotr Osiewicz <piotr@zed.dev>"]
repository = "https://github.com/zed-extensions/php"
Expand All @@ -20,6 +20,11 @@ language_ids = { PHP = "php" }
name = "Phpactor"
language = "PHP"

[language_servers.phpantom]
name = "PHPantom"
language = "PHP"
language_ids = { PHP = "php" }

[debug_adapters.Xdebug]

[grammars.php]
Expand Down
2 changes: 2 additions & 0 deletions src/language_servers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod intelephense;
mod phpactor;
mod phpantom;
mod phptools;

pub use intelephense::*;
pub use phpactor::*;
pub use phpantom::*;
pub use phptools::*;
140 changes: 140 additions & 0 deletions src/language_servers/phpantom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::fs;

use zed_extension_api::settings::LspSettings;
use zed_extension_api::{self as zed, LanguageServerId, Result};

const REPO: &str = "AJenbo/phpantom_lsp";
Comment thread
roxblnfk marked this conversation as resolved.
Outdated
const BINARY_NAME: &str = "phpantom_lsp";

pub struct Phpantom {
cached_binary_path: Option<String>,
}

impl Phpantom {
pub const LANGUAGE_SERVER_ID: &'static str = "phpantom";

pub fn new() -> Self {
Self {
cached_binary_path: None,
}
}

pub fn language_server_command(
&mut self,
language_server_id: &LanguageServerId,
worktree: &zed::Worktree,
) -> Result<zed::Command> {
// Allow users to point at their own build via
// `lsp.phpantom.binary.{path,arguments}` in the settings.
if let Some(binary) = LspSettings::for_worktree("phpantom", worktree)
.ok()
.and_then(|settings| settings.binary)
{
if let Some(path) = binary.path {
return Ok(zed::Command {
command: path,
args: binary.arguments.unwrap_or_default(),
env: Default::default(),
});
}
}

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

fn language_server_binary_path(
&mut self,
language_server_id: &LanguageServerId,
worktree: &zed::Worktree,
) -> Result<String> {
if let Some(path) = worktree.which(BINARY_NAME) {
return Ok(path);
}

if let Some(path) = &self.cached_binary_path {
if fs::metadata(path).is_ok_and(|stat| stat.is_file()) {
return Ok(path.clone());
}
}

zed::set_language_server_installation_status(
language_server_id,
&zed::LanguageServerInstallationStatus::CheckingForUpdate,
);
let release = zed::latest_github_release(
REPO,
zed::GithubReleaseOptions {
require_assets: true,
pre_release: false,
},
)?;

let (platform, arch) = zed::current_platform();

let (os_str, ext) = match platform {
zed::Os::Mac => ("apple-darwin", "tar.gz"),
zed::Os::Linux => ("unknown-linux-gnu", "tar.gz"),
zed::Os::Windows => ("pc-windows-msvc", "zip"),
};

let arch_str = match arch {
zed::Architecture::Aarch64 => "aarch64",
zed::Architecture::X8664 => "x86_64",
_ => return Err(format!("unsupported architecture: {arch:?}")),
};

let asset_name = format!("{BINARY_NAME}-{arch_str}-{os_str}.{ext}");
let asset = release
.assets
.iter()
.find(|asset| asset.name == asset_name)
.ok_or_else(|| {
format!(
"no release asset found matching {asset_name:?} — you may need to build \
{BINARY_NAME} from source for your platform"
)
})?;

let version_dir = format!("{BINARY_NAME}-{}", release.version);
fs::create_dir_all(&version_dir).map_err(|e| format!("failed to create directory: {e}"))?;

let binary_path = match platform {
zed::Os::Windows => format!("{version_dir}/{BINARY_NAME}.exe"),
_ => format!("{version_dir}/{BINARY_NAME}"),
};

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

let file_type = match ext {
"tar.gz" => zed::DownloadedFileType::GzipTar,
"zip" => zed::DownloadedFileType::Zip,
_ => unreachable!(),
};

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

zed::make_file_executable(&binary_path)?;

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)
}
}
8 changes: 7 additions & 1 deletion src/php.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ use zed_extension_api::{
};

use crate::{
language_servers::{Intelephense, PhpTools, Phpactor},
language_servers::{Intelephense, PhpTools, Phpactor, Phpantom},
xdebug::XDebug,
};

struct PhpExtension {
phptools: Option<PhpTools>,
intelephense: Option<Intelephense>,
phpactor: Option<Phpactor>,
phpantom: Option<Phpantom>,
xdebug: XDebug,
}

Expand All @@ -26,6 +27,7 @@ impl zed::Extension for PhpExtension {
phptools: None,
intelephense: None,
phpactor: None,
phpantom: None,
xdebug: XDebug::new(),
}
}
Expand Down Expand Up @@ -85,6 +87,10 @@ impl zed::Extension for PhpExtension {
})
}
}
Phpantom::LANGUAGE_SERVER_ID => {
let phpantom = self.phpantom.get_or_insert_with(Phpantom::new);
phpantom.language_server_command(language_server_id, worktree)
}
language_server_id => Err(format!("unknown language server: {language_server_id}")),
}
}
Expand Down