fix(template): parse entire template

resolves #2937
This commit is contained in:
Jan De Dobbeleer 2022-10-13 20:12:06 +02:00 committed by Jan De Dobbeleer
parent 040a73e0f0
commit 9a98823166
2 changed files with 49 additions and 47 deletions

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"errors" "errors"
"oh-my-posh/environment" "oh-my-posh/environment"
"oh-my-posh/regex"
"strings" "strings"
"text/template" "text/template"
) )
@ -97,56 +96,47 @@ func (t *Text) cleanTemplate() {
return false return false
} }
walkAndReplace := func(node string) string { var result string
var result string var property string
var property string var inProperty bool
var inProperty bool for _, char := range t.Template {
// var literal bool switch char {
for _, char := range node { case '.':
switch char { var lastChar rune
case '.': if len(result) > 0 {
var lastChar rune lastChar = rune(result[len(result)-1])
if len(result) > 0 { }
lastChar = rune(result[len(result)-1]) // only replace if we're in a valid property start
} // with a space, { or ( character
// only replace if we're in a valid property start switch lastChar {
// with a space, { or ( character case ' ', '{', '(':
switch lastChar { property += string(char)
case ' ', '{', '(': inProperty = true
property += string(char)
inProperty = true
default:
result += string(char)
}
case ' ', '}', ')': // space or }
if !inProperty {
result += string(char)
continue
}
// end of a variable, needs to be appended
if !knownVariable(property) {
result += ".Data" + property
} else {
result += property
}
property = ""
result += string(char)
inProperty = false
default: default:
if inProperty {
property += string(char)
continue
}
result += string(char) result += string(char)
} }
case ' ', '}', ')': // space or }
if !inProperty {
result += string(char)
continue
}
// end of a variable, needs to be appended
if !knownVariable(property) {
result += ".Data" + property
} else {
result += property
}
property = ""
result += string(char)
inProperty = false
default:
if inProperty {
property += string(char)
continue
}
result += string(char)
} }
return result
} }
// matches := regex.FindAllNamedRegexMatch(`(?: |{|\()(?P<VAR>(\.[a-zA-Z_][a-zA-Z0-9]*)+)`, t.Template) t.Template = result
matches := regex.FindAllNamedRegexMatch(`(?P<NODE>{{[^{]+}})`, t.Template)
for _, match := range matches {
node := walkAndReplace(match["NODE"])
t.Template = strings.Replace(t.Template, match["NODE"], node, 1)
}
} }

View file

@ -20,6 +20,18 @@ func TestRenderTemplate(t *testing.T) {
ShouldError bool ShouldError bool
Context interface{} Context interface{}
}{ }{
{
Case: "tillig's regex",
Expected: " ⎈ hello :: world ",
Template: " ⎈ {{ replaceP \"([a-f0-9]{2})[a-f0-9]{6}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{10}([a-f0-9]{2})\" .Context \"$1..$2\" }}{{ if .Namespace }} :: {{ .Namespace }}{{ end }} ", //nolint:lll
Context: struct {
Context string
Namespace string
}{
Context: "hello",
Namespace: "world",
},
},
{ {
Case: "Env like property name", Case: "Env like property name",
Expected: "hello world", Expected: "hello world",