From a1fe5abeaf500b1e4fb484f0733fdbb9114d68e8 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:31:20 +0200 Subject: [PATCH 01/13] Add rudimentary PHP syntax highlighting --- Cargo.lock | 10 ++ crates/zed/Cargo.toml | 1 + crates/zed/src/languages.rs | 1 + crates/zed/src/languages/php/config.toml | 11 ++ crates/zed/src/languages/php/highlights.scm | 122 ++++++++++++++++++++ crates/zed/src/languages/php/injections.scm | 3 + crates/zed/src/languages/php/outline.scm | 8 ++ crates/zed/src/languages/php/tags.scm | 40 +++++++ crates/zed/src/languages/python/outline.scm | 2 +- 9 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 crates/zed/src/languages/php/config.toml create mode 100644 crates/zed/src/languages/php/highlights.scm create mode 100644 crates/zed/src/languages/php/injections.scm create mode 100644 crates/zed/src/languages/php/outline.scm create mode 100644 crates/zed/src/languages/php/tags.scm 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 From 1cc8ecad1215e7d9e8b7411cb2e03f7d6b1c52ed Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:33:09 +0200 Subject: [PATCH 02/13] Fix HTML injections (Thanks Max!) Co-authored-by: Max --- crates/zed/src/languages/php/injections.scm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/zed/src/languages/php/injections.scm b/crates/zed/src/languages/php/injections.scm index 16d5736beb..57abd8ea2b 100644 --- a/crates/zed/src/languages/php/injections.scm +++ b/crates/zed/src/languages/php/injections.scm @@ -1,3 +1,3 @@ -((text) @injection.content - (#set! injection.language "html") - (#set! injection.combined)) +((text) @content + (#set! "language" "html") + (#set! "combined")) From 608c16342c0ecdec4373e9d848a88ab1c37e5214 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:23:49 +0200 Subject: [PATCH 03/13] Update outline queries; add enum as a highlighted keyword --- crates/zed/src/languages/php/highlights.scm | 1 + crates/zed/src/languages/php/outline.scm | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/zed/src/languages/php/highlights.scm b/crates/zed/src/languages/php/highlights.scm index 666a49be2a..fcb087c47d 100644 --- a/crates/zed/src/languages/php/highlights.scm +++ b/crates/zed/src/languages/php/highlights.scm @@ -88,6 +88,7 @@ "echo" @keyword "else" @keyword "elseif" @keyword +"enum" @keyword "enddeclare" @keyword "endforeach" @keyword "endif" @keyword diff --git a/crates/zed/src/languages/php/outline.scm b/crates/zed/src/languages/php/outline.scm index 57ea2ae334..4934bc494d 100644 --- a/crates/zed/src/languages/php/outline.scm +++ b/crates/zed/src/languages/php/outline.scm @@ -5,4 +5,22 @@ (function_definition "function" @context - name: (_) @name) @item + name: (_) @name + ) @item + + + +(method_declaration + "function" @context + name: (_) @name + ) @item + +(interface_declaration + "interface" @context + name: (_) @name + ) @item + +(enum_declaration + "enum" @context + name: (_) @name + ) @item From dc557e16478ba0fe570cef208185ac104842bdde Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 11:34:22 +0200 Subject: [PATCH 04/13] Add scaffolding of php language server --- crates/language/src/language.rs | 23 +++- crates/lsp/src/lsp.rs | 7 +- crates/project/src/project.rs | 2 +- crates/zed/src/languages.rs | 9 +- crates/zed/src/languages/php.rs | 203 ++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 12 deletions(-) create mode 100644 crates/zed/src/languages/php.rs diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index e8450344b8..af6a6e5045 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -262,24 +262,31 @@ pub trait LspAdapter: 'static + Send + Sync { container_dir: PathBuf, ) -> Option; - async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + async fn process_diagnostics(&self, d: &mut lsp::PublishDiagnosticsParams) { + dbg!(d); + } - async fn process_completion(&self, _: &mut lsp::CompletionItem) {} + async fn process_completion(&self, d: &mut lsp::CompletionItem) { + dbg!(d); + } async fn label_for_completion( &self, - _: &lsp::CompletionItem, + item: &lsp::CompletionItem, _: &Arc, ) -> Option { + dbg!(item); None } async fn label_for_symbol( &self, - _: &str, - _: lsp::SymbolKind, + name: &str, + kind: lsp::SymbolKind, _: &Arc, ) -> Option { + dbg!(name); + dbg!(kind); None } @@ -321,7 +328,7 @@ pub struct CodeLabel { pub filter_range: Range, } -#[derive(Clone, Deserialize)] +#[derive(Clone, Deserialize, Debug)] pub struct LanguageConfig { pub name: Arc, pub path_suffixes: Vec, @@ -810,6 +817,7 @@ impl LanguageRegistry { .spawn(async move { let id = language.id; let queries = (language.get_queries)(&language.path); + dbg!(&language.path); let language = Language::new(language.config, Some(language.grammar)) .with_lsp_adapters(language.lsp_adapters) @@ -819,9 +827,11 @@ impl LanguageRegistry { Ok(language) => { let language = Arc::new(language); let mut state = this.state.write(); + state.add(language.clone()); state.mark_language_loaded(id); if let Some(mut txs) = state.loading_languages.remove(&id) { + dbg!(&name); for tx in txs.drain(..) { let _ = tx.send(Ok(language.clone())); } @@ -829,6 +839,7 @@ impl LanguageRegistry { } Err(err) => { log::error!("failed to load language {name} - {err}"); + dbg!(&name); let mut state = this.state.write(); state.mark_language_loaded(id); if let Some(mut txs) = state.loading_languages.remove(&id) { diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index a01f6e8a49..78c858a90c 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -151,16 +151,17 @@ impl LanguageServer { let stdin = server.stdin.take().unwrap(); let stout = server.stdout.take().unwrap(); let mut server = Self::new_internal( - server_id, + server_id.clone(), stdin, stout, Some(server), root_path, code_action_kinds, cx, - |notification| { + move |notification| { log::info!( - "unhandled notification {}:\n{}", + "{} unhandled notification {}:\n{}", + server_id, notification.method, serde_json::to_string_pretty( ¬ification diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 81db0c7ed7..666503e210 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2680,6 +2680,7 @@ impl Project { key: (WorktreeId, LanguageServerName), cx: &mut AsyncAppContext, ) -> Result>> { + dbg!(language.name()); let setup = Self::setup_pending_language_server( this, initialization_options, @@ -2694,7 +2695,6 @@ impl Project { Some(language_server) => language_server, None => return Ok(None), }; - let this = match this.upgrade(cx) { Some(this) => this, None => return Err(anyhow!("failed to upgrade project handle")), diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index 81edd92d37..2a29fd537b 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -13,6 +13,7 @@ mod json; #[cfg(feature = "plugin_runtime")] mod language_plugin; mod lua; +mod php; mod python; mod ruby; mod rust; @@ -135,9 +136,13 @@ pub fn init(languages: Arc, node_runtime: Arc) { language( "yaml", tree_sitter_yaml::language(), - vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime))], + vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime.clone()))], + ); + language( + "php", + tree_sitter_php::language(), + vec![Arc::new(php::IntelephenseLspAdapter::new(node_runtime))], ); - language("php", tree_sitter_php::language(), vec![]); } #[cfg(any(test, feature = "test-support"))] diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs new file mode 100644 index 0000000000..b42ad18a53 --- /dev/null +++ b/crates/zed/src/languages/php.rs @@ -0,0 +1,203 @@ +use anyhow::{anyhow, Result}; +use async_compression::futures::bufread::GzipDecoder; +use async_tar::Archive; +use async_trait::async_trait; +use futures::{future::BoxFuture, FutureExt}; +use gpui::AppContext; +use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; +use lsp::{CodeActionKind, LanguageServerBinary}; +use node_runtime::NodeRuntime; +use serde_json::{json, Value}; +use smol::{fs, io::BufReader, stream::StreamExt}; +use std::{ + any::Any, + ffi::OsString, + future, + path::{Path, PathBuf}, + sync::Arc, +}; +use util::ResultExt; + +fn intelephense_server_binary_arguments(server_path: &Path) -> Vec { + vec![server_path.into(), "--stdio".into()] +} + +pub struct IntelephenseVersion(String); + +pub struct IntelephenseLspAdapter { + node: Arc, +} + +impl IntelephenseLspAdapter { + const SERVER_PATH: &'static str = "node_modules/intelephense/lib/intelephense.js"; + + #[allow(unused)] + pub fn new(node: Arc) -> Self { + Self { node } + } +} + +#[async_trait] +impl LspAdapter for IntelephenseLspAdapter { + async fn name(&self) -> LanguageServerName { + LanguageServerName("intelephense".into()) + } + + async fn fetch_latest_server_version( + &self, + _delegate: &dyn LspAdapterDelegate, + ) -> Result> { + // At the time of writing the latest vscode-eslint release was released in 2020 and requires + // special custom LSP protocol extensions be handled to fully initialize. Download the latest + // prerelease instead to sidestep this issue + dbg!("Strarting fetching server binary version"); + Ok(Box::new(IntelephenseVersion( + self.node.npm_package_latest_version("intelephense").await?, + )) as Box<_>) + } + + async fn fetch_server_binary( + &self, + version: Box, + container_dir: PathBuf, + _delegate: &dyn LspAdapterDelegate, + ) -> Result { + dbg!("Strarting fetching server binary"); + let version = version.downcast::().unwrap(); + let server_path = container_dir.join(Self::SERVER_PATH); + + if fs::metadata(&server_path).await.is_err() { + self.node + .npm_install_packages(&container_dir, [("intelephense", version.0.as_str())]) + .await?; + } + dbg!("Fetched server binary"); + Ok(LanguageServerBinary { + path: dbg!(self.node.binary_path().await)?, + arguments: intelephense_server_binary_arguments(&server_path), + }) + } + + async fn cached_server_binary( + &self, + container_dir: PathBuf, + _: &dyn LspAdapterDelegate, + ) -> Option { + dbg!("cached_server_binary"); + get_cached_server_binary(container_dir, &self.node).await + } + + async fn installation_test_binary( + &self, + container_dir: PathBuf, + ) -> Option { + dbg!("installation_test_binary"); + get_cached_server_binary(container_dir, &self.node).await + } + + async fn label_for_completion( + &self, + _item: &lsp::CompletionItem, + _language: &Arc, + ) -> Option { + dbg!(_item.kind); + None + } + + async fn initialization_options(&self) -> Option { + dbg!("init_options"); + None + } +} + +async fn get_cached_server_binary( + container_dir: PathBuf, + node: &NodeRuntime, +) -> Option { + (|| async move { + let mut last_version_dir = None; + let mut entries = fs::read_dir(&container_dir).await?; + while let Some(entry) = entries.next().await { + let entry = entry?; + if entry.file_type().await?.is_dir() { + last_version_dir = Some(entry.path()); + } + } + let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?; + let server_path = last_version_dir.join(IntelephenseLspAdapter::SERVER_PATH); + if server_path.exists() { + Ok(LanguageServerBinary { + path: node.binary_path().await?, + arguments: intelephense_server_binary_arguments(&server_path), + }) + } else { + Err(anyhow!( + "missing executable in directory {:?}", + last_version_dir + )) + } + })() + .await + .log_err() +} + +#[cfg(test)] +mod tests { + use gpui::TestAppContext; + use unindent::Unindent; + + #[gpui::test] + async fn test_outline(cx: &mut TestAppContext) { + let language = crate::languages::language("php", tree_sitter_php::language(), None).await; + + /*let text = r#" + function a() { + // local variables are omitted + let a1 = 1; + // all functions are included + async function a2() {} + } + // top-level variables are included + let b: C + function getB() {} + // exported variables are included + export const d = e; + "# + .unindent();*/ + let text = r#" + function a() { + // local variables are omitted + $a1 = 1; + // all functions are included + function a2() {} + } + class Foo {} + "# + .unindent(); + let buffer = + cx.add_model(|cx| language::Buffer::new(0, text, cx).with_language(language, cx)); + let outline = buffer.read_with(cx, |buffer, _| buffer.snapshot().outline(None).unwrap()); + panic!( + "{:?}", + outline + .items + .iter() + .map(|item| (item.text.as_str(), item.depth)) + .collect::>() + ); + assert_eq!( + outline + .items + .iter() + .map(|item| (item.text.as_str(), item.depth)) + .collect::>(), + &[ + ("function a()", 0), + ("async function a2()", 1), + ("let b", 0), + ("function getB()", 0), + ("const d", 0), + ] + ); + } +} From 965cc2efbc6fbc6316d82a27af0d39deb535c539 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:07:25 +0200 Subject: [PATCH 05/13] Fix a crash in tree-sitter-php --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c972dc2530..d433805a1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8053,7 +8053,7 @@ dependencies = [ [[package]] name = "tree-sitter-php" version = "0.19.1" -source = "git+https://github.com/tree-sitter/tree-sitter-php?rev=d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462#d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462" +source = "git+https://github.com/tree-sitter/tree-sitter-php?rev=d43130fd1525301e9826f420c5393a4d169819fc#d43130fd1525301e9826f420c5393a4d169819fc" dependencies = [ "cc", "tree-sitter", diff --git a/Cargo.toml b/Cargo.toml index 9a4fc81607..7a32938c37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,7 +117,7 @@ tree-sitter-heex = { git = "https://github.com/phoenixframework/tree-sitter-heex tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "40a81c01a40ac48744e0c8ccabbaba1920441199" } tree-sitter-rust = "0.20.3" tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" } -tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php", rev = "d38adb26304d9b9d38e9a3b4aae0ec4b29bf9462" } +tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php", rev = "d43130fd1525301e9826f420c5393a4d169819fc" } tree-sitter-python = "0.20.2" 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" } From 94796e943b16053886a282dd944d431cf6046340 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:36:08 +0200 Subject: [PATCH 06/13] Set language id for PHP. LSP works! --- crates/zed/src/languages/php.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index b42ad18a53..ee6493b576 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -2,6 +2,7 @@ use anyhow::{anyhow, Result}; use async_compression::futures::bufread::GzipDecoder; use async_tar::Archive; use async_trait::async_trait; +use collections::HashMap; use futures::{future::BoxFuture, FutureExt}; use gpui::AppContext; use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; @@ -50,7 +51,6 @@ impl LspAdapter for IntelephenseLspAdapter { // At the time of writing the latest vscode-eslint release was released in 2020 and requires // special custom LSP protocol extensions be handled to fully initialize. Download the latest // prerelease instead to sidestep this issue - dbg!("Strarting fetching server binary version"); Ok(Box::new(IntelephenseVersion( self.node.npm_package_latest_version("intelephense").await?, )) as Box<_>) @@ -62,7 +62,6 @@ impl LspAdapter for IntelephenseLspAdapter { container_dir: PathBuf, _delegate: &dyn LspAdapterDelegate, ) -> Result { - dbg!("Strarting fetching server binary"); let version = version.downcast::().unwrap(); let server_path = container_dir.join(Self::SERVER_PATH); @@ -71,9 +70,8 @@ impl LspAdapter for IntelephenseLspAdapter { .npm_install_packages(&container_dir, [("intelephense", version.0.as_str())]) .await?; } - dbg!("Fetched server binary"); Ok(LanguageServerBinary { - path: dbg!(self.node.binary_path().await)?, + path: self.node.binary_path().await?, arguments: intelephense_server_binary_arguments(&server_path), }) } @@ -83,7 +81,6 @@ impl LspAdapter for IntelephenseLspAdapter { container_dir: PathBuf, _: &dyn LspAdapterDelegate, ) -> Option { - dbg!("cached_server_binary"); get_cached_server_binary(container_dir, &self.node).await } @@ -91,7 +88,6 @@ impl LspAdapter for IntelephenseLspAdapter { &self, container_dir: PathBuf, ) -> Option { - dbg!("installation_test_binary"); get_cached_server_binary(container_dir, &self.node).await } @@ -100,14 +96,15 @@ impl LspAdapter for IntelephenseLspAdapter { _item: &lsp::CompletionItem, _language: &Arc, ) -> Option { - dbg!(_item.kind); None } async fn initialization_options(&self) -> Option { - dbg!("init_options"); None } + async fn language_ids(&self) -> HashMap { + HashMap::from_iter([("PHP".into(), "php".into())]) + } } async fn get_cached_server_binary( From 6c7a6d43fce52334b9309a70c02a98f911956bd4 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:38:35 +0200 Subject: [PATCH 07/13] Cargo fix --- crates/zed/src/languages/php.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index ee6493b576..84115b4528 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -1,19 +1,18 @@ use anyhow::{anyhow, Result}; -use async_compression::futures::bufread::GzipDecoder; -use async_tar::Archive; + + use async_trait::async_trait; use collections::HashMap; -use futures::{future::BoxFuture, FutureExt}; -use gpui::AppContext; + + use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; -use lsp::{CodeActionKind, LanguageServerBinary}; +use lsp::{LanguageServerBinary}; use node_runtime::NodeRuntime; -use serde_json::{json, Value}; -use smol::{fs, io::BufReader, stream::StreamExt}; + +use smol::{fs, stream::StreamExt}; use std::{ any::Any, ffi::OsString, - future, path::{Path, PathBuf}, sync::Arc, }; From 5b6582a7c28b9afd98172a9cb25a82653e90eb2c Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:51:00 +0200 Subject: [PATCH 08/13] rustfmt --- crates/zed/src/languages/php.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index 84115b4528..75eef29e50 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -1,12 +1,10 @@ use anyhow::{anyhow, Result}; - use async_trait::async_trait; use collections::HashMap; - use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; -use lsp::{LanguageServerBinary}; +use lsp::LanguageServerBinary; use node_runtime::NodeRuntime; use smol::{fs, stream::StreamExt}; From ee9123a7da70eed702da7496276ba785268f03af Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:56:25 +0200 Subject: [PATCH 09/13] Remove test --- crates/zed/src/languages/php.rs | 61 --------------------------------- 1 file changed, 61 deletions(-) diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index 75eef29e50..2607dc410b 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -134,64 +134,3 @@ async fn get_cached_server_binary( .await .log_err() } - -#[cfg(test)] -mod tests { - use gpui::TestAppContext; - use unindent::Unindent; - - #[gpui::test] - async fn test_outline(cx: &mut TestAppContext) { - let language = crate::languages::language("php", tree_sitter_php::language(), None).await; - - /*let text = r#" - function a() { - // local variables are omitted - let a1 = 1; - // all functions are included - async function a2() {} - } - // top-level variables are included - let b: C - function getB() {} - // exported variables are included - export const d = e; - "# - .unindent();*/ - let text = r#" - function a() { - // local variables are omitted - $a1 = 1; - // all functions are included - function a2() {} - } - class Foo {} - "# - .unindent(); - let buffer = - cx.add_model(|cx| language::Buffer::new(0, text, cx).with_language(language, cx)); - let outline = buffer.read_with(cx, |buffer, _| buffer.snapshot().outline(None).unwrap()); - panic!( - "{:?}", - outline - .items - .iter() - .map(|item| (item.text.as_str(), item.depth)) - .collect::>() - ); - assert_eq!( - outline - .items - .iter() - .map(|item| (item.text.as_str(), item.depth)) - .collect::>(), - &[ - ("function a()", 0), - ("async function a2()", 1), - ("let b", 0), - ("function getB()", 0), - ("const d", 0), - ] - ); - } -} From 8642a1d074c404ea00cd52a3cfde00a5b43d6f9f Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:03:57 +0200 Subject: [PATCH 10/13] Remove dbg! calls --- crates/language/src/language.rs | 5 ----- crates/project/src/project.rs | 1 - 2 files changed, 6 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index dec01daea5..08a377d280 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -285,8 +285,6 @@ pub trait LspAdapter: 'static + Send + Sync { kind: lsp::SymbolKind, _: &Arc, ) -> Option { - dbg!(name); - dbg!(kind); None } @@ -829,7 +827,6 @@ impl LanguageRegistry { .spawn(async move { let id = language.id; let queries = (language.get_queries)(&language.path); - dbg!(&language.path); let language = Language::new(language.config, Some(language.grammar)) .with_lsp_adapters(language.lsp_adapters) @@ -843,7 +840,6 @@ impl LanguageRegistry { state.add(language.clone()); state.mark_language_loaded(id); if let Some(mut txs) = state.loading_languages.remove(&id) { - dbg!(&name); for tx in txs.drain(..) { let _ = tx.send(Ok(language.clone())); } @@ -851,7 +847,6 @@ impl LanguageRegistry { } Err(err) => { log::error!("failed to load language {name} - {err}"); - dbg!(&name); let mut state = this.state.write(); state.mark_language_loaded(id); if let Some(mut txs) = state.loading_languages.remove(&id) { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 8b46f0fd7f..b931560d25 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2695,7 +2695,6 @@ impl Project { key: (WorktreeId, LanguageServerName), cx: &mut AsyncAppContext, ) -> Result>> { - dbg!(language.name()); let setup = Self::setup_pending_language_server( this, initialization_options, From dd6b674e7ee3cc11346d1756348f8051f6e09d3a Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:08:41 +0200 Subject: [PATCH 11/13] Remove dbg calls --- crates/language/src/language.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 08a377d280..f8e25fbce1 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -262,27 +262,22 @@ pub trait LspAdapter: 'static + Send + Sync { container_dir: PathBuf, ) -> Option; - async fn process_diagnostics(&self, d: &mut lsp::PublishDiagnosticsParams) { - dbg!(d); - } + async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} - async fn process_completion(&self, d: &mut lsp::CompletionItem) { - dbg!(d); - } + async fn process_completion(&self, _: &mut lsp::CompletionItem) {} async fn label_for_completion( &self, - item: &lsp::CompletionItem, + _: &lsp::CompletionItem, _: &Arc, ) -> Option { - dbg!(item); None } async fn label_for_symbol( &self, - name: &str, - kind: lsp::SymbolKind, + _: &str, + _: lsp::SymbolKind, _: &Arc, ) -> Option { None From 7fde3614fec4ff8a7806fe5544e3e40ae3a8d114 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:19:35 +0200 Subject: [PATCH 12/13] Remove leftover comment --- crates/zed/src/languages/php.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index 2607dc410b..6a01d00300 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -45,9 +45,6 @@ impl LspAdapter for IntelephenseLspAdapter { &self, _delegate: &dyn LspAdapterDelegate, ) -> Result> { - // At the time of writing the latest vscode-eslint release was released in 2020 and requires - // special custom LSP protocol extensions be handled to fully initialize. Download the latest - // prerelease instead to sidestep this issue Ok(Box::new(IntelephenseVersion( self.node.npm_package_latest_version("intelephense").await?, )) as Box<_>) From fa529d9590dffffc753d46829ec2ccf2c6db8865 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:21:00 +0200 Subject: [PATCH 13/13] Remove redundant debug impl --- crates/language/src/language.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index f8e25fbce1..50a0b4b161 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -321,7 +321,7 @@ pub struct CodeLabel { pub filter_range: Range, } -#[derive(Clone, Deserialize, Debug)] +#[derive(Clone, Deserialize)] pub struct LanguageConfig { pub name: Arc, pub path_suffixes: Vec,