Repository: typst/typst
File: crates/typst/src/foundations/scope.rs (Rust)

Code before:
/// The error message when a variable is not found.
#[cold]
fn unknown_variable(var: &str) -> HintedString {
    let mut res = HintedString::new(eco_format!("unknown variable: {}", var));

    if var.contains('-') {
        res.hint(eco_format!(
            "if you meant to use subtraction, try adding spaces around the minus sign(s): `{}`",
            var.replace('-', " - ")
        ));
    }

    res
}

#[cold]
fn unknown_variable_math(var: &str, in_global: bool) -> HintedString {
    let mut res = HintedString::new(eco_format!("unknown variable: {}", var));

    if matches!(var, "none" | "auto" | "false" | "true") {
        res.hint(eco_format!(
            "if you meant to use a literal, try adding a hash before it: `#{var}`",
        ));
    } else if in_global {
        res.hint(eco_format!(
            "`{var}` is not available in math, add a hash before it: `#{var}`",
        ));
    }

    res
}

/// A map from binding names to values.
#[derive(Default, Clone)]
pub struct Scope {
    map: IndexMap<EcoString, Slot>,
    deduplicate: bool,
    category: Option<Category>,
}

impl Scope {
    /// Create a new empty scope.
    pub fn new() -> Self {
        Default::default()
    }

    /// Create a new scope with duplication prevention.
    pub fn deduplicating() -> Self {
        Self { deduplicate: true, ..Default::default() }
    }


Review comment (suggestion):
```suggestion
            "`{var}` is not available directly in math, try adding a hash before it: `#{var}`",
```
- I think "directly" makes it a bit clearer that it _is_ available, just with hash.
- The "add" -> "try adding" is maybe unnecessary, but I feel like with all hints that make suggestions, it might be good to be cautious with the wording

Code after:
/// The error message when a variable is not found.
#[cold]
fn unknown_variable(var: &str) -> HintedString {
    let mut res = HintedString::new(eco_format!("unknown variable: {}", var));

    if var.contains('-') {
        res.hint(eco_format!(
            "if you meant to use subtraction, try adding spaces around the minus sign{}: `{}`",
            if var.matches('-').count() > 1 { "s" } else { "" },
            var.replace('-', " - ")
        ));
    }

    res
}

#[cold]
fn unknown_variable_math(var: &str, in_global: bool) -> HintedString {
    let mut res = HintedString::new(eco_format!("unknown variable: {}", var));

    if matches!(var, "none" | "auto" | "false" | "true") {
        res.hint(eco_format!(
            "if you meant to use a literal, try adding a hash before it: `#{var}`",
        ));
    } else if in_global {
        res.hint(eco_format!(
            "`{var}` is not available directly in math, try adding a hash before it: `#{var}`",
        ));
    }

    res
}

/// A map from binding names to values.
#[derive(Default, Clone)]
pub struct Scope {
    map: IndexMap<EcoString, Slot>,
    deduplicate: bool,
    category: Option<Category>,
}

impl Scope {
    /// Create a new empty scope.
    pub fn new() -> Self {
        Default::default()
    }

    /// Create a new scope with duplication prevention.
    pub fn deduplicating() -> Self {
        Self { deduplicate: true, ..Default::default() }
    }