From 62bb3398edeae513eeb4f97dc724ee1021942f2e Mon Sep 17 00:00:00 2001 From: Peter Tripp Date: Mon, 10 Feb 2025 16:07:38 -0500 Subject: [PATCH] Migate PHP Extension to zed-extensions/php (#24583) PHP Extension has been extracted to it's own repository available here: - https://github.com/zed-extensions/php --- Cargo.lock | 7 - Cargo.toml | 1 - extensions/php/Cargo.toml | 16 -- extensions/php/LICENSE-APACHE | 1 - extensions/php/extension.toml | 25 --- extensions/php/languages/php/brackets.scm | 4 - extensions/php/languages/php/config.toml | 18 -- extensions/php/languages/php/embedding.scm | 36 --- extensions/php/languages/php/highlights.scm | 137 ------------ extensions/php/languages/php/indents.scm | 1 - extensions/php/languages/php/injections.scm | 11 - extensions/php/languages/php/outline.scm | 46 ---- extensions/php/languages/php/runnables.scm | 105 --------- extensions/php/languages/php/tags.scm | 40 ---- extensions/php/languages/php/tasks.json | 19 -- extensions/php/languages/php/textobjects.scm | 45 ---- extensions/php/languages/phpdoc/config.toml | 9 - .../php/languages/phpdoc/highlights.scm | 13 -- extensions/php/src/language_servers.rs | 5 - .../php/src/language_servers/intelephense.rs | 209 ------------------ .../php/src/language_servers/phpactor.rs | 85 ------- extensions/php/src/php.rs | 72 ------ 22 files changed, 905 deletions(-) delete mode 100644 extensions/php/Cargo.toml delete mode 120000 extensions/php/LICENSE-APACHE delete mode 100644 extensions/php/extension.toml delete mode 100644 extensions/php/languages/php/brackets.scm delete mode 100644 extensions/php/languages/php/config.toml delete mode 100644 extensions/php/languages/php/embedding.scm delete mode 100644 extensions/php/languages/php/highlights.scm delete mode 100644 extensions/php/languages/php/indents.scm delete mode 100644 extensions/php/languages/php/injections.scm delete mode 100644 extensions/php/languages/php/outline.scm delete mode 100644 extensions/php/languages/php/runnables.scm delete mode 100644 extensions/php/languages/php/tags.scm delete mode 100644 extensions/php/languages/php/tasks.json delete mode 100644 extensions/php/languages/php/textobjects.scm delete mode 100644 extensions/php/languages/phpdoc/config.toml delete mode 100644 extensions/php/languages/phpdoc/highlights.scm delete mode 100644 extensions/php/src/language_servers.rs delete mode 100644 extensions/php/src/language_servers/intelephense.rs delete mode 100644 extensions/php/src/language_servers/phpactor.rs delete mode 100644 extensions/php/src/php.rs diff --git a/Cargo.lock b/Cargo.lock index c114e0ee52..63c66cf045 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16823,13 +16823,6 @@ dependencies = [ "zed_extension_api 0.1.0", ] -[[package]] -name = "zed_php" -version = "0.2.4" -dependencies = [ - "zed_extension_api 0.1.0", -] - [[package]] name = "zed_proto" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index e0481d632a..935b053378 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,7 +171,6 @@ members = [ "extensions/haskell", "extensions/html", "extensions/lua", - "extensions/php", "extensions/perplexity", "extensions/proto", "extensions/purescript", diff --git a/extensions/php/Cargo.toml b/extensions/php/Cargo.toml deleted file mode 100644 index b3f0ad663d..0000000000 --- a/extensions/php/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "zed_php" -version = "0.2.4" -edition.workspace = true -publish.workspace = true -license = "Apache-2.0" - -[lints] -workspace = true - -[lib] -path = "src/php.rs" -crate-type = ["cdylib"] - -[dependencies] -zed_extension_api = "0.1.0" diff --git a/extensions/php/LICENSE-APACHE b/extensions/php/LICENSE-APACHE deleted file mode 120000 index 1cd601d0a3..0000000000 --- a/extensions/php/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-APACHE \ No newline at end of file diff --git a/extensions/php/extension.toml b/extensions/php/extension.toml deleted file mode 100644 index 0f89e3f885..0000000000 --- a/extensions/php/extension.toml +++ /dev/null @@ -1,25 +0,0 @@ -id = "php" -name = "PHP" -description = "PHP support." -version = "0.2.4" -schema_version = 1 -authors = ["Piotr Osiewicz "] -repository = "https://github.com/zed-industries/zed" - -[language_servers.intelephense] -name = "Intelephense" -language = "PHP" -language_ids = { PHP = "php"} - -[language_servers.phpactor] -name = "Phpactor" -language = "PHP" - -[grammars.php] -repository = "https://github.com/tree-sitter/tree-sitter-php" -commit = "8ab93274065cbaf529ea15c24360cfa3348ec9e4" -path = "php" - -[grammars.phpdoc] -repository = "https://github.com/claytonrcarter/tree-sitter-phpdoc" -commit = "1d0e255b37477d0ca46f1c9e9268c8fa76c0b3fc" diff --git a/extensions/php/languages/php/brackets.scm b/extensions/php/languages/php/brackets.scm deleted file mode 100644 index 988602aa8d..0000000000 --- a/extensions/php/languages/php/brackets.scm +++ /dev/null @@ -1,4 +0,0 @@ -("{" @open "}" @close) -("(" @open ")" @close) -("[" @open "]" @close) -("\"" @open "\"" @close) diff --git a/extensions/php/languages/php/config.toml b/extensions/php/languages/php/config.toml deleted file mode 100644 index 54b6c2905f..0000000000 --- a/extensions/php/languages/php/config.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "PHP" -grammar = "php" -path_suffixes = ["php"] -first_line_pattern = '^#!.*php' -line_comments = ["// ", "# "] -autoclose_before = ";:.,=}])>" -brackets = [ - { start = "{", end = "}", close = true, newline = true }, - { start = "[", end = "]", close = true, newline = true }, - { start = "(", end = ")", close = true, newline = true }, - { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }, - { start = "'", end = "'", close = true, newline = false, not_in = ["string"] }, -] -collapsed_placeholder = "/* ... */" -word_characters = ["$"] -scope_opt_in_language_servers = ["tailwindcss-language-server"] -prettier_parser_name = "php" -prettier_plugins = ["@prettier/plugin-php"] diff --git a/extensions/php/languages/php/embedding.scm b/extensions/php/languages/php/embedding.scm deleted file mode 100644 index db277775b3..0000000000 --- a/extensions/php/languages/php/embedding.scm +++ /dev/null @@ -1,36 +0,0 @@ -( - (comment)* @context - . - [ - (function_definition - "function" @name - name: (_) @name - body: (_ - "{" @keep - "}" @keep) @collapse - ) - - (trait_declaration - "trait" @name - name: (_) @name) - - (method_declaration - "function" @name - name: (_) @name - body: (_ - "{" @keep - "}" @keep) @collapse - ) - - (interface_declaration - "interface" @name - name: (_) @name - ) - - (enum_declaration - "enum" @name - name: (_) @name - ) - - ] @item - ) diff --git a/extensions/php/languages/php/highlights.scm b/extensions/php/languages/php/highlights.scm deleted file mode 100644 index 6afeb1090b..0000000000 --- a/extensions/php/languages/php/highlights.scm +++ /dev/null @@ -1,137 +0,0 @@ -(php_tag) @tag -"?>" @tag - -; Types - -(primitive_type) @type.builtin -(cast_type) @type.builtin -(named_type (name) @type) @type -(named_type (qualified_name) @type) @type - -; Functions - -(array_creation_expression "array" @function.builtin) -(list_literal "list" @function.builtin) - -(method_declaration - name: (name) @function.method) - -(function_call_expression - function: [(qualified_name (name)) (name)] @function) - -(scoped_call_expression - name: (name) @function) - -(member_call_expression - name: (name) @function.method) - -(function_definition - name: (name) @function) - -; Member - -(property_element - (variable_name) @property) - -(member_access_expression - name: (variable_name (name)) @property) -(member_access_expression - name: (name) @property) - -; Variables - -(relative_scope) @variable.builtin - -((name) @constant - (#match? @constant "^_?[A-Z][A-Z\\d_]+$")) -((name) @constant.builtin - (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) - -((name) @constructor - (#match? @constructor "^[A-Z]")) - -((name) @variable.builtin - (#eq? @variable.builtin "this")) - -(variable_name) @variable - -; Basic tokens -[ - (string) - (string_value) - (encapsed_string) - (heredoc) - (heredoc_body) - (nowdoc_body) -] @string -(boolean) @constant.builtin -(null) @constant.builtin -(integer) @number -(float) @number -(comment) @comment - -"$" @operator - -; Keywords - -"abstract" @keyword -"and" @keyword -"as" @keyword -"break" @keyword -"callable" @keyword -"case" @keyword -"catch" @keyword -"class" @keyword -"clone" @keyword -"const" @keyword -"continue" @keyword -"declare" @keyword -"default" @keyword -"do" @keyword -"echo" @keyword -"else" @keyword -"elseif" @keyword -"enum" @keyword -"enddeclare" @keyword -"endfor" @keyword -"endforeach" @keyword -"endif" @keyword -"endswitch" @keyword -"endwhile" @keyword -"extends" @keyword -"final" @keyword -"readonly" @keyword -"finally" @keyword -"for" @keyword -"foreach" @keyword -"fn" @keyword -"function" @keyword -"global" @keyword -"goto" @keyword -"if" @keyword -"implements" @keyword -"include_once" @keyword -"include" @keyword -"instanceof" @keyword -"insteadof" @keyword -"interface" @keyword -"match" @keyword -"namespace" @keyword -"new" @keyword -"or" @keyword -"print" @keyword -"private" @keyword -"protected" @keyword -"public" @keyword -"readonly" @keyword -"require_once" @keyword -"require" @keyword -"return" @keyword -"static" @keyword -"switch" @keyword -"throw" @keyword -"trait" @keyword -"try" @keyword -"use" @keyword -"while" @keyword -"xor" @keyword diff --git a/extensions/php/languages/php/indents.scm b/extensions/php/languages/php/indents.scm deleted file mode 100644 index e975469092..0000000000 --- a/extensions/php/languages/php/indents.scm +++ /dev/null @@ -1 +0,0 @@ -(_ "{" "}" @end) @indent diff --git a/extensions/php/languages/php/injections.scm b/extensions/php/languages/php/injections.scm deleted file mode 100644 index 657145c13f..0000000000 --- a/extensions/php/languages/php/injections.scm +++ /dev/null @@ -1,11 +0,0 @@ -((text) @injection.content - (#set! injection.language "html") - (#set! injection.combined)) - -((comment) @injection.content - (#match? @injection.content "^/\\*\\*[^*]") - (#set! injection.language "phpdoc")) - -((heredoc_body) (heredoc_end) @injection.language) @injection.content - -((nowdoc_body) (heredoc_end) @injection.language) @injection.content diff --git a/extensions/php/languages/php/outline.scm b/extensions/php/languages/php/outline.scm deleted file mode 100644 index 13c11676b9..0000000000 --- a/extensions/php/languages/php/outline.scm +++ /dev/null @@ -1,46 +0,0 @@ -(class_declaration - "class" @context - name: (name) @name - ) @item - -(function_definition - "function" @context - name: (_) @name - ) @item - -(method_declaration - "function" @context - name: (_) @name - ) @item - -(interface_declaration - "interface" @context - name: (_) @name - ) @item - -(enum_declaration - "enum" @context - name: (_) @name - ) @item - -(trait_declaration - "trait" @context - name: (_) @name - ) @item - -; Add support for Pest runnable -(function_call_expression - function: (_) @context - (#any-of? @context "it" "test" "describe") - arguments: (arguments - . - (argument - [ - (encapsed_string (string_value) @name) - (string (string_value) @name) - ] - ) - ) -) @item - -(comment) @annotation diff --git a/extensions/php/languages/php/runnables.scm b/extensions/php/languages/php/runnables.scm deleted file mode 100644 index 96c90d2f8a..0000000000 --- a/extensions/php/languages/php/runnables.scm +++ /dev/null @@ -1,105 +0,0 @@ -; Class that follow the naming convention of PHPUnit test classes -; and that doesn't have the abstract modifier -; and have a method that follow the naming convention of PHPUnit test methods -; and the method is public -( - (class_declaration - modifier: (_)? @_modifier - (#not-eq? @_modifier "abstract") - name: (_) @_name - (#match? @_name ".*Test$") - body: (declaration_list - (method_declaration - (visibility_modifier)? @_visibility - (#eq? @_visibility "public") - name: (_) @run - (#match? @run "^test.*") - ) - ) - ) @_phpunit-test - (#set! tag phpunit-test) -) - -; Class that follow the naming convention of PHPUnit test classes -; and that doesn't have the abstract modifier -; and have a method that has the @test annotation -; and the method is public -( - (class_declaration - modifier: (_)? @_modifier - (#not-eq? @_modifier "abstract") - name: (_) @_name - (#match? @_name ".*Test$") - body: (declaration_list - ((comment) @_comment - (#match? @_comment ".*@test\\b.*") - . - (method_declaration - (visibility_modifier)? @_visibility - (#eq? @_visibility "public") - name: (_) @run - (#not-match? @run "^test.*") - )) - ) - ) @_phpunit-test - (#set! tag phpunit-test) -) - -; Class that follow the naming convention of PHPUnit test classes -; and that doesn't have the abstract modifier -; and have a method that has the #[Test] attribute -; and the method is public -( - (class_declaration - modifier: (_)? @_modifier - (#not-eq? @_modifier "abstract") - name: (_) @_name - (#match? @_name ".*Test$") - body: (declaration_list - (method_declaration - (attribute_list - (attribute_group - (attribute (name) @_attribute) - ) - ) - (#eq? @_attribute "Test") - (visibility_modifier)? @_visibility - (#eq? @_visibility "public") - name: (_) @run - (#not-match? @run "^test.*") - ) - ) - ) @_phpunit-test - (#set! tag phpunit-test) -) - -; Class that follow the naming convention of PHPUnit test classes -; and that doesn't have the abstract modifier -( - (class_declaration - modifier: (_)? @_modifier - (#not-eq? @_modifier "abstract") - name: (_) @run - (#match? @run ".*Test$") - ) @_phpunit-test - (#set! tag phpunit-test) -) - -; Add support for Pest runnable -; Function expression that has `it`, `test` or `describe` as the function name -( - (function_call_expression - function: (_) @_name - (#any-of? @_name "it" "test" "describe") - arguments: (arguments - . - (argument - [ - (encapsed_string (string_value) @run) - (string (string_value) @run) - ] - ) - ) - ) @_pest-test - (#set! tag pest-test) -) diff --git a/extensions/php/languages/php/tags.scm b/extensions/php/languages/php/tags.scm deleted file mode 100644 index 66d594c254..0000000000 --- a/extensions/php/languages/php/tags.scm +++ /dev/null @@ -1,40 +0,0 @@ -(namespace_definition - name: (namespace_name) @name) @module - -(interface_declaration - name: (name) @name) @definition.interface - -(trait_declaration - name: (name) @name) @definition.interface - -(class_declaration - name: (name) @name) @definition.class - -(class_interface_clause [(name) (qualified_name)] @name) @impl - -(property_declaration - (property_element (variable_name (name) @name))) @definition.field - -(function_definition - name: (name) @name) @definition.function - -(method_declaration - name: (name) @name) @definition.function - -(object_creation_expression - [ - (qualified_name (name) @name) - (variable_name (name) @name) - ]) @reference.class - -(function_call_expression - function: [ - (qualified_name (name) @name) - (variable_name (name)) @name - ]) @reference.call - -(scoped_call_expression - name: (name) @name) @reference.call - -(member_call_expression - name: (name) @name) @reference.call diff --git a/extensions/php/languages/php/tasks.json b/extensions/php/languages/php/tasks.json deleted file mode 100644 index 65800eebe2..0000000000 --- a/extensions/php/languages/php/tasks.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - { - "label": "phpunit test $ZED_SYMBOL", - "command": "./vendor/bin/phpunit", - "args": ["--filter $ZED_SYMBOL $ZED_FILE"], - "tags": ["phpunit-test"] - }, - { - "label": "pest test $ZED_SYMBOL", - "command": "./vendor/bin/pest", - "args": ["--filter \"$ZED_SYMBOL\" $ZED_FILE"], - "tags": ["pest-test"] - }, - { - "label": "execute selection $ZED_SELECTED_TEXT", - "command": "php", - "args": ["-r", "$ZED_SELECTED_TEXT"] - } -] diff --git a/extensions/php/languages/php/textobjects.scm b/extensions/php/languages/php/textobjects.scm deleted file mode 100644 index d86a0c1252..0000000000 --- a/extensions/php/languages/php/textobjects.scm +++ /dev/null @@ -1,45 +0,0 @@ -(function_definition - body: (_ - "{" - (_)* @function.inside - "}" )) @function.around - -(method_declaration - body: (_ - "{" - (_)* @function.inside - "}" )) @function.around - -(method_declaration) @function.around - -(class_declaration - body: (_ - "{" - (_)* @class.inside - "}")) @class.around - -(interface_declaration - body: (_ - "{" - (_)* @class.inside - "}")) @class.around - -(trait_declaration - body: (_ - "{" - (_)* @class.inside - "}")) @class.around - -(enum_declaration - body: (_ - "{" - (_)* @class.inside - "}")) @class.around - -(namespace_definition - body: (_ - "{" - (_)* @class.inside - "}")) @class.around - -(comment)+ @comment.around diff --git a/extensions/php/languages/phpdoc/config.toml b/extensions/php/languages/phpdoc/config.toml deleted file mode 100644 index 78aa5e64aa..0000000000 --- a/extensions/php/languages/phpdoc/config.toml +++ /dev/null @@ -1,9 +0,0 @@ -name = "PHPDoc" -grammar = "phpdoc" -autoclose_before = "]})>" -brackets = [ - { start = "{", end = "}", close = true, newline = false }, - { start = "[", end = "]", close = true, newline = false }, - { start = "(", end = ")", close = true, newline = false }, - { start = "<", end = ">", close = true, newline = false }, -] diff --git a/extensions/php/languages/phpdoc/highlights.scm b/extensions/php/languages/phpdoc/highlights.scm deleted file mode 100644 index 767d8e6220..0000000000 --- a/extensions/php/languages/phpdoc/highlights.scm +++ /dev/null @@ -1,13 +0,0 @@ -(tag_name) @keyword - -(tag (variable_name) @variable) -(variable_name "$" @operator) - -(tag - (tag_name) @keyword - (#eq? @keyword "@method") - (name) @function.method) - -(primitive_type) @type.builtin -(named_type (name) @type) @type -(named_type (qualified_name) @type) @type diff --git a/extensions/php/src/language_servers.rs b/extensions/php/src/language_servers.rs deleted file mode 100644 index f209d1c00a..0000000000 --- a/extensions/php/src/language_servers.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod intelephense; -mod phpactor; - -pub use intelephense::*; -pub use phpactor::*; diff --git a/extensions/php/src/language_servers/intelephense.rs b/extensions/php/src/language_servers/intelephense.rs deleted file mode 100644 index 23f47ac5c0..0000000000 --- a/extensions/php/src/language_servers/intelephense.rs +++ /dev/null @@ -1,209 +0,0 @@ -use std::{env, fs}; - -use zed::{CodeLabel, CodeLabelSpan}; -use zed_extension_api::settings::LspSettings; -use zed_extension_api::{self as zed, serde_json, LanguageServerId, Result}; - -const SERVER_PATH: &str = "node_modules/intelephense/lib/intelephense.js"; -const PACKAGE_NAME: &str = "intelephense"; - -pub struct Intelephense { - did_find_server: bool, -} - -impl Intelephense { - pub const LANGUAGE_SERVER_ID: &'static str = "intelephense"; - - pub fn new() -> Self { - Self { - did_find_server: false, - } - } - - pub fn language_server_command( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - if let Some(path) = worktree.which("intelephense") { - return Ok(zed::Command { - command: path, - args: vec!["--stdio".to_string()], - env: Default::default(), - }); - } - - let server_path = self.server_script_path(language_server_id)?; - 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 server_exists(&self) -> bool { - fs::metadata(SERVER_PATH).map_or(false, |stat| stat.is_file()) - } - - fn server_script_path(&mut self, language_server_id: &LanguageServerId) -> Result { - 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( - language_server_id, - &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( - language_server_id, - &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()) - } - - pub fn language_server_workspace_configuration( - &mut self, - worktree: &zed::Worktree, - ) -> Result> { - let settings = LspSettings::for_worktree("intelephense", worktree) - .ok() - .and_then(|lsp_settings| lsp_settings.settings.clone()) - .unwrap_or_default(); - - Ok(Some(serde_json::json!({ - "intelephense": settings - }))) - } - - pub fn label_for_completion(&self, completion: zed::lsp::Completion) -> Option { - let label = &completion.label; - - match completion.kind? { - zed::lsp::CompletionKind::Method => { - // __construct method doesn't have a detail - if let Some(ref detail) = completion.detail { - if detail.is_empty() { - return Some(CodeLabel { - spans: vec![ - CodeLabelSpan::literal(label, Some("function.method".to_string())), - CodeLabelSpan::literal("()", None), - ], - filter_range: (0..label.len()).into(), - code: completion.label, - }); - } - } - - let mut parts = completion.detail.as_ref()?.split(":"); - // E.g., `foo(string $var)` - let name_and_params = parts.next()?; - let return_type = parts.next()?.trim(); - - let (_, params) = name_and_params.split_once("(")?; - let params = params.trim_end_matches(")"); - - Some(CodeLabel { - spans: vec![ - CodeLabelSpan::literal(label, Some("function.method".to_string())), - CodeLabelSpan::literal("(", None), - CodeLabelSpan::literal(params, Some("comment".to_string())), - CodeLabelSpan::literal("): ", None), - CodeLabelSpan::literal(return_type, Some("type".to_string())), - ], - filter_range: (0..label.len()).into(), - code: completion.label, - }) - } - zed::lsp::CompletionKind::Constant | zed::lsp::CompletionKind::EnumMember => { - if let Some(ref detail) = completion.detail { - if !detail.is_empty() { - return Some(CodeLabel { - spans: vec![ - CodeLabelSpan::literal(label, Some("constant".to_string())), - CodeLabelSpan::literal(" ", None), - CodeLabelSpan::literal(detail, Some("comment".to_string())), - ], - filter_range: (0..label.len()).into(), - code: completion.label, - }); - } - } - - Some(CodeLabel { - spans: vec![CodeLabelSpan::literal(label, Some("constant".to_string()))], - filter_range: (0..label.len()).into(), - code: completion.label, - }) - } - zed::lsp::CompletionKind::Property => { - let return_type = completion.detail?; - Some(CodeLabel { - spans: vec![ - CodeLabelSpan::literal(label, Some("attribute".to_string())), - CodeLabelSpan::literal(": ", None), - CodeLabelSpan::literal(return_type, Some("type".to_string())), - ], - filter_range: (0..label.len()).into(), - code: completion.label, - }) - } - zed::lsp::CompletionKind::Variable => { - // See https://www.php.net/manual/en/reserved.variables.php - const SYSTEM_VAR_NAMES: &[&str] = - &["argc", "argv", "php_errormsg", "http_response_header"]; - - let var_name = completion.label.trim_start_matches("$"); - let is_uppercase = var_name - .chars() - .filter(|c| c.is_alphabetic()) - .all(|c| c.is_uppercase()); - let is_system_constant = var_name.starts_with("_"); - let is_reserved = SYSTEM_VAR_NAMES.contains(&var_name); - - let highlight = if is_uppercase || is_system_constant || is_reserved { - Some("comment".to_string()) - } else { - None - }; - - Some(CodeLabel { - spans: vec![CodeLabelSpan::literal(label, highlight)], - filter_range: (0..label.len()).into(), - code: completion.label, - }) - } - _ => None, - } - } -} diff --git a/extensions/php/src/language_servers/phpactor.rs b/extensions/php/src/language_servers/phpactor.rs deleted file mode 100644 index 3ba668b1e8..0000000000 --- a/extensions/php/src/language_servers/phpactor.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::fs; - -use zed_extension_api::{self as zed, LanguageServerId, Result}; - -pub struct Phpactor { - cached_binary_path: Option, -} - -impl Phpactor { - pub const LANGUAGE_SERVER_ID: &'static str = "phpactor"; - - pub fn new() -> Self { - Self { - cached_binary_path: None, - } - } - - pub fn language_server_binary_path( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - if let Some(path) = worktree.which("phpactor") { - 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()); - } - } - - zed::set_language_server_installation_status( - language_server_id, - &zed::LanguageServerInstallationStatus::CheckingForUpdate, - ); - let release = zed::latest_github_release( - "phpactor/phpactor", - zed::GithubReleaseOptions { - require_assets: true, - pre_release: false, - }, - )?; - - let asset_name = "phpactor.phar"; - 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!("phpactor-{}", release.version); - fs::create_dir_all(&version_dir).map_err(|e| format!("failed to create directory: {e}"))?; - - let binary_path = format!("{version_dir}/phpactor.phar"); - - 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, - &binary_path, - zed::DownloadedFileType::Uncompressed, - ) - .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) - } -} diff --git a/extensions/php/src/php.rs b/extensions/php/src/php.rs deleted file mode 100644 index 53b4c29951..0000000000 --- a/extensions/php/src/php.rs +++ /dev/null @@ -1,72 +0,0 @@ -mod language_servers; - -use zed::CodeLabel; -use zed_extension_api::{self as zed, serde_json, LanguageServerId, Result}; - -use crate::language_servers::{Intelephense, Phpactor}; - -struct PhpExtension { - intelephense: Option, - phpactor: Option, -} - -impl zed::Extension for PhpExtension { - fn new() -> Self { - Self { - intelephense: None, - phpactor: None, - } - } - - fn language_server_command( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result { - match language_server_id.as_ref() { - Intelephense::LANGUAGE_SERVER_ID => { - let intelephense = self.intelephense.get_or_insert_with(Intelephense::new); - intelephense.language_server_command(language_server_id, worktree) - } - Phpactor::LANGUAGE_SERVER_ID => { - let phpactor = self.phpactor.get_or_insert_with(Phpactor::new); - - Ok(zed::Command { - command: phpactor.language_server_binary_path(language_server_id, worktree)?, - args: vec!["language-server".into()], - env: Default::default(), - }) - } - language_server_id => Err(format!("unknown language server: {language_server_id}")), - } - } - - fn language_server_workspace_configuration( - &mut self, - language_server_id: &LanguageServerId, - worktree: &zed::Worktree, - ) -> Result> { - if language_server_id.as_ref() == Intelephense::LANGUAGE_SERVER_ID { - if let Some(intelephense) = self.intelephense.as_mut() { - return intelephense.language_server_workspace_configuration(worktree); - } - } - - Ok(None) - } - - fn label_for_completion( - &self, - language_server_id: &zed::LanguageServerId, - completion: zed::lsp::Completion, - ) -> Option { - match language_server_id.as_ref() { - Intelephense::LANGUAGE_SERVER_ID => { - self.intelephense.as_ref()?.label_for_completion(completion) - } - _ => None, - } - } -} - -zed::register_extension!(PhpExtension);