Skip to content

Commit a79f12e

Browse files
mikebronnerclaude
andcommitted
feat: ✨ simplify path handling to use LSP server directory
- Remove all user-provided path configuration complexity - Extension downloads PHARs to same directory as LSP server binary - LSP server automatically finds PHPCS/PHPCBF in its own directory - Eliminates path resolution issues and configuration overhead 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8f64ae8 commit a79f12e

File tree

3 files changed

+35
-116
lines changed

3 files changed

+35
-116
lines changed

extension.wasm

-939 KB
Binary file not shown.

lsp-server/src/main.rs

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,44 @@ use url::Url;
1313

1414
#[derive(Debug, Deserialize, Serialize)]
1515
struct InitializationOptions {
16-
#[serde(rename = "phpcsPath")]
17-
phpcs_path: Option<String>,
16+
// No longer using phpcsPath - LSP server finds PHPCS automatically
1817
}
1918

2019
#[derive(Debug)]
2120
struct PhpcsLanguageServer {
2221
client: Client,
23-
phpcs_path: std::sync::Arc<std::sync::RwLock<Option<String>>>,
2422
open_docs: std::sync::Arc<std::sync::RwLock<HashMap<Url, String>>>,
2523
}
2624

2725
impl PhpcsLanguageServer {
2826
fn new(client: Client) -> Self {
2927
Self {
3028
client,
31-
phpcs_path: std::sync::Arc::new(std::sync::RwLock::new(None)),
3229
open_docs: std::sync::Arc::new(std::sync::RwLock::new(HashMap::new())),
3330
}
3431
}
3532

3633
async fn run_phpcs(&self, uri: &Url, file_path: &str, content: Option<&str>) -> Result<Vec<Diagnostic>> {
37-
let phpcs_path = {
38-
let path_guard = self.phpcs_path.read().unwrap();
39-
path_guard.clone().unwrap_or_else(|| {
40-
eprintln!("PHPCS LSP: No phpcsPath provided via initialization options");
41-
42-
// Try to find bundled PHPCS PHAR relative to LSP server
43-
if let Ok(current_exe) = std::env::current_exe() {
44-
if let Some(exe_dir) = current_exe.parent() {
45-
// Look for PHPCS PHAR in same directory as LSP server
46-
let bundled_phpcs = exe_dir.join("phpcs.phar");
47-
eprintln!("PHPCS LSP: Checking for PHPCS at: {}", bundled_phpcs.display());
48-
49-
if bundled_phpcs.exists() {
50-
eprintln!("PHPCS LSP: Found bundled PHPCS PHAR in LSP directory");
51-
return bundled_phpcs.to_string_lossy().to_string();
52-
}
53-
}
34+
// Always look for PHPCS in the same directory as the LSP server
35+
let phpcs_path = if let Ok(current_exe) = std::env::current_exe() {
36+
if let Some(exe_dir) = current_exe.parent() {
37+
let bundled_phpcs = exe_dir.join("phpcs.phar");
38+
eprintln!("PHPCS LSP: Looking for PHPCS at: {}", bundled_phpcs.display());
39+
40+
if bundled_phpcs.exists() {
41+
eprintln!("PHPCS LSP: Found PHPCS PHAR in LSP directory");
42+
bundled_phpcs.to_string_lossy().to_string()
43+
} else {
44+
eprintln!("PHPCS LSP: No PHPCS PHAR found, trying system phpcs");
45+
"phpcs".to_string()
5446
}
55-
56-
eprintln!("PHPCS LSP: No bundled PHPCS found, trying system phpcs");
47+
} else {
48+
eprintln!("PHPCS LSP: Could not get LSP server directory");
5749
"phpcs".to_string()
58-
})
50+
}
51+
} else {
52+
eprintln!("PHPCS LSP: Could not get current executable path");
53+
"phpcs".to_string()
5954
};
6055

6156
eprintln!("PHPCS LSP: Using PHPCS path: {}", phpcs_path);
@@ -372,19 +367,9 @@ impl LanguageServer for PhpcsLanguageServer {
372367

373368
if let Some(options) = params.initialization_options {
374369
eprintln!("PHPCS LSP: Received initialization options: {:?}", options);
375-
if let Ok(init_opts) = serde_json::from_value::<InitializationOptions>(options) {
376-
eprintln!("PHPCS LSP: Parsed initialization options successfully");
377-
if let Some(ref phpcs_path) = init_opts.phpcs_path {
378-
eprintln!("PHPCS LSP: Setting phpcsPath to: {}", phpcs_path);
379-
*self.phpcs_path.write().unwrap() = Some(phpcs_path.clone());
380-
} else {
381-
eprintln!("PHPCS LSP: No phpcsPath in initialization options");
382-
}
383-
} else {
384-
eprintln!("PHPCS LSP: Failed to parse initialization options");
385-
}
370+
// Initialization options can be used for future configuration if needed
386371
} else {
387-
eprintln!("PHPCS LSP: No initialization options received");
372+
eprintln!("PHPCS LSP: No initialization options provided");
388373
}
389374

390375
Ok(InitializeResult {

src/lib.rs

Lines changed: 14 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -168,91 +168,25 @@ impl zed::Extension for PhpcsLspExtension {
168168
.ok()
169169
.and_then(|lsp_settings| lsp_settings.settings.clone());
170170

171-
// Check for user-configured PHPCS path from settings.json
172-
let mut found_phpcs_path = false;
173-
if let Some(settings) = user_settings.as_ref() {
174-
if let Some(phpcs_path) = settings.get("phpcsPath").and_then(|v| v.as_str()) {
175-
if !phpcs_path.trim().is_empty() {
176-
eprintln!("PHPCS LSP: Using custom PHPCS path from settings: {}", phpcs_path);
177-
options.insert("phpcsPath".to_string(), zed::serde_json::Value::String(phpcs_path.to_string()));
178-
found_phpcs_path = true;
179-
}
180-
}
181-
}
182-
183-
// Fall back to environment variable if no settings configured
184-
if !found_phpcs_path {
185-
if let Ok(custom_phpcs_path) = env::var("PHPCS_PATH") {
186-
if !custom_phpcs_path.trim().is_empty() {
187-
eprintln!("PHPCS LSP: Using custom PHPCS path from PHPCS_PATH env: {}", custom_phpcs_path);
188-
options.insert("phpcsPath".to_string(), zed::serde_json::Value::String(custom_phpcs_path));
189-
found_phpcs_path = true;
190-
}
191-
}
192-
}
193-
194-
// Fall back to auto-discovery if no custom path specified
195-
if !found_phpcs_path {
196-
if let Some(phpcs_path) = Self::find_phpcs_binary(worktree) {
197-
eprintln!("PHPCS LSP: Found PHPCS: {}", phpcs_path);
198-
options.insert("phpcsPath".to_string(), zed::serde_json::Value::String(phpcs_path));
199-
} else {
200-
// Try to download PHPCS PHAR
201-
eprintln!("PHPCS LSP: No local PHPCS found, attempting to download...");
202-
match Self::download_phar_if_needed("phpcs.phar") {
203-
Ok(_phar_path) => {
204-
eprintln!("PHPCS LSP: Downloaded PHPCS successfully");
205-
// Since the LSP server runs from the version directory, just provide the filename
206-
options.insert("phpcsPath".to_string(), zed::serde_json::Value::String("phpcs.phar".to_string()));
207-
}
208-
Err(e) => {
209-
eprintln!("PHPCS LSP: Failed to download PHPCS: {}", e);
210-
}
211-
}
171+
// Download PHPCS PHAR to LSP server directory - LSP server will find it automatically
172+
eprintln!("PHPCS LSP: Ensuring PHPCS PHAR is available in LSP server directory...");
173+
match Self::download_phar_if_needed("phpcs.phar") {
174+
Ok(_phar_path) => {
175+
eprintln!("PHPCS LSP: PHPCS PHAR available for LSP server");
212176
}
213-
}
214-
215-
// Check for user-configured PHPCBF path from settings.json
216-
let mut found_phpcbf_path = false;
217-
if let Some(settings) = user_settings.as_ref() {
218-
if let Some(phpcbf_path) = settings.get("phpcbfPath").and_then(|v| v.as_str()) {
219-
if !phpcbf_path.trim().is_empty() {
220-
eprintln!("PHPCS LSP: Using custom PHPCBF path from settings: {}", phpcbf_path);
221-
options.insert("phpcbfPath".to_string(), zed::serde_json::Value::String(phpcbf_path.to_string()));
222-
found_phpcbf_path = true;
223-
}
177+
Err(e) => {
178+
eprintln!("PHPCS LSP: Failed to download PHPCS PHAR: {}", e);
224179
}
225180
}
226181

227-
// Fall back to environment variable if no settings configured
228-
if !found_phpcbf_path {
229-
if let Ok(custom_phpcbf_path) = env::var("PHPCBF_PATH") {
230-
if !custom_phpcbf_path.trim().is_empty() {
231-
eprintln!("PHPCS LSP: Using custom PHPCBF path from PHPCBF_PATH env: {}", custom_phpcbf_path);
232-
options.insert("phpcbfPath".to_string(), zed::serde_json::Value::String(custom_phpcbf_path));
233-
found_phpcbf_path = true;
234-
}
182+
// Download PHPCBF PHAR to LSP server directory - LSP server will find it automatically
183+
eprintln!("PHPCS LSP: Ensuring PHPCBF PHAR is available in LSP server directory...");
184+
match Self::download_phar_if_needed("phpcbf.phar") {
185+
Ok(_phar_path) => {
186+
eprintln!("PHPCS LSP: PHPCBF PHAR available for LSP server");
235187
}
236-
}
237-
238-
// Fall back to auto-discovery if no custom path specified
239-
if !found_phpcbf_path {
240-
if let Some(phpcbf_path) = Self::find_phpcbf_binary(worktree) {
241-
eprintln!("PHPCS LSP: Found PHPCBF: {}", phpcbf_path);
242-
options.insert("phpcbfPath".to_string(), zed::serde_json::Value::String(phpcbf_path));
243-
} else {
244-
// Try to download PHPCBF PHAR
245-
eprintln!("PHPCS LSP: No local PHPCBF found, attempting to download...");
246-
match Self::download_phar_if_needed("phpcbf.phar") {
247-
Ok(_phar_path) => {
248-
eprintln!("PHPCS LSP: Downloaded PHPCBF successfully");
249-
// Since the LSP server runs from the version directory, just provide the filename
250-
options.insert("phpcbfPath".to_string(), zed::serde_json::Value::String("phpcbf.phar".to_string()));
251-
}
252-
Err(e) => {
253-
eprintln!("PHPCS LSP: Failed to download PHPCBF: {}", e);
254-
}
255-
}
188+
Err(e) => {
189+
eprintln!("PHPCS LSP: Failed to download PHPCBF PHAR: {}", e);
256190
}
257191
}
258192

0 commit comments

Comments
 (0)