Customize language settings JSON schema in language crate

This commit is contained in:
Max Brunsfeld 2023-05-17 09:26:32 -07:00
parent 6403bb86e1
commit d2ba18eae9
4 changed files with 77 additions and 48 deletions

View file

@ -1,7 +1,10 @@
use anyhow::Result; use anyhow::Result;
use collections::HashMap; use collections::HashMap;
use gpui::AppContext; use gpui::AppContext;
use schemars::JsonSchema; use schemars::{
schema::{InstanceType, ObjectValidation, Schema, SchemaObject},
JsonSchema,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{num::NonZeroU32, path::Path, sync::Arc}; use std::{num::NonZeroU32, path::Path, sync::Arc};
@ -247,6 +250,61 @@ impl settings::Setting for AllLanguageSettings {
languages, languages,
}) })
} }
fn json_schema(
generator: &mut schemars::gen::SchemaGenerator,
params: &settings::SettingsJsonSchemaParams,
) -> schemars::schema::RootSchema {
let mut root_schema = generator.root_schema_for::<Self::FileContent>();
// Create a schema for a 'languages overrides' object, associating editor
// settings with specific langauges.
assert!(root_schema
.definitions
.contains_key("LanguageSettingsContent"));
let languages_object_schema = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
object: Some(Box::new(ObjectValidation {
properties: params
.language_names
.iter()
.map(|name| {
(
name.clone(),
Schema::new_ref("#/definitions/LanguageSettingsContent".into()),
)
})
.collect(),
..Default::default()
})),
..Default::default()
};
root_schema
.definitions
.extend([("Languages".into(), languages_object_schema.into())]);
root_schema
.schema
.object
.as_mut()
.unwrap()
.properties
.extend([
(
"languages".to_owned(),
Schema::new_ref("#/definitions/Languages".into()),
),
// For backward compatibility
(
"language_overrides".to_owned(),
Schema::new_ref("#/definitions/Languages".into()),
),
]);
root_schema
}
} }
fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent) { fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent) {

View file

@ -10,7 +10,7 @@ use gpui::{
}; };
use schemars::{ use schemars::{
gen::SchemaGenerator, gen::SchemaGenerator,
schema::{InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec}, schema::{InstanceType, Schema, SchemaObject},
JsonSchema, JsonSchema,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -80,7 +80,7 @@ impl Setting for Settings {
// Create a schema for a theme name. // Create a schema for a theme name.
let theme_name_schema = SchemaObject { let theme_name_schema = SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), instance_type: Some(InstanceType::String.into()),
enum_values: Some( enum_values: Some(
params params
.theme_names .theme_names
@ -92,51 +92,20 @@ impl Setting for Settings {
..Default::default() ..Default::default()
}; };
// Create a schema for a 'languages overrides' object, associating editor root_schema
// settings with specific langauges. .definitions
assert!(root_schema.definitions.contains_key("EditorSettings")); .extend([("ThemeName".into(), theme_name_schema.into())]);
let languages_object_schema = SchemaObject { root_schema
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))), .schema
object: Some(Box::new(ObjectValidation { .object
properties: params .as_mut()
.language_names .unwrap()
.iter() .properties
.map(|name| { .extend([(
(
name.clone(),
Schema::new_ref("#/definitions/EditorSettings".into()),
)
})
.collect(),
..Default::default()
})),
..Default::default()
};
// Add these new schemas as definitions, and modify properties of the root
// schema to reference them.
root_schema.definitions.extend([
("ThemeName".into(), theme_name_schema.into()),
("Languages".into(), languages_object_schema.into()),
]);
let root_schema_object = &mut root_schema.schema.object.as_mut().unwrap();
root_schema_object.properties.extend([
(
"theme".to_owned(), "theme".to_owned(),
Schema::new_ref("#/definitions/ThemeName".into()), Schema::new_ref("#/definitions/ThemeName".into()),
), )]);
(
"languages".to_owned(),
Schema::new_ref("#/definitions/Languages".into()),
),
// For backward compatibility
(
"language_overrides".to_owned(),
Schema::new_ref("#/definitions/Languages".into()),
),
]);
root_schema root_schema
} }

View file

@ -308,7 +308,8 @@ impl SettingsStore {
default_settings_content: &str, default_settings_content: &str,
cx: &AppContext, cx: &AppContext,
) -> Result<()> { ) -> Result<()> {
self.default_deserialized_settings = Some(serde_json::from_str(default_settings_content)?); self.default_deserialized_settings =
Some(parse_json_with_comments(default_settings_content)?);
self.recompute_values(None, cx)?; self.recompute_values(None, cx)?;
Ok(()) Ok(())
} }
@ -319,7 +320,7 @@ impl SettingsStore {
user_settings_content: &str, user_settings_content: &str,
cx: &AppContext, cx: &AppContext,
) -> Result<()> { ) -> Result<()> {
self.user_deserialized_settings = Some(serde_json::from_str(user_settings_content)?); self.user_deserialized_settings = Some(parse_json_with_comments(user_settings_content)?);
self.recompute_values(None, cx)?; self.recompute_values(None, cx)?;
Ok(()) Ok(())
} }
@ -333,7 +334,7 @@ impl SettingsStore {
) -> Result<()> { ) -> Result<()> {
if let Some(content) = settings_content { if let Some(content) = settings_content {
self.local_deserialized_settings self.local_deserialized_settings
.insert(path.clone(), serde_json::from_str(content)?); .insert(path.clone(), parse_json_with_comments(content)?);
} else { } else {
self.local_deserialized_settings.remove(&path); self.local_deserialized_settings.remove(&path);
} }

View file

@ -160,6 +160,7 @@ fn main() {
project::Project::init(&client, cx); project::Project::init(&client, cx);
client::init(&client, cx); client::init(&client, cx);
command_palette::init(cx); command_palette::init(cx);
language::init(cx);
editor::init(cx); editor::init(cx);
go_to_line::init(cx); go_to_line::init(cx);
file_finder::init(cx); file_finder::init(cx);