Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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";
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