diff --git a/Cargo.lock b/Cargo.lock index 60ed830683..9806c86c96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8004,6 +8004,15 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-php" +version = "0.19.1" +source = "git+https://github.com/tree-sitter/tree-sitter-php?rev=d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462#d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-python" version = "0.20.2" @@ -9432,6 +9441,7 @@ dependencies = [ "tree-sitter-json 0.20.0", "tree-sitter-lua", "tree-sitter-markdown", + "tree-sitter-php", "tree-sitter-python", "tree-sitter-racket", "tree-sitter-ruby", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index d016525af4..0e92b2e3ea 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -114,6 +114,7 @@ tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", re tree-sitter-rust = "0.20.3" tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" } tree-sitter-python = "0.20.2" +tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php", rev = "d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462" } tree-sitter-toml = { git = "https://github.com/tree-sitter/tree-sitter-toml", rev = "342d9be207c2dba869b9967124c679b5e6fd0ebe" } tree-sitter-typescript = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "5d20856f34315b068c41edaee2ac8a100081d259" } tree-sitter-ruby = "0.20.0" diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index 44e144e89b..81edd92d37 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -137,6 +137,7 @@ pub fn init(languages: Arc, node_runtime: Arc) { tree_sitter_yaml::language(), vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime))], ); + language("php", tree_sitter_php::language(), vec![]); } #[cfg(any(test, feature = "test-support"))] diff --git a/crates/zed/src/languages/php/config.toml b/crates/zed/src/languages/php/config.toml new file mode 100644 index 0000000000..e9de52745a --- /dev/null +++ b/crates/zed/src/languages/php/config.toml @@ -0,0 +1,11 @@ +name = "PHP" +path_suffixes = ["php"] +first_line_pattern = '^#!.*php' +line_comment = "// " +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"] }, +] diff --git a/crates/zed/src/languages/php/highlights.scm b/crates/zed/src/languages/php/highlights.scm new file mode 100644 index 0000000000..666a49be2a --- /dev/null +++ b/crates/zed/src/languages/php/highlights.scm @@ -0,0 +1,122 @@ +(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 +"as" @keyword +"break" @keyword +"case" @keyword +"catch" @keyword +"class" @keyword +"const" @keyword +"continue" @keyword +"declare" @keyword +"default" @keyword +"do" @keyword +"echo" @keyword +"else" @keyword +"elseif" @keyword +"enddeclare" @keyword +"endforeach" @keyword +"endif" @keyword +"endswitch" @keyword +"endwhile" @keyword +"extends" @keyword +"final" @keyword +"finally" @keyword +"foreach" @keyword +"function" @keyword +"global" @keyword +"if" @keyword +"implements" @keyword +"include_once" @keyword +"include" @keyword +"insteadof" @keyword +"interface" @keyword +"namespace" @keyword +"new" @keyword +"private" @keyword +"protected" @keyword +"public" @keyword +"require_once" @keyword +"require" @keyword +"return" @keyword +"static" @keyword +"switch" @keyword +"throw" @keyword +"trait" @keyword +"try" @keyword +"use" @keyword +"while" @keyword diff --git a/crates/zed/src/languages/php/injections.scm b/crates/zed/src/languages/php/injections.scm new file mode 100644 index 0000000000..16d5736beb --- /dev/null +++ b/crates/zed/src/languages/php/injections.scm @@ -0,0 +1,3 @@ +((text) @injection.content + (#set! injection.language "html") + (#set! injection.combined)) diff --git a/crates/zed/src/languages/php/outline.scm b/crates/zed/src/languages/php/outline.scm new file mode 100644 index 0000000000..57ea2ae334 --- /dev/null +++ b/crates/zed/src/languages/php/outline.scm @@ -0,0 +1,8 @@ +(class_declaration + "class" @context + name: (name) @name + ) @item + +(function_definition + "function" @context + name: (_) @name) @item diff --git a/crates/zed/src/languages/php/tags.scm b/crates/zed/src/languages/php/tags.scm new file mode 100644 index 0000000000..66d594c254 --- /dev/null +++ b/crates/zed/src/languages/php/tags.scm @@ -0,0 +1,40 @@ +(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/crates/zed/src/languages/python/outline.scm b/crates/zed/src/languages/python/outline.scm index 373c7c7c68..e3efb3dbf6 100644 --- a/crates/zed/src/languages/python/outline.scm +++ b/crates/zed/src/languages/python/outline.scm @@ -6,4 +6,4 @@ (function_definition "async"? @context "def" @context - name: (_) @name) @item \ No newline at end of file + name: (_) @name) @item