From 20fed599b2f6065561d386e13fd5d35630e0c7ef Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 11 Mar 2022 17:36:27 -0800 Subject: [PATCH] Start work on relaying settings to language servers --- crates/language/src/language.rs | 5 +--- crates/lsp/src/lsp.rs | 7 +++++ crates/project/src/project.rs | 48 ++++++++++++++++++++++++++++++++ crates/workspace/src/settings.rs | 5 ++-- crates/zed/src/language.rs | 11 -------- crates/zed/src/zed.rs | 14 ++++++++++ 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index b94c15a8790815d20b45a5148a59017a0a6abb2a..8c1a34c01080a35b839f9c952c126b40dab0249e 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -95,8 +95,6 @@ pub trait LspAdapter: 'static + Send + Sync { fn initialization_options(&self) -> Option { None } - - fn register_handlers(&self, _: &mut lsp::LanguageServer) {} } #[derive(Clone, Debug, PartialEq, Eq)] @@ -321,14 +319,13 @@ impl LanguageRegistry { let server_binary_path = server_binary_path.await?; let server_args = adapter.server_args(); - let mut server = lsp::LanguageServer::new( + let server = lsp::LanguageServer::new( &server_binary_path, server_args, &root_path, adapter.initialization_options(), background, )?; - adapter.register_handlers(&mut server); Ok(server) })) } diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 883d78343f61132cfe06de7d333dfbb04251aa8b..a8ae9e4cd7071632fb30fb9086c574c4940f53be 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -265,6 +265,13 @@ impl LanguageServer { root_uri: Some(root_uri), initialization_options: options, capabilities: ClientCapabilities { + workspace: Some(WorkspaceClientCapabilities { + configuration: Some(true), + did_change_configuration: Some(DynamicRegistrationClientCapabilities { + dynamic_registration: Some(true), + }), + ..Default::default() + }), text_document: Some(TextDocumentClientCapabilities { definition: Some(GotoCapability { link_support: Some(true), diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 2f84f702bec9a169af6767f0ed3695f8c6f0d6ae..d8ae7f3de5b4f3d7ee921f75ede215dfb17a8f59 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -23,6 +23,7 @@ use language::{ }; use lsp::{DiagnosticSeverity, DocumentHighlightKind, LanguageServer}; use lsp_command::*; +use parking_lot::Mutex; use postage::watch; use rand::prelude::*; use search::SearchQuery; @@ -52,6 +53,7 @@ pub struct Project { language_servers: HashMap<(WorktreeId, Arc), Arc>, started_language_servers: HashMap<(WorktreeId, Arc), Task>>>, language_server_statuses: BTreeMap, + language_server_settings: Arc>, next_language_server_id: usize, client: Arc, user_store: ModelHandle, @@ -333,6 +335,7 @@ impl Project { language_servers: Default::default(), started_language_servers: Default::default(), language_server_statuses: Default::default(), + language_server_settings: Default::default(), next_language_server_id: 0, nonce: StdRng::from_entropy().gen(), } @@ -403,6 +406,7 @@ impl Project { language_servers_with_diagnostics_running: 0, language_servers: Default::default(), started_language_servers: Default::default(), + language_server_settings: Default::default(), language_server_statuses: response .language_servers .into_iter() @@ -1228,6 +1232,30 @@ impl Project { }) .detach(); + language_server + .on_request::({ + let settings = this + .read_with(&cx, |this, _| this.language_server_settings.clone()); + move |params| { + let settings = settings.lock(); + Ok(params + .items + .into_iter() + .map(|item| { + if let Some(section) = &item.section { + settings + .get(section) + .cloned() + .unwrap_or(serde_json::Value::Null) + } else { + settings.clone() + } + }) + .collect()) + } + }) + .detach(); + language_server .on_notification::(move |params| { let token = match params.token { @@ -1299,6 +1327,13 @@ impl Project { pending_diagnostic_updates: 0, }, ); + language_server + .notify::( + lsp::DidChangeConfigurationParams { + settings: this.language_server_settings.lock().clone(), + }, + ) + .ok(); if let Some(project_id) = this.remote_id() { this.client @@ -1547,6 +1582,19 @@ impl Project { } } + pub fn set_language_server_settings(&mut self, settings: serde_json::Value) { + for server in self.language_servers.values() { + server + .notify::( + lsp::DidChangeConfigurationParams { + settings: settings.clone(), + }, + ) + .ok(); + } + *self.language_server_settings.lock() = settings; + } + pub fn language_server_statuses( &self, ) -> impl DoubleEndedIterator { diff --git a/crates/workspace/src/settings.rs b/crates/workspace/src/settings.rs index 9e11002acd713103a9703e4422feaf5aaadbd493..e97f7f8920f8f126a41485b612820d3b14e57e88 100644 --- a/crates/workspace/src/settings.rs +++ b/crates/workspace/src/settings.rs @@ -93,9 +93,8 @@ impl SettingsFile { } impl Settings { - pub fn file_json_schema() -> String { - let schema = schema_for!(SettingsFileContent); - serde_json::to_string(&schema).unwrap() + pub fn file_json_schema() -> serde_json::Value { + serde_json::to_value(schema_for!(SettingsFileContent)).unwrap() } pub fn from_files( diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index 5782c75c972a724c43435f656b377a5ada272fb7..0d69ebee690a02a7dff73593c538dd978f996835 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -530,17 +530,6 @@ impl LspAdapter for JsonLspAdapter { "provideFormatter": true })) } - - fn register_handlers(&self, lsp: &mut lsp::LanguageServer) { - lsp.on_custom_request::, Option, _>("vscode/content", |schema| { - if schema.get(0).map(String::as_str) == Some("zed://settings") { - Ok(Some(workspace::Settings::file_json_schema())) - } else { - Ok(None) - } - }) - .detach(); - } } pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegistry { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 6734464f79207eed7cb7c27c36f56e2d14a3a123..1e43bf0396c178866f0b1111ec435e13707765d5 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -96,6 +96,20 @@ pub fn build_workspace( }; let mut workspace = Workspace::new(&workspace_params, cx); let project = workspace.project().clone(); + + project.update(cx, |project, _| { + project.set_language_server_settings(serde_json::json!({ + "json": { + "schemas": [ + { + "fileMatch": "**/.zed/settings.json", + "schema": Settings::file_json_schema(), + } + ] + } + })); + }); + workspace.left_sidebar_mut().add_item( "icons/folder-tree-16.svg", ProjectPanel::new(project, cx).into(),