diff --git a/src/syntax.rs b/src/syntax.rs index 780b8d1..42b25b7 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -92,6 +92,7 @@ impl LanguageRegistry { fn load(&self, name: &str) -> Option<&'static LanguageConfig> { let lang_dir = self.syntax_root.join(name); if !lang_dir.join(format!("{name}.so")).exists() { + warn!("No grammar found for language {name}"); return None; } match load_language(name, &lang_dir, &self.syntax_root) { @@ -229,14 +230,18 @@ fn highlight_code( light: Option<&str>, dark: Option<&str>, ) -> Option { - let scopes = crate::themes::shared_scopes(light?, dark?)?; + let (lang, light, dark) = (lang?, light?, dark?); + let Some(scopes) = crate::themes::shared_scopes(light, dark) else { + warn!("Unknown theme in pair (light={light}, dark={dark})"); + return None; + }; let registry = registry_for(scopes)?; - let language = registry.language(lang?)?; + let language = registry.language(lang)?; let rope = Rope::from_str(source); let slice = rope.slice(..); let loader = registry.as_ref(); - let syntax = Syntax::new(slice, language, Duration::from_millis(500), loader).ok()?; + let syntax = Syntax::new(slice, language, Duration::from_secs(3), loader).ok()?; let mut hl = Highlighter::new(&syntax, slice, loader, 0..source.len() as u32); let src = source.as_bytes(); diff --git a/src/themes.rs b/src/themes.rs index 2ed442e..aa61a64 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -82,7 +82,13 @@ impl ThemeRegistry { let themes = helix_themes .into_iter() - .flat_map(|(name, table)| Theme::from_toml(table).map(|t| (name, t))) + .flat_map(|(name, table)| match Theme::from_toml(table) { + Some(theme) => Some((name, theme)), + None => { + warn!("Theme {name} is missing an `ui.background`, skipping it"); + None + } + }) .collect(); Self { themes } @@ -104,8 +110,13 @@ impl Color { fn from_palette(color: &str, palette: &HashMap) -> Option { if color.starts_with('#') { Self::from_str(color) + } else if let Some(color) = palette.get(color) { + Some(color.clone()) } else { - palette.get(color).cloned() + // Neither a hex literal nor a palette entry; assume a named CSS + // colour and pass it through verbatim. + warn!("Unresolved colour {color}, passing it through as a literal"); + Some(Self(color.into())) } } } @@ -282,14 +293,21 @@ fn generate_css(scopes: &[&str], theme: &Theme) -> String { groups.entry(style).or_default().push(scope); } } - rules.extend(groups.iter().map(|(style, scopes)| { - let selectors = scopes - .iter() - .map(|s| scope_to_selector(s)) - .collect::>() - .join(","); - format!("{}{{{}}}", selectors, style_declarations(style)) - })); + + let mut group_rules: Vec = groups + .iter() + .map(|(style, scopes)| { + let selectors = scopes + .iter() + .map(|s| scope_to_selector(s)) + .collect::>() + .join(","); + format!("{}{{{}}}", selectors, style_declarations(style)) + }) + .collect(); + // Sort so the emitted stylesheet is deterministic across runs. + group_rules.sort(); + rules.extend(group_rules); rules.join("\n") } @@ -308,13 +326,8 @@ fn theme_css(light: String, dark: String) -> String { return String::new(); }; - let mut shared: Vec<&str> = light_theme - .styles - .keys() - .filter(|k| dark_theme.styles.contains_key(*k)) - .map(String::as_str) - .collect(); - shared.sort(); + let shared = shared_scopes(&light, &dark).unwrap_or_default(); + let shared: Vec<&str> = shared.iter().map(String::as_str).collect(); let light_css = generate_css(&shared, light_theme); let dark_css = generate_css(&shared, dark_theme);