@@ -2,10 +2,14 @@ use anyhow::Result;
use gpui::font_cache::{FamilyId, FontCache};
use schemars::{
gen::{SchemaGenerator, SchemaSettings},
+ schema::{
+ InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec, SubschemaValidation,
+ },
JsonSchema,
};
use serde::Deserialize;
-use std::{collections::HashMap, fmt::Display, sync::Arc};
+use serde_json::Value;
+use std::{collections::HashMap, fmt::Display, os::unix::fs::chroot, sync::Arc};
use theme::{Theme, ThemeRegistry};
use util::ResultExt as _;
@@ -36,53 +40,6 @@ pub enum SoftWrap {
PreferredLineLength,
}
-#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
-pub enum ThemeNames {
- Dark,
- Light,
-}
-
-impl Display for ThemeNames {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self {
- ThemeNames::Dark => write!(f, "Dark"),
- ThemeNames::Light => write!(f, "Light"),
- }
- }
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct LanguageOverrides {
- C: Option<LanguageOverride>,
- JSON: Option<LanguageOverride>,
- Markdown: Option<LanguageOverride>,
- PlainText: Option<LanguageOverride>,
- Rust: Option<LanguageOverride>,
- TSX: Option<LanguageOverride>,
- TypeScript: Option<LanguageOverride>,
-}
-
-impl IntoIterator for LanguageOverrides {
- type Item = (String, LanguageOverride);
- type IntoIter = std::vec::IntoIter<Self::Item>;
-
- fn into_iter(self) -> Self::IntoIter {
- vec![
- ("C", self.C),
- ("JSON", self.JSON),
- ("Markdown", self.Markdown),
- ("PlainText", self.PlainText),
- ("Rust", self.Rust),
- ("TSX", self.TSX),
- ("TypeScript", self.TypeScript),
- ]
- .into_iter()
- .filter_map(|(name, language_override)| language_override.map(|lo| (name.to_owned(), lo)))
- .collect::<Vec<_>>()
- .into_iter()
- }
-}
-
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
pub struct SettingsFileContent {
#[serde(default)]
@@ -94,9 +51,9 @@ pub struct SettingsFileContent {
#[serde(flatten)]
pub editor: LanguageOverride,
#[serde(default)]
- pub language_overrides: LanguageOverrides,
+ pub language_overrides: HashMap<Arc<str>, LanguageOverride>,
#[serde(default)]
- pub theme: Option<ThemeNames>,
+ pub theme: Option<String>,
}
impl Settings {
@@ -117,13 +74,88 @@ impl Settings {
})
}
- pub fn file_json_schema() -> serde_json::Value {
+ pub fn file_json_schema(
+ theme_names: Vec<String>,
+ language_names: Vec<String>,
+ ) -> serde_json::Value {
let settings = SchemaSettings::draft07().with(|settings| {
- settings.option_nullable = true;
settings.option_add_null_type = false;
});
let generator = SchemaGenerator::new(settings);
- serde_json::to_value(generator.into_root_schema_for::<SettingsFileContent>()).unwrap()
+ let mut root_schema = generator.into_root_schema_for::<SettingsFileContent>();
+
+ // Construct theme names reference type
+ let theme_names = theme_names
+ .into_iter()
+ .map(|name| Value::String(name))
+ .collect();
+ let theme_names_schema = Schema::Object(SchemaObject {
+ instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
+ enum_values: Some(theme_names),
+ ..Default::default()
+ });
+ root_schema
+ .definitions
+ .insert("ThemeName".to_owned(), theme_names_schema);
+
+ // Construct language overrides reference type
+ let language_override_schema_reference = Schema::Object(SchemaObject {
+ reference: Some("#/definitions/LanguageOverride".to_owned()),
+ ..Default::default()
+ });
+ let language_overrides_properties = language_names
+ .into_iter()
+ .map(|name| {
+ (
+ name,
+ Schema::Object(SchemaObject {
+ subschemas: Some(Box::new(SubschemaValidation {
+ all_of: Some(vec![language_override_schema_reference.clone()]),
+ ..Default::default()
+ })),
+ ..Default::default()
+ }),
+ )
+ })
+ .collect();
+ let language_overrides_schema = Schema::Object(SchemaObject {
+ instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
+ object: Some(Box::new(ObjectValidation {
+ properties: language_overrides_properties,
+ ..Default::default()
+ })),
+ ..Default::default()
+ });
+ root_schema
+ .definitions
+ .insert("LanguageOverrides".to_owned(), language_overrides_schema);
+
+ // Modify theme property to use new theme reference type
+ let settings_file_schema = root_schema.schema.object.as_mut().unwrap();
+ let language_overrides_schema_reference = Schema::Object(SchemaObject {
+ reference: Some("#/definitions/ThemeName".to_owned()),
+ ..Default::default()
+ });
+ settings_file_schema.properties.insert(
+ "theme".to_owned(),
+ Schema::Object(SchemaObject {
+ subschemas: Some(Box::new(SubschemaValidation {
+ all_of: Some(vec![language_overrides_schema_reference]),
+ ..Default::default()
+ })),
+ ..Default::default()
+ }),
+ );
+
+ // Modify language_overrides property to use LanguageOverrides reference
+ settings_file_schema.properties.insert(
+ "language_overrides".to_owned(),
+ Schema::Object(SchemaObject {
+ reference: Some("#/definitions/LanguageOverrides".to_owned()),
+ ..Default::default()
+ }),
+ );
+ serde_json::to_value(root_schema).unwrap()
}
pub fn with_overrides(