elio 1.1.0

Snappy, batteries-included terminal file manager with rich previews, inline images, bulk actions, and trash support.
Documentation
use super::{
    data,
    types::{RegisteredLanguage, RegistryEntry},
};

pub(crate) fn language_for_extension(ext: &str) -> Option<RegisteredLanguage> {
    language_for_alias(ext, |entry| entry.extensions)
}

pub(crate) fn language_for_exact_name(name: &str) -> Option<RegisteredLanguage> {
    let normalized = normalize(name);
    if is_env_name(&normalized) {
        return language_for_code_syntax("dotenv");
    }
    data::all_languages()
        .find(|entry| contains(entry.exact_filenames, &normalized))
        .map(|entry| entry.language)
}

pub(crate) fn language_for_shebang(interpreter: &str) -> Option<RegisteredLanguage> {
    language_for_alias(interpreter, |entry| entry.shebang_interpreters)
}

pub(crate) fn language_for_modeline(token: &str) -> Option<RegisteredLanguage> {
    language_for_alias(token, |entry| entry.modelines)
}

pub(crate) fn language_for_markdown_fence(token: &str) -> Option<RegisteredLanguage> {
    language_for_alias(token, |entry| entry.markdown_fences)
}

pub(crate) fn language_for_code_syntax(code_syntax: &str) -> Option<RegisteredLanguage> {
    let normalized = normalize(code_syntax);
    data::all_languages()
        .find(|entry| entry.language.canonical_id == normalized)
        .map(|entry| entry.language)
}

pub(crate) fn display_label_for_code_syntax(code_syntax: &str) -> Option<&'static str> {
    language_for_code_syntax(code_syntax).map(|language| language.display_label)
}

fn language_for_alias(
    value: &str,
    aliases: impl Fn(&RegistryEntry) -> &'static [&'static str],
) -> Option<RegisteredLanguage> {
    let normalized = normalize(value);
    data::all_languages()
        .find(|entry| contains(aliases(entry), &normalized))
        .map(|entry| entry.language)
}

fn normalize(value: &str) -> String {
    value.trim().to_ascii_lowercase()
}

fn contains(values: &[&str], needle: &str) -> bool {
    values.contains(&needle)
}

fn is_env_name(name: &str) -> bool {
    name == ".env" || name.starts_with(".env.")
}