From: Alpha Chen Date: Sun, 26 Apr 2026 00:40:20 +0000 (+0000) Subject: Fix line extraction for names containing colons X-Git-Url: http://quire.kejadlen.dev/?a=commitdiff_plain;h=332e45ecdab12761403d10ad98cfe647cbfcab2f;p=quire.git Fix line extraction for names containing colons extract_line_offset split on : from the left, so names like HEAD:.quire/config.fnl broke the parser. Use regex-lite to match the first :LINE:COLUMN: run instead, which is unambiguous. Assisted-by: GLM-5.1 via pi --- diff --git a/Cargo.lock b/Cargo.lock index eba8b25..57016a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,6 +882,7 @@ dependencies = [ "miette", "mlua", "predicates", + "regex", "serde", "shell-words", "tempfile", diff --git a/Cargo.toml b/Cargo.toml index 0e0a608..114eebe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ path = "src/bin/quire/main.rs" [dependencies] axum = "*" mlua = { version = "*", features = ["lua54", "serde", "vendored"] } +regex = "*" serde = { version = "*", features = ["derive"] } clap = { version = "*", features = ["derive", "env"] } clap_complete = "*" diff --git a/src/fennel.rs b/src/fennel.rs index d99539d..a14d346 100644 --- a/src/fennel.rs +++ b/src/fennel.rs @@ -168,15 +168,19 @@ fn eval_error(source: &str, name: &str, err: &mlua::Error) -> FennelError { /// Try to extract a line number from a Lua error message. /// -/// Lua errors look like `filename:LINE: message`. +/// Lua/Fennel errors embed the source location as `name:LINE:COLUMN: message`. +/// The name may contain colons (e.g. `HEAD:.quire/config.fnl`), so splitting +/// from the left breaks. Match the first `:LINE:COLUMN: ` run, which is +/// unambiguous — filenames don't end with `:digits:digits:`. fn extract_line_offset(err: &mlua::Error) -> Option { let msg = err.to_string(); - let mut parts = msg.split(':'); - // Skip the filename part. - parts.next()?; - // Next should be the line number. - let line_str = parts.next()?.trim(); - line_str.parse::().ok().filter(|&n| n > 0) + let re = regex::Regex::new(r":(\d+):\d+: ").ok()?; + let caps = re.captures(&msg)?; + caps.get(1)? + .as_str() + .parse::() + .ok() + .filter(|&n| n > 0) } /// Convert a 1-based line number to a byte offset in the source. @@ -337,4 +341,19 @@ mod tests { assert!(result.is_err()); assert!(matches!(result.unwrap_err(), FennelError::FileNotFound(..))); } + + #[test] + fn error_label_works_with_colon_in_name() { + let f = fennel(); + let source = "\n{:bad {:}"; + let result: Result = f.load_string(source, "HEAD:.quire/config.fnl"); + let err = result.unwrap_err(); + if let FennelError::Eval { label, .. } = &err { + assert_eq!( + label.offset(), + 1, + "label should point at line 2 despite colons in name" + ); + } + } }