@@ -4,7 +4,7 @@ use std::{
7−use anyhow::{anyhow, Context, Result};
7+use anyhow::{anyhow, Result};
8use helix_core::hashmap;
8use helix_core::hashmap;
9use helix_loader::merge_toml_values;
9use helix_loader::merge_toml_values;
10use log::warn;
10use log::warn;
@@ -209,16 +209,18 @@ pub struct Theme {
210impl From<Value> for Theme {
210impl From<Value> for Theme {
211 fn from(value: Value) -> Self {
211 fn from(value: Value) -> Self {
212− let values: Result<HashMap<String, Value>> =
212+ if let Value::Table(table) = value {
213− toml::from_str(&value.to_string()).context("Failed to load theme");
215− let (styles, scopes, highlights) = build_theme_values(values);
213+ let (styles, scopes, highlights) = build_theme_values(table);
220− highlights,
218+ highlights,
221− ..Default::default()
219+ ..Default::default()
222+ warn!("Expected theme TOML value to be a table, found {:?}", value);
@@ -228,9 +230,9 @@ impl<'de> Deserialize<'de> for Theme {
229 D: Deserializer<'de>,
231 D: Deserializer<'de>,
231− let values = HashMap::<String, Value>::deserialize(deserializer)?;
233+ let values = Map::<String, Value>::deserialize(deserializer)?;
233− let (styles, scopes, highlights) = build_theme_values(Ok(values));
235+ let (styles, scopes, highlights) = build_theme_values(values);
235 Ok(Self {
237 Ok(Self {
@@ -242,39 +244,37 @@ impl<'de> Deserialize<'de> for Theme {
244fn build_theme_values(
246fn build_theme_values(
245− values: Result<HashMap<String, Value>>,
247+ mut values: Map<String, Value>,
246) -> (HashMap<String, Style>, Vec<String>, Vec<Style>) {
248) -> (HashMap<String, Style>, Vec<String>, Vec<Style>) {
247 let mut styles = HashMap::new();
249 let mut styles = HashMap::new();
248 let mut scopes = Vec::new();
250 let mut scopes = Vec::new();
249 let mut highlights = Vec::new();
251 let mut highlights = Vec::new();
251− if let Ok(mut colors) = values {
252− // TODO: alert user of parsing failures in editor
253+ // TODO: alert user of parsing failures in editor
253− let palette = colors
254+ let palette = values
254− .remove("palette")
255+ .remove("palette")
255− .map(|value| {
256+ .map(|value| {
256− ThemePalette::try_from(value).unwrap_or_else(|err| {
257+ ThemePalette::try_from(value).unwrap_or_else(|err| {
258− ThemePalette::default()
261− .unwrap_or_default();
262− // remove inherits from value to prevent errors
263− let _ = colors.remove("inherits");
264− styles.reserve(colors.len());
265− scopes.reserve(colors.len());
266− highlights.reserve(colors.len());
267− for (name, style_value) in colors {
268− let mut style = Style::default();
269− if let Err(err) = palette.parse_style(&mut style, style_value) {
270 warn!("{}", err);
258 warn!("{}", err);
259+ ThemePalette::default()
273− // these are used both as UI and as highlights
262+ .unwrap_or_default();
274− styles.insert(name.clone(), style);
263+ // remove inherits from value to prevent errors
275− scopes.push(name);
264+ let _ = values.remove("inherits");
265+ styles.reserve(values.len());
266+ scopes.reserve(values.len());
276− highlights.push(style);
267+ highlights.reserve(values.len());
268+ for (name, style_value) in values {
269+ let mut style = Style::default();
270+ if let Err(err) = palette.parse_style(&mut style, style_value) {
274+ // these are used both as UI and as highlights
275+ styles.insert(name.clone(), style);
277+ highlights.push(style);
280 (styles, scopes, highlights)
280 (styles, scopes, highlights)