fix: implement LSP initialization and configuration handlers#83
fix: implement LSP initialization and configuration handlers#83pmig wants to merge 1 commit intonathansbradshaw:mainfrom
Conversation
Add language_server_initialization_options and language_server_workspace_configuration trait methods to properly respond to LSP initialize and workspace/configuration requests. Without these, the Angular Language Server's workspace/configuration requests fail with deserialization errors, and user-configured LSP settings are not forwarded to the server. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds missing Zed extension hooks so the Angular Language Server can receive user-provided LSP initialization options and successfully retrieve per-workspace configuration via workspace/configuration, addressing failures reported in #69 and #77.
Changes:
- Implement
language_server_initialization_optionsto forward userlsp.angular.initialization_optionsto the server. - Implement
language_server_workspace_configurationto return userlsp.angular.settingsin response to serverworkspace/configurationrequests.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let settings = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | ||
| .ok() | ||
| .and_then(|settings| settings.settings) | ||
| .unwrap_or_else(|| serde_json::json!({})); | ||
| Ok(Some(settings)) |
There was a problem hiding this comment.
LspSettings::for_worktree(...).ok() discards any error and silently falls back to {}. If settings parsing fails, returning {} may hide the underlying issue; consider propagating the error or logging it before falling back.
| _language_server_id: &zed::LanguageServerId, | ||
| worktree: &zed::Worktree, | ||
| ) -> Result<Option<serde_json::Value>> { | ||
| let initialization_options = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | ||
| .ok() | ||
| .and_then(|settings| settings.initialization_options) | ||
| .unwrap_or_else(|| serde_json::json!({})); | ||
| Ok(Some(initialization_options)) |
There was a problem hiding this comment.
This ignores the language_server_id argument and hard-codes Self::LANGUAGE_SERVER_ID when reading per-worktree LSP settings. Using the provided language_server_id keeps this method correct if the server id ever differs (and is consistent with read_user_settings).
| let initialization_options = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | ||
| .ok() | ||
| .and_then(|settings| settings.initialization_options) | ||
| .unwrap_or_else(|| serde_json::json!({})); | ||
| Ok(Some(initialization_options)) |
There was a problem hiding this comment.
LspSettings::for_worktree(...).ok() discards any error (e.g., malformed user settings) and silently falls back to {}. Consider propagating the error (using ?) or at least emitting a log/warning so configuration problems don’t become hard-to-diagnose runtime behavior.
| _language_server_id: &zed::LanguageServerId, | ||
| worktree: &zed::Worktree, | ||
| ) -> Result<Option<serde_json::Value>> { | ||
| let initialization_options = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | ||
| .ok() | ||
| .and_then(|settings| settings.initialization_options) | ||
| .unwrap_or_else(|| serde_json::json!({})); | ||
| Ok(Some(initialization_options)) | ||
| } | ||
|
|
||
| fn language_server_workspace_configuration( | ||
| &mut self, | ||
| _language_server_id: &zed::LanguageServerId, | ||
| worktree: &zed::Worktree, | ||
| ) -> Result<Option<serde_json::Value>> { | ||
| let settings = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | ||
| .ok() | ||
| .and_then(|settings| settings.settings) | ||
| .unwrap_or_else(|| serde_json::json!({})); |
There was a problem hiding this comment.
This ignores the language_server_id argument and hard-codes Self::LANGUAGE_SERVER_ID when reading per-worktree LSP settings. Using the provided language_server_id avoids accidental mismatches and keeps the implementation consistent with other trait methods that accept a server id.
| _language_server_id: &zed::LanguageServerId, | |
| worktree: &zed::Worktree, | |
| ) -> Result<Option<serde_json::Value>> { | |
| let initialization_options = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | |
| .ok() | |
| .and_then(|settings| settings.initialization_options) | |
| .unwrap_or_else(|| serde_json::json!({})); | |
| Ok(Some(initialization_options)) | |
| } | |
| fn language_server_workspace_configuration( | |
| &mut self, | |
| _language_server_id: &zed::LanguageServerId, | |
| worktree: &zed::Worktree, | |
| ) -> Result<Option<serde_json::Value>> { | |
| let settings = LspSettings::for_worktree(Self::LANGUAGE_SERVER_ID, worktree) | |
| .ok() | |
| .and_then(|settings| settings.settings) | |
| .unwrap_or_else(|| serde_json::json!({})); | |
| language_server_id: &zed::LanguageServerId, | |
| worktree: &zed::Worktree, | |
| ) -> Result<Option<serde_json::Value>> { | |
| let initialization_options = | |
| LspSettings::for_worktree(language_server_id, worktree) | |
| .ok() | |
| .and_then(|settings| settings.initialization_options) | |
| .unwrap_or_else(|| serde_json::json!({})); | |
| Ok(Some(initialization_options)) | |
| } | |
| fn language_server_workspace_configuration( | |
| &mut self, | |
| language_server_id: &zed::LanguageServerId, | |
| worktree: &zed::Worktree, | |
| ) -> Result<Option<serde_json::Value>> { | |
| let settings = | |
| LspSettings::for_worktree(language_server_id, worktree) | |
| .ok() | |
| .and_then(|settings| settings.settings) | |
| .unwrap_or_else(|| serde_json::json!({})); |
|
Do you have example Zed settings so this can be tested/validated? |
Bump @pmig |
|
closing PR because submitter is not taking proper ownership of this pr. there are also copilot requests left unaddressed. submitter says he tested it himself, but that's not enough assurance to confidently move forward |
This actually a series a fixes to make that extension work again. You can try out the extension locally over at https://github.com/pmig/zed-angular. Although most of the code was written by claude, I (@pmig) manually reviewed and tested it.
Summary
language_server_initialization_optionstrait method to forward user-configured LSP init options to the Angular Language Serverlanguage_server_workspace_configurationtrait method to respond toworkspace/configurationrequests from the serverworkspace/configurationrequests fail withError("relative URL without a base"), and user-configured LSP settings (via Zed'slspsettings) are not forwarded to the serverFollows the same pattern used by the Vue extension.
Relates to #69, #77