fix: limit loading of grammars

This commit is contained in:
Jan-Bulthuis 2026-07-19 15:25:44 +02:00
parent 308dcf2911
commit 06173555f6
2 changed files with 30 additions and 3 deletions

View File

@ -64,6 +64,11 @@ struct AppConfig {
#[arg(short = 'g', long, value_name = "DIR", default_value = None)] #[arg(short = 'g', long, value_name = "DIR", default_value = None)]
syntax_root: Option<PathBuf>, syntax_root: Option<PathBuf>,
/// Grammars to load, separated by commas.
/// Useful to avoid the memory required to load all languages.
#[arg(short = 'L', long = "lang", value_name = "NAME", value_delimiter = ',')]
languages: Vec<String>,
/// The log level to use /// The log level to use
#[arg(short = 'l', long, value_name = "LEVEL", default_value_t = Level::INFO)] #[arg(short = 'l', long, value_name = "LEVEL", default_value_t = Level::INFO)]
log_level: Level, log_level: Level,

View File

@ -1,4 +1,11 @@
use std::{borrow::Cow, collections::HashMap, error::Error, fs, path::Path, sync::OnceLock}; use std::{
borrow::Cow,
collections::{HashMap, HashSet},
error::Error,
fs,
path::Path,
sync::OnceLock,
};
use tracing::{info, warn}; use tracing::{info, warn};
use tree_house::{ use tree_house::{
@ -67,12 +74,20 @@ struct LanguageRegistry {
} }
impl LanguageRegistry { impl LanguageRegistry {
fn new(syntax_root: &Path) -> Self { /// Loads grammars from `syntax_root`. When `languages` is non-empty, only
/// grammars with those names are loaded; otherwise every grammar found is.
fn new(syntax_root: &Path, languages: &[String]) -> Self {
let filter: Option<HashSet<&str>> =
(!languages.is_empty()).then(|| languages.iter().map(String::as_str).collect());
let mut by_name = HashMap::new(); let mut by_name = HashMap::new();
let mut configs = Vec::new(); let mut configs = Vec::new();
for entry in fs::read_dir(syntax_root).into_iter().flatten().flatten() { for entry in fs::read_dir(syntax_root).into_iter().flatten().flatten() {
let name = entry.file_name().to_string_lossy().into_owned(); let name = entry.file_name().to_string_lossy().into_owned();
if filter.as_ref().is_some_and(|f| !f.contains(name.as_str())) {
continue;
}
let so_path = entry.path().join(format!("{name}.so")); let so_path = entry.path().join(format!("{name}.so"));
if !so_path.exists() { if !so_path.exists() {
continue; continue;
@ -87,6 +102,13 @@ impl LanguageRegistry {
} }
} }
// Warn about explicitly requested grammars that were not found.
for lang in languages {
if !by_name.contains_key(lang) {
warn!("Requested grammar {lang} was not found in the syntax root");
}
}
info!("Loaded {} syntax highlighting grammars", configs.len()); info!("Loaded {} syntax highlighting grammars", configs.len());
Self { by_name, configs } Self { by_name, configs }
} }
@ -138,7 +160,7 @@ pub fn init(config: &AppConfig) {
match &config.syntax_root { match &config.syntax_root {
Some(syntax_root) => { Some(syntax_root) => {
info!("Loading syntax files from {}", syntax_root.display()); info!("Loading syntax files from {}", syntax_root.display());
REGISTRY.get_or_init(|| LanguageRegistry::new(syntax_root)); REGISTRY.get_or_init(|| LanguageRegistry::new(syntax_root, &config.languages));
} }
None => { None => {
warn!( warn!(