diff --git a/Cargo.lock b/Cargo.lock index 5f066635bc..d738fe86cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1574,6 +1574,12 @@ dependencies = [ "wio", ] +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + [[package]] name = "easy-parallel" version = "3.1.0" @@ -4139,6 +4145,30 @@ dependencies = [ "winapi", ] +[[package]] +name = "schemars" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "scoped-tls" version = "1.0.0" @@ -4260,6 +4290,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.64" @@ -5851,6 +5892,7 @@ dependencies = [ "parking_lot", "postage", "project", + "schemars", "serde", "serde_json", "smallvec", diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 5af18241b6..b94c15a879 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -95,6 +95,8 @@ pub trait LspAdapter: 'static + Send + Sync { fn initialization_options(&self) -> Option { None } + + fn register_handlers(&self, _: &mut lsp::LanguageServer) {} } #[derive(Clone, Debug, PartialEq, Eq)] @@ -319,13 +321,15 @@ impl LanguageRegistry { let server_binary_path = server_binary_path.await?; let server_args = adapter.server_args(); - lsp::LanguageServer::new( + let mut 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/workspace/Cargo.toml b/crates/workspace/Cargo.toml index c8cf21c571..7ef0bd8543 100644 --- a/crates/workspace/Cargo.toml +++ b/crates/workspace/Cargo.toml @@ -24,6 +24,7 @@ futures = "0.3" log = "0.4" parking_lot = "0.11.1" postage = { version = "0.4.1", features = ["futures-traits"] } +schemars = "0.8" serde = { version = "1", features = ["derive", "rc"] } serde_json = { version = "1", features = ["preserve_order"] } smallvec = { version = "1.6", features = ["union"] } diff --git a/crates/workspace/src/settings.rs b/crates/workspace/src/settings.rs index 62a6d4af8c..fbda0e2b71 100644 --- a/crates/workspace/src/settings.rs +++ b/crates/workspace/src/settings.rs @@ -8,6 +8,7 @@ use language::Language; use parking_lot::Mutex; use postage::{prelude::Stream, watch}; use project::Fs; +use schemars::{schema_for, JsonSchema}; use serde::Deserialize; use std::{collections::HashMap, path::Path, sync::Arc, time::Duration}; use theme::{Theme, ThemeRegistry}; @@ -24,14 +25,14 @@ pub struct Settings { pub theme: Arc, } -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, JsonSchema)] pub struct LanguageOverride { pub tab_size: Option, pub soft_wrap: Option, pub preferred_line_length: Option, } -#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum SoftWrap { None, @@ -42,7 +43,7 @@ pub enum SoftWrap { #[derive(Clone)] pub struct SettingsFile(watch::Receiver); -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, JsonSchema)] struct SettingsFileContent { #[serde(default)] buffer_font_family: Option, @@ -94,6 +95,11 @@ impl SettingsFile { } impl Settings { + pub fn file_json_schema() -> String { + let schema = schema_for!(SettingsFileContent); + serde_json::to_string(&schema).unwrap() + } + pub fn from_files( defaults: Self, sources: Vec, diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index 0d69ebee69..5782c75c97 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -530,6 +530,17 @@ 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 {