From 97c8164bc81e0a438dab92d7244485005dac4ff2 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 23:45:23 +0200 Subject: literal braces are text, not placeholders, for containment and walk exclusion --- internal/plan/placeholder.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'internal/plan/placeholder.go') diff --git a/internal/plan/placeholder.go b/internal/plan/placeholder.go index b947236..5922b07 100644 --- a/internal/plan/placeholder.go +++ b/internal/plan/placeholder.go @@ -30,6 +30,30 @@ func splitExt(name string) (stem, ext string) { return name[:i], name[i:] } +// StaticPrefix returns the literal text of s before its first placeholder, +// with "{{" and "}}" read as the braces they stand for, and whether s has a +// placeholder at all. It scans like Expand, so a literal brace never counts +// as a placeholder (triage 28b). +func StaticPrefix(s string) (prefix string, templated bool) { + var b strings.Builder + for i := 0; i < len(s); { + switch { + case s[i] == '{' && i+1 < len(s) && s[i+1] == '{': + b.WriteByte('{') + i += 2 + case s[i] == '}' && i+1 < len(s) && s[i+1] == '}': + b.WriteByte('}') + i += 2 + case s[i] == '{': + return b.String(), true + default: + b.WriteByte(s[i]) + i++ + } + } + return b.String(), false +} + // Expand replaces every placeholder in s. It returns an error naming the // first placeholder it could not expand. It scans s once: "{{" and "}}" // each emit one literal brace, and any other "{" opens a placeholder that -- cgit v1.3