mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-01-21 16:11:20 -08:00
refactor: remove env from template/text
This commit is contained in:
parent
701cd499df
commit
cefe985bf7
4
src/cache/template.go
vendored
4
src/cache/template.go
vendored
|
@ -1,13 +1,10 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/maps"
|
||||
)
|
||||
|
||||
type Template struct {
|
||||
Env map[string]string
|
||||
SegmentsCache maps.Simple
|
||||
Segments *maps.Concurrent
|
||||
Var maps.Simple
|
||||
|
@ -24,7 +21,6 @@ type Template struct {
|
|||
PromptCount int
|
||||
SHLVL int
|
||||
Jobs int
|
||||
sync.RWMutex
|
||||
WSL bool
|
||||
Root bool
|
||||
Initialized bool
|
||||
|
|
|
@ -69,7 +69,7 @@ Exports the config to an image file using customized output options.`,
|
|||
env.Var = cfg.Var
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate(env)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
||||
terminal.Colors = cfg.MakeColors()
|
||||
|
||||
eng := &prompt.Engine{
|
||||
|
|
|
@ -55,7 +55,7 @@ func createDebugCmd() *cobra.Command {
|
|||
env.Var = cfg.Var
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate(env)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
||||
terminal.Colors = cfg.MakeColors()
|
||||
terminal.Plain = plain
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/shell"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -67,6 +68,8 @@ See the documentation to initialize your shell: https://ohmyposh.dev/docs/instal
|
|||
env.Init()
|
||||
defer env.Close()
|
||||
|
||||
template.Init(env)
|
||||
|
||||
cfg := config.Load(env)
|
||||
|
||||
feats := cfg.Features()
|
||||
|
|
|
@ -120,7 +120,7 @@ func (c Ansi) ToForeground() Ansi {
|
|||
return c
|
||||
}
|
||||
|
||||
func (c Ansi) ResolveTemplate(env runtime.Environment) Ansi {
|
||||
func (c Ansi) ResolveTemplate() Ansi {
|
||||
if c.IsEmpty() {
|
||||
return c
|
||||
}
|
||||
|
@ -132,7 +132,6 @@ func (c Ansi) ResolveTemplate(env runtime.Environment) Ansi {
|
|||
tmpl := &template.Text{
|
||||
Template: string(c),
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache/mock"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
||||
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
@ -81,15 +82,14 @@ func TestAnsiRender(t *testing.T) {
|
|||
for _, tc := range cases {
|
||||
env := new(mock.Environment)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{
|
||||
"TERM_PROGRAM": tc.Term,
|
||||
},
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
env.On("Getenv", "TERM_PROGRAM").Return(tc.Term)
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
template.Init(env)
|
||||
|
||||
ansi := Ansi("{{ if eq \"vscode\" .Env.TERM_PROGRAM }}#123456{{end}}")
|
||||
got := ansi.ResolveTemplate(env)
|
||||
got := ansi.ResolveTemplate()
|
||||
|
||||
assert.Equal(t, tc.Expected, got, tc.Case)
|
||||
}
|
||||
|
|
|
@ -64,7 +64,6 @@ func (cfg *Config) getPalette() color.Palette {
|
|||
|
||||
tmpl := &template.Text{
|
||||
Template: cfg.Palettes.Template,
|
||||
Env: cfg.env,
|
||||
}
|
||||
|
||||
key, err := tmpl.Render()
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/color"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
|
@ -93,11 +93,12 @@ func TestGetPalette(t *testing.T) {
|
|||
for _, tc := range cases {
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{},
|
||||
Shell: "bash",
|
||||
})
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return("bash")
|
||||
|
||||
template.Init(env)
|
||||
|
||||
cfg := &Config{
|
||||
env: env,
|
||||
|
|
|
@ -20,17 +20,19 @@ import (
|
|||
// SegmentStyle the style of segment, for more information, see the constants
|
||||
type SegmentStyle string
|
||||
|
||||
func (s *SegmentStyle) resolve(env runtime.Environment, context any) SegmentStyle {
|
||||
func (s *SegmentStyle) resolve(context any) SegmentStyle {
|
||||
txtTemplate := &template.Text{
|
||||
Context: context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
txtTemplate.Template = string(*s)
|
||||
value, err := txtTemplate.Render()
|
||||
|
||||
// default to Plain
|
||||
if err != nil || len(value) == 0 {
|
||||
return Plain
|
||||
}
|
||||
|
||||
return SegmentStyle(value)
|
||||
}
|
||||
|
||||
|
@ -218,7 +220,7 @@ func (segment *Segment) SetText() {
|
|||
|
||||
func (segment *Segment) string() string {
|
||||
if !segment.Templates.Empty() {
|
||||
templatesResult := segment.Templates.Resolve(segment.writer, segment.env, "", segment.TemplatesLogic)
|
||||
templatesResult := segment.Templates.Resolve(segment.writer, "", segment.TemplatesLogic)
|
||||
if len(segment.Template) == 0 {
|
||||
return templatesResult
|
||||
}
|
||||
|
@ -231,7 +233,6 @@ func (segment *Segment) string() string {
|
|||
tmpl := &template.Text{
|
||||
Template: segment.Template,
|
||||
Context: segment.writer,
|
||||
Env: segment.env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
@ -282,7 +283,7 @@ func (segment *Segment) cwdExcluded() bool {
|
|||
|
||||
func (segment *Segment) ResolveForeground() color.Ansi {
|
||||
if len(segment.ForegroundTemplates) != 0 {
|
||||
match := segment.ForegroundTemplates.FirstMatch(segment.writer, segment.env, segment.Foreground.String())
|
||||
match := segment.ForegroundTemplates.FirstMatch(segment.writer, segment.Foreground.String())
|
||||
segment.Foreground = color.Ansi(match)
|
||||
}
|
||||
|
||||
|
@ -291,7 +292,7 @@ func (segment *Segment) ResolveForeground() color.Ansi {
|
|||
|
||||
func (segment *Segment) ResolveBackground() color.Ansi {
|
||||
if len(segment.BackgroundTemplates) != 0 {
|
||||
match := segment.BackgroundTemplates.FirstMatch(segment.writer, segment.env, segment.Background.String())
|
||||
match := segment.BackgroundTemplates.FirstMatch(segment.writer, segment.Background.String())
|
||||
segment.Background = color.Ansi(match)
|
||||
}
|
||||
|
||||
|
@ -303,7 +304,7 @@ func (segment *Segment) ResolveStyle() SegmentStyle {
|
|||
return segment.styleCache
|
||||
}
|
||||
|
||||
segment.styleCache = segment.Style.resolve(segment.env, segment.writer)
|
||||
segment.styleCache = segment.Style.resolve(segment.writer)
|
||||
|
||||
return segment.styleCache
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/color"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
|
@ -12,7 +11,6 @@ import (
|
|||
"github.com/jandedobbeleer/oh-my-posh/src/segments"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -144,19 +142,11 @@ func TestGetColors(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
env := new(mock.Environment)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
segment := &Segment{
|
||||
writer: &segments.Aws{
|
||||
Profile: tc.Profile,
|
||||
Region: tc.Region,
|
||||
},
|
||||
env: env,
|
||||
}
|
||||
|
||||
if tc.Background {
|
||||
|
|
|
@ -86,7 +86,6 @@ func (e *Engine) pwd() {
|
|||
// Allow template logic to define when to enable the PWD (when supported)
|
||||
tmpl := &template.Text{
|
||||
Template: e.Config.PWD,
|
||||
Env: e.Env,
|
||||
}
|
||||
|
||||
pwdType, err := tmpl.Render()
|
||||
|
@ -159,7 +158,6 @@ func (e *Engine) shouldFill(filler string, padLength int) (string, bool) {
|
|||
func (e *Engine) getTitleTemplateText() string {
|
||||
tmpl := &template.Text{
|
||||
Template: e.Config.ConsoleTitleTemplate,
|
||||
Env: e.Env,
|
||||
}
|
||||
if text, err := tmpl.Render(); err == nil {
|
||||
return text
|
||||
|
@ -520,11 +518,13 @@ func New(flags *runtime.Flags) *Engine {
|
|||
env.Init()
|
||||
cfg := config.Load(env)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
env.Var = cfg.Var
|
||||
flags.HasTransient = cfg.TransientPrompt != nil
|
||||
|
||||
terminal.Init(env.Shell())
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate(env)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
||||
terminal.Colors = cfg.MakeColors()
|
||||
terminal.Plain = flags.Plain
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/shell"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -92,12 +93,11 @@ func TestPrintPWD(t *testing.T) {
|
|||
env.On("Host").Return("host", nil)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
Shell: "shell",
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
template.Init(env)
|
||||
|
||||
engine := &Engine{
|
||||
Env: env,
|
||||
|
@ -127,7 +127,7 @@ func engineRender() {
|
|||
cfg := config.Load(env)
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate(env)
|
||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
||||
terminal.Colors = cfg.MakeColors()
|
||||
|
||||
engine := &Engine{
|
||||
|
@ -185,11 +185,7 @@ func TestGetTitle(t *testing.T) {
|
|||
env.On("Home").Return("/usr/home")
|
||||
env.On("PathSeparator").Return(tc.PathSeparator)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{
|
||||
"USERDOMAIN": "MyCompany",
|
||||
},
|
||||
Shell: tc.ShellName,
|
||||
UserName: "MyUser",
|
||||
Root: tc.Root,
|
||||
|
@ -197,8 +193,11 @@ func TestGetTitle(t *testing.T) {
|
|||
PWD: tc.Cwd,
|
||||
Folder: "vagrant",
|
||||
})
|
||||
env.On("Getenv", "USERDOMAIN").Return("MyCompany")
|
||||
env.On("Shell").Return(tc.ShellName)
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
template.Init(env)
|
||||
|
||||
engine := &Engine{
|
||||
Config: &config.Config{
|
||||
|
@ -249,18 +248,17 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) {
|
|||
env.On("Pwd").Return(tc.Cwd)
|
||||
env.On("Home").Return("/usr/home")
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{
|
||||
"USERDOMAIN": "MyCompany",
|
||||
},
|
||||
Shell: tc.ShellName,
|
||||
UserName: "MyUser",
|
||||
Root: tc.Root,
|
||||
HostName: "",
|
||||
})
|
||||
env.On("Getenv", "USERDOMAIN").Return("MyCompany")
|
||||
env.On("Shell").Return(tc.ShellName)
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
template.Init(env)
|
||||
|
||||
engine := &Engine{
|
||||
Config: &config.Config{
|
||||
|
|
|
@ -60,7 +60,6 @@ func (e *Engine) ExtraPrompt(promptType ExtraPromptType) string {
|
|||
|
||||
tmpl := &template.Text{
|
||||
Template: getTemplate(prompt.Template),
|
||||
Env: e.Env,
|
||||
}
|
||||
|
||||
promptText, err := tmpl.Render()
|
||||
|
@ -78,8 +77,8 @@ func (e *Engine) ExtraPrompt(promptType ExtraPromptType) string {
|
|||
e.write(terminal.PromptStart())
|
||||
}
|
||||
|
||||
foreground := color.Ansi(prompt.ForegroundTemplates.FirstMatch(nil, e.Env, string(prompt.Foreground)))
|
||||
background := color.Ansi(prompt.BackgroundTemplates.FirstMatch(nil, e.Env, string(prompt.Background)))
|
||||
foreground := color.Ansi(prompt.ForegroundTemplates.FirstMatch(nil, string(prompt.Foreground)))
|
||||
background := color.Ansi(prompt.BackgroundTemplates.FirstMatch(nil, string(prompt.Background)))
|
||||
terminal.SetColors(background, foreground)
|
||||
terminal.Write(background, foreground, promptText)
|
||||
|
||||
|
|
|
@ -641,8 +641,6 @@ func (term *Terminal) Logs() string {
|
|||
func (term *Terminal) TemplateCache() *cache.Template {
|
||||
defer term.Trace(time.Now())
|
||||
tmplCache := term.tmplCache
|
||||
tmplCache.Lock()
|
||||
defer tmplCache.Unlock()
|
||||
|
||||
if tmplCache.Initialized {
|
||||
return tmplCache
|
||||
|
@ -655,7 +653,6 @@ func (term *Terminal) TemplateCache() *cache.Template {
|
|||
tmplCache.WSL = term.IsWsl()
|
||||
tmplCache.Segments = maps.NewConcurrent()
|
||||
tmplCache.PromptCount = term.CmdFlags.PromptCount
|
||||
tmplCache.Env = make(map[string]string)
|
||||
tmplCache.Var = make(map[string]any)
|
||||
tmplCache.Jobs = term.CmdFlags.JobCount
|
||||
|
||||
|
@ -663,17 +660,6 @@ func (term *Terminal) TemplateCache() *cache.Template {
|
|||
tmplCache.Var = term.Var
|
||||
}
|
||||
|
||||
const separator = "="
|
||||
values := os.Environ()
|
||||
term.DebugF("environment: %v", values)
|
||||
for value := range values {
|
||||
key, val, valid := strings.Cut(values[value], separator)
|
||||
if !valid {
|
||||
continue
|
||||
}
|
||||
tmplCache.Env[key] = val
|
||||
}
|
||||
|
||||
pwd := term.Pwd()
|
||||
tmplCache.PWD = ReplaceHomeDirPrefixWithTilde(term, pwd)
|
||||
|
||||
|
|
|
@ -261,14 +261,16 @@ func (l *language) buildVersionURL() {
|
|||
if len(versionURLTemplate) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
tmpl := &template.Text{
|
||||
Template: versionURLTemplate,
|
||||
Context: l.version,
|
||||
Env: l.env,
|
||||
}
|
||||
|
||||
url, err := tmpl.Render()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
l.version.URL = url
|
||||
}
|
||||
|
|
|
@ -3,13 +3,11 @@ package segments
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -60,12 +58,6 @@ func bootStrapLanguageTest(args *languageArgs) *language {
|
|||
|
||||
env.On("Pwd").Return(cwd)
|
||||
env.On("Home").Return(home)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
|
||||
if args.properties == nil {
|
||||
args.properties = properties.Map{}
|
||||
|
@ -549,11 +541,6 @@ func getMockedLanguageEnv(params *mockedLanguageParams) (*mock.Environment, prop
|
|||
env.On("HasFiles", params.extension).Return(true)
|
||||
env.On("Pwd").Return("/usr/home/project")
|
||||
env.On("Home").Return("/usr/home")
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
props := properties.Map{
|
||||
properties.FetchVersion: true,
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -26,19 +25,18 @@ func TestGetNodePackageVersion(t *testing.T) {
|
|||
|
||||
for _, tc := range cases {
|
||||
var env = new(mock.Environment)
|
||||
// mock getVersion methods
|
||||
env.On("Pwd").Return("posh")
|
||||
path := filepath.Join("posh", "node_modules", "nx")
|
||||
env.On("HasFilesInDir", path, "package.json").Return(!tc.NoFiles)
|
||||
env.On("FileContent", filepath.Join(path, "package.json")).Return(tc.PackageJSON)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
|
||||
got, err := getNodePackageVersion(env, "nx")
|
||||
|
||||
if tc.ShouldFail {
|
||||
assert.Error(t, err, tc.Case)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Nil(t, err, tc.Case)
|
||||
assert.Equal(t, tc.Version, got, tc.Case)
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ func TestOSInfo(t *testing.T) {
|
|||
env.On("GOOS").Return(tc.GOOS)
|
||||
env.On("Platform").Return(tc.Platform)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
WSL: tc.IsWSL,
|
||||
})
|
||||
|
||||
|
|
|
@ -247,7 +247,6 @@ func (pt *Path) getMaxWidth() int {
|
|||
tmpl := &template.Text{
|
||||
Template: width,
|
||||
Context: pt,
|
||||
Env: pt.env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
@ -279,7 +278,6 @@ func (pt *Path) getFolderSeparator() string {
|
|||
tmpl := &template.Text{
|
||||
Template: separatorTemplate,
|
||||
Context: pt,
|
||||
Env: pt.env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
@ -573,7 +571,6 @@ func (pt *Path) setMappedLocations() {
|
|||
tmpl := &template.Text{
|
||||
Template: key,
|
||||
Context: pt,
|
||||
Env: pt.env,
|
||||
}
|
||||
|
||||
path, err := tmpl.Render()
|
||||
|
|
|
@ -33,25 +33,28 @@ func renderTemplateNoTrimSpace(env *mock.Environment, segmentTemplate string, co
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
}
|
||||
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
template.Init(env)
|
||||
|
||||
tmpl := &template.Text{
|
||||
Template: segmentTemplate,
|
||||
Context: context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
|
@ -157,7 +160,9 @@ func TestParent(t *testing.T) {
|
|||
FolderSeparatorIcon: tc.FolderSeparatorIcon,
|
||||
},
|
||||
}
|
||||
|
||||
path.setPaths()
|
||||
|
||||
got := path.Parent()
|
||||
assert.EqualValues(t, tc.Expected, got, tc.Case)
|
||||
}
|
||||
|
@ -947,7 +952,7 @@ func TestFullPathCustomMappedLocations(t *testing.T) {
|
|||
PathSeparator string
|
||||
Expected string
|
||||
}{
|
||||
{Pwd: abcd, MappedLocations: map[string]string{"{{ .Env.HOME }}/d": "#"}, Expected: "#"},
|
||||
{Pwd: homeDir + "/d", MappedLocations: map[string]string{"{{ .Env.HOME }}/d": "#"}, Expected: "#"},
|
||||
{Pwd: abcd, MappedLocations: map[string]string{abcd: "#"}, Expected: "#"},
|
||||
{Pwd: "\\a\\b\\c\\d", MappedLocations: map[string]string{"\\a\\b": "#"}, GOOS: runtime.WINDOWS, PathSeparator: "\\", Expected: "#\\c\\d"},
|
||||
{Pwd: abcd, MappedLocations: map[string]string{"/a/b": "#"}, Expected: "#/c/d"},
|
||||
|
@ -980,11 +985,10 @@ func TestFullPathCustomMappedLocations(t *testing.T) {
|
|||
env.On("Flags").Return(args)
|
||||
env.On("Shell").Return(shell.GENERIC)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{
|
||||
"HOME": "/a/b/c",
|
||||
},
|
||||
})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
env.On("Getenv", "HOME").Return(homeDir)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
|
@ -997,6 +1001,7 @@ func TestFullPathCustomMappedLocations(t *testing.T) {
|
|||
|
||||
path.setPaths()
|
||||
path.setStyle()
|
||||
|
||||
got := renderTemplateNoTrimSpace(env, "{{ .Path }}", path)
|
||||
assert.Equal(t, tc.Expected, got)
|
||||
}
|
||||
|
@ -1015,6 +1020,9 @@ func TestFolderPathCustomMappedLocations(t *testing.T) {
|
|||
env.On("Flags").Return(args)
|
||||
env.On("Shell").Return(shell.GENERIC)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
props: properties.Map{
|
||||
|
@ -1024,8 +1032,10 @@ func TestFolderPathCustomMappedLocations(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
path.setPaths()
|
||||
path.setStyle()
|
||||
|
||||
got := renderTemplateNoTrimSpace(env, "{{ .Path }}", path)
|
||||
assert.Equal(t, "#", got)
|
||||
}
|
||||
|
@ -1404,6 +1414,9 @@ func TestGetPwd(t *testing.T) {
|
|||
env.On("Flags").Return(args)
|
||||
env.On("Shell").Return(shell.PWSH)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
props: properties.Map{
|
||||
|
@ -1413,6 +1426,7 @@ func TestGetPwd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
path.setPaths()
|
||||
assert.Equal(t, tc.Expected, path.pwd)
|
||||
}
|
||||
|
@ -1437,7 +1451,9 @@ func TestGetFolderSeparator(t *testing.T) {
|
|||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return(shell.GENERIC)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
|
@ -1455,7 +1471,6 @@ func TestGetFolderSeparator(t *testing.T) {
|
|||
}
|
||||
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
Shell: "bash",
|
||||
})
|
||||
|
||||
|
@ -1626,7 +1641,8 @@ func TestReplaceMappedLocations(t *testing.T) {
|
|||
env.On("GOOS").Return(runtime.DARWIN)
|
||||
env.On("Home").Return("/a/b/k")
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
|
@ -1750,13 +1766,11 @@ func TestGetMaxWidth(t *testing.T) {
|
|||
env := new(mock.Environment)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Error", testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{
|
||||
"MAX_WIDTH": "120",
|
||||
},
|
||||
Shell: "bash",
|
||||
})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
env.On("Getenv", "MAX_WIDTH").Return("120")
|
||||
env.On("Shell").Return(shell.BASH)
|
||||
|
||||
template.Init(env)
|
||||
|
||||
path := &Path{
|
||||
env: env,
|
||||
|
|
|
@ -117,20 +117,19 @@ func TestSessionSegmentTemplate(t *testing.T) {
|
|||
env.On("User").Return(tc.UserName)
|
||||
env.On("GOOS").Return("burp")
|
||||
env.On("Host").Return(tc.ComputerName, nil)
|
||||
|
||||
var SSHSession string
|
||||
if tc.SSHSession {
|
||||
SSHSession = "zezzion"
|
||||
}
|
||||
|
||||
env.On("Getenv", "SSH_CONNECTION").Return(SSHSession)
|
||||
env.On("Getenv", "SSH_CLIENT").Return(SSHSession)
|
||||
env.On("Getenv", "POSH_SESSION_DEFAULT_USER").Return(tc.DefaultUserName)
|
||||
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
UserName: tc.UserName,
|
||||
HostName: tc.ComputerName,
|
||||
Env: map[string]string{
|
||||
"SSH_CONNECTION": SSHSession,
|
||||
"SSH_CLIENT": SSHSession,
|
||||
"POSH_SESSION_DEFAULT_USER": tc.DefaultUserName,
|
||||
},
|
||||
Root: tc.Root,
|
||||
})
|
||||
|
||||
|
@ -147,6 +146,7 @@ func TestSessionSegmentTemplate(t *testing.T) {
|
|||
env: env,
|
||||
props: properties.Map{},
|
||||
}
|
||||
|
||||
_ = session.Enabled()
|
||||
assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, session), tc.Case)
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ func (s *Status) Init(props properties.Properties, env runtime.Environment) {
|
|||
statusTemplate := s.props.GetString(StatusTemplate, "{{ .Code }}")
|
||||
s.template = &template.Text{
|
||||
Template: statusTemplate,
|
||||
Env: s.env,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,21 +93,13 @@ func TestFormatStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
env := new(mock.Environment)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Code: 133,
|
||||
})
|
||||
env.On("Error", testify_.Anything).Return(nil)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
props := properties.Map{
|
||||
StatusTemplate: tc.Template,
|
||||
StatusSeparator: tc.Separator,
|
||||
}
|
||||
|
||||
s := &Status{}
|
||||
s.Init(props, env)
|
||||
s.Init(props, new(mock.Environment))
|
||||
|
||||
assert.Equal(t, tc.Expected, s.formatStatus(tc.Status, tc.PipeStatus), tc.Case)
|
||||
}
|
||||
|
|
|
@ -30,15 +30,14 @@ func TestTextSegment(t *testing.T) {
|
|||
env.On("PathSeparator").Return("/")
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
UserName: "Posh",
|
||||
Env: map[string]string{
|
||||
"HELLO": "hello",
|
||||
"WORLD": "",
|
||||
},
|
||||
HostName: "MyHost",
|
||||
Shell: "terminal",
|
||||
Root: true,
|
||||
Folder: "posh",
|
||||
})
|
||||
env.On("Getenv", "HELLO").Return("hello")
|
||||
env.On("Getenv", "WORLD").Return("")
|
||||
|
||||
txt := &Text{
|
||||
env: env,
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ func (w *Wakatime) getURL() (string, error) {
|
|||
tmpl := &template.Text{
|
||||
Template: url,
|
||||
Context: w,
|
||||
Env: w.env,
|
||||
}
|
||||
return tmpl.Render()
|
||||
}
|
||||
|
|
|
@ -5,13 +5,10 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestWTTrackedTime(t *testing.T) {
|
||||
|
@ -68,13 +65,6 @@ func TestWTTrackedTime(t *testing.T) {
|
|||
|
||||
env.On("HTTPRequest", FAKEAPIURL).Return([]byte(response), tc.Error)
|
||||
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{"HELLO": "hello"},
|
||||
})
|
||||
|
||||
w := &Wakatime{
|
||||
props: properties.Map{
|
||||
URL: FAKEAPIURL,
|
||||
|
@ -86,54 +76,3 @@ func TestWTTrackedTime(t *testing.T) {
|
|||
assert.Equal(t, tc.Expected, renderTemplate(env, w.Template(), w), tc.Case+" - String")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWTGetUrl(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
Expected string
|
||||
URL string
|
||||
ShouldError bool
|
||||
}{
|
||||
{
|
||||
Case: "no template",
|
||||
Expected: "test",
|
||||
URL: "test",
|
||||
},
|
||||
{
|
||||
Case: "template",
|
||||
URL: "{{ .Env.HELLO }} world",
|
||||
Expected: "hello world",
|
||||
},
|
||||
{
|
||||
Case: "error",
|
||||
URL: "{{ .BURR }}",
|
||||
ShouldError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
env := &mock.Environment{}
|
||||
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: map[string]string{"HELLO": "hello"},
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
w := &Wakatime{
|
||||
props: properties.Map{
|
||||
URL: tc.URL,
|
||||
},
|
||||
env: env,
|
||||
}
|
||||
|
||||
got, err := w.getURL()
|
||||
|
||||
if tc.ShouldError {
|
||||
assert.Error(t, err, tc.Case)
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, tc.Expected, got, tc.Case)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -25,16 +24,15 @@ func TestGlob(t *testing.T) {
|
|||
|
||||
env := &mock.Environment{}
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
Init(env)
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
|
85
src/template/init.go
Normal file
85
src/template/init.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package template
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// Errors to show when the template handling fails
|
||||
InvalidTemplate = "invalid template text"
|
||||
IncorrectTemplate = "unable to create text based on template"
|
||||
|
||||
globalRef = ".$"
|
||||
|
||||
elvish = "elvish"
|
||||
xonsh = "xonsh"
|
||||
)
|
||||
|
||||
var (
|
||||
shell string
|
||||
tmplFunc *template.Template
|
||||
contextPool sync.Pool
|
||||
buffPool sync.Pool
|
||||
env runtime.Environment
|
||||
knownVariables []string
|
||||
)
|
||||
|
||||
type buff bytes.Buffer
|
||||
|
||||
func (b *buff) release() {
|
||||
(*bytes.Buffer)(b).Reset()
|
||||
buffPool.Put(b)
|
||||
}
|
||||
|
||||
func (b *buff) Write(p []byte) (n int, err error) {
|
||||
return (*bytes.Buffer)(b).Write(p)
|
||||
}
|
||||
|
||||
func (b *buff) String() string {
|
||||
return (*bytes.Buffer)(b).String()
|
||||
}
|
||||
|
||||
func Init(environment runtime.Environment) {
|
||||
env = environment
|
||||
shell = env.Shell()
|
||||
|
||||
tmplFunc = template.New("cache").Funcs(funcMap())
|
||||
|
||||
contextPool = sync.Pool{
|
||||
New: func() any {
|
||||
return &context{}
|
||||
},
|
||||
}
|
||||
|
||||
buffPool = sync.Pool{
|
||||
New: func() any {
|
||||
return &buff{}
|
||||
},
|
||||
}
|
||||
|
||||
knownVariables = []string{
|
||||
"Root",
|
||||
"PWD",
|
||||
"AbsolutePWD",
|
||||
"Folder",
|
||||
"Shell",
|
||||
"ShellVersion",
|
||||
"UserName",
|
||||
"HostName",
|
||||
"Code",
|
||||
"Env",
|
||||
"OS",
|
||||
"WSL",
|
||||
"PromptCount",
|
||||
"Segments",
|
||||
"SHLVL",
|
||||
"Templates",
|
||||
"Var",
|
||||
"Data",
|
||||
"Jobs",
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -23,25 +22,26 @@ func TestUrl(t *testing.T) {
|
|||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("TemplateCache").Return(&cache.Template{})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
Init(env)
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
if tc.ShouldError {
|
||||
assert.Error(t, err)
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.Expected, text, tc.Case)
|
||||
}
|
||||
}
|
||||
|
@ -55,18 +55,10 @@ func TestPath(t *testing.T) {
|
|||
{Case: "valid path", Expected: "<LINK>file:/test/test<TEXT>link</TEXT></LINK>", Template: `{{ path "link" "/test/test" }}`},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, _ := tmpl.Render()
|
||||
|
|
|
@ -2,8 +2,6 @@ package template
|
|||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
)
|
||||
|
||||
type Logic string
|
||||
|
@ -19,25 +17,24 @@ func (l List) Empty() bool {
|
|||
return len(l) == 0
|
||||
}
|
||||
|
||||
func (l List) Resolve(context any, env runtime.Environment, defaultValue string, logic Logic) string {
|
||||
func (l List) Resolve(context any, defaultValue string, logic Logic) string {
|
||||
switch logic {
|
||||
case FirstMatch:
|
||||
return l.FirstMatch(context, env, defaultValue)
|
||||
return l.FirstMatch(context, defaultValue)
|
||||
case Join:
|
||||
fallthrough
|
||||
default:
|
||||
return l.Join(context, env)
|
||||
return l.Join(context)
|
||||
}
|
||||
}
|
||||
|
||||
func (l List) Join(context any, env runtime.Environment) string {
|
||||
func (l List) Join(context any) string {
|
||||
if len(l) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
txtTemplate := &Text{
|
||||
Context: context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
var buffer strings.Builder
|
||||
|
@ -54,14 +51,13 @@ func (l List) Join(context any, env runtime.Environment) string {
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (l List) FirstMatch(context any, env runtime.Environment, defaultValue string) string {
|
||||
func (l List) FirstMatch(context any, defaultValue string) string {
|
||||
if len(l) == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
txtTemplate := &Text{
|
||||
Context: context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
for _, tmpl := range l {
|
||||
|
|
|
@ -3,12 +3,7 @@ package template
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestHResult(t *testing.T) {
|
||||
|
@ -22,20 +17,10 @@ func TestHResult(t *testing.T) {
|
|||
{Case: "Not a number", Template: `{{ hresult "no number" }}`, ShouldError: true},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
|
|
@ -3,12 +3,7 @@ package template
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestRoundSeconds(t *testing.T) {
|
||||
|
@ -29,20 +24,10 @@ func TestRoundSeconds(t *testing.T) {
|
|||
{Case: "error", Expected: "", Template: "{{ secondsRound foo }}", ShouldError: true},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
|
|
@ -3,12 +3,7 @@ package template
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
testify_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestTrunc(t *testing.T) {
|
||||
|
@ -26,20 +21,10 @@ func TestTrunc(t *testing.T) {
|
|||
{Case: "negative", Expected: "ld", Template: `{{ trunc -2 "Hello World" }}`},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("Debug", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
|
|
@ -1,98 +1,26 @@
|
|||
package template
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// Errors to show when the template handling fails
|
||||
InvalidTemplate = "invalid template text"
|
||||
IncorrectTemplate = "unable to create text based on template"
|
||||
|
||||
globalRef = ".$"
|
||||
|
||||
elvish = "elvish"
|
||||
xonsh = "xonsh"
|
||||
)
|
||||
|
||||
var (
|
||||
knownVariables = []string{
|
||||
"Root",
|
||||
"PWD",
|
||||
"AbsolutePWD",
|
||||
"PSWD",
|
||||
"Folder",
|
||||
"Shell",
|
||||
"ShellVersion",
|
||||
"UserName",
|
||||
"HostName",
|
||||
"Code",
|
||||
"Env",
|
||||
"OS",
|
||||
"WSL",
|
||||
"PromptCount",
|
||||
"Segments",
|
||||
"SHLVL",
|
||||
"Templates",
|
||||
"Var",
|
||||
"Data",
|
||||
"Jobs",
|
||||
}
|
||||
|
||||
shell string
|
||||
|
||||
tmplFunc = template.New("cache").Funcs(funcMap())
|
||||
|
||||
contextPool = sync.Pool{
|
||||
New: func() any {
|
||||
return &context{}
|
||||
},
|
||||
}
|
||||
|
||||
buffPool = sync.Pool{
|
||||
New: func() any {
|
||||
return &buff{}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type buff bytes.Buffer
|
||||
|
||||
func (b *buff) release() {
|
||||
(*bytes.Buffer)(b).Reset()
|
||||
buffPool.Put(b)
|
||||
}
|
||||
|
||||
func (b *buff) Write(p []byte) (n int, err error) {
|
||||
return (*bytes.Buffer)(b).Write(p)
|
||||
}
|
||||
|
||||
func (b *buff) String() string {
|
||||
return (*bytes.Buffer)(b).String()
|
||||
}
|
||||
|
||||
type Text struct {
|
||||
Template string
|
||||
Context any
|
||||
Env runtime.Environment
|
||||
Template string
|
||||
}
|
||||
|
||||
type Data any
|
||||
|
||||
type context struct {
|
||||
*cache.Template
|
||||
|
||||
// Simple container to hold ANY object
|
||||
Data
|
||||
Getenv func(string) string
|
||||
cache.Template
|
||||
initialized bool
|
||||
}
|
||||
|
||||
|
@ -103,9 +31,8 @@ func (c *context) init(t *Text) {
|
|||
return
|
||||
}
|
||||
|
||||
if tmplCache := t.Env.TemplateCache(); tmplCache != nil {
|
||||
c.Template = tmplCache
|
||||
}
|
||||
c.Getenv = env.Getenv
|
||||
c.Template = *env.TemplateCache()
|
||||
|
||||
c.initialized = true
|
||||
}
|
||||
|
@ -116,19 +43,17 @@ func (c *context) release() {
|
|||
}
|
||||
|
||||
func (t *Text) Render() (string, error) {
|
||||
t.Env.DebugF("rendering template: %s", t.Template)
|
||||
|
||||
shell = t.Env.Flags().Shell
|
||||
env.DebugF("rendering template: %s", t.Template)
|
||||
|
||||
if !strings.Contains(t.Template, "{{") || !strings.Contains(t.Template, "}}") {
|
||||
return t.Template, nil
|
||||
}
|
||||
|
||||
t.cleanTemplate()
|
||||
t.patchTemplate()
|
||||
|
||||
tmpl, err := tmplFunc.Parse(t.Template)
|
||||
if err != nil {
|
||||
t.Env.Error(err)
|
||||
env.Error(err)
|
||||
return "", errors.New(InvalidTemplate)
|
||||
}
|
||||
|
||||
|
@ -141,7 +66,7 @@ func (t *Text) Render() (string, error) {
|
|||
|
||||
err = tmpl.Execute(buffer, context)
|
||||
if err != nil {
|
||||
t.Env.Error(err)
|
||||
env.Error(err)
|
||||
msg := regex.FindNamedRegexMatch(`at (?P<MSG><.*)$`, err.Error())
|
||||
if len(msg) == 0 {
|
||||
return "", errors.New(IncorrectTemplate)
|
||||
|
@ -158,7 +83,7 @@ func (t *Text) Render() (string, error) {
|
|||
return text, nil
|
||||
}
|
||||
|
||||
func (t *Text) cleanTemplate() {
|
||||
func (t *Text) patchTemplate() {
|
||||
isKnownVariable := func(variable string) bool {
|
||||
variable = strings.TrimPrefix(variable, ".")
|
||||
splitted := strings.Split(variable, ".")
|
||||
|
@ -233,6 +158,11 @@ func (t *Text) cleanTemplate() {
|
|||
// the list of segments so they can be accessed directly
|
||||
property = strings.Replace(property, ".Segments", ".Segments.ToSimple", 1)
|
||||
result += property
|
||||
case strings.HasPrefix(property, ".Env."):
|
||||
// we need to replace the property with the getEnv function
|
||||
// so we can access the environment variables directly
|
||||
property = strings.TrimPrefix(property, ".Env.")
|
||||
result += fmt.Sprintf(`(call .Getenv "%s")`, property)
|
||||
default:
|
||||
// check if we have the same property in Data
|
||||
// and replace it with the Data property so it
|
||||
|
@ -240,6 +170,7 @@ func (t *Text) cleanTemplate() {
|
|||
if fields.hasField(property) {
|
||||
property = ".Data" + property
|
||||
}
|
||||
|
||||
// remove the global reference so we can use it directly
|
||||
property = strings.TrimPrefix(property, globalRef)
|
||||
result += property
|
||||
|
|
|
@ -157,19 +157,10 @@ func TestRenderTemplate(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: tc.Context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
@ -247,18 +238,23 @@ func TestRenderTemplateEnvVar(t *testing.T) {
|
|||
}
|
||||
for _, tc := range cases {
|
||||
env := &mock.Environment{}
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: tc.Env,
|
||||
OS: "darwin",
|
||||
})
|
||||
env.On("Error", testify_.Anything)
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return("foo")
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
OS: "darwin",
|
||||
})
|
||||
|
||||
for k, v := range tc.Env {
|
||||
env.On("Getenv", k).Return(v)
|
||||
}
|
||||
|
||||
Init(env)
|
||||
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: tc.Context,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, err := tmpl.Render()
|
||||
|
@ -271,7 +267,7 @@ func TestRenderTemplateEnvVar(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCleanTemplate(t *testing.T) {
|
||||
func TestPatchTemplate(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
Expected string
|
||||
|
@ -294,27 +290,27 @@ func TestCleanTemplate(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Case: "Same prefix",
|
||||
Expected: "{{ .Env.HELLO }} {{ .Data.World }} {{ .Data.WorldTrend }}",
|
||||
Expected: "{{ (call .Getenv \"HELLO\") }} {{ .Data.World }} {{ .Data.WorldTrend }}",
|
||||
Template: "{{ .Env.HELLO }} {{ .World }} {{ .WorldTrend }}",
|
||||
},
|
||||
{
|
||||
Case: "Double use of property with different child",
|
||||
Expected: "{{ .Env.HELLO }} {{ .Data.World.Trend }} {{ .Data.World.Hello }} {{ .Data.World }}",
|
||||
Expected: "{{ (call .Getenv \"HELLO\") }} {{ .Data.World.Trend }} {{ .Data.World.Hello }} {{ .Data.World }}",
|
||||
Template: "{{ .Env.HELLO }} {{ .World.Trend }} {{ .World.Hello }} {{ .World }}",
|
||||
},
|
||||
{
|
||||
Case: "Hello world",
|
||||
Expected: "{{.Env.HELLO}} {{.Data.World}}",
|
||||
Expected: "{{(call .Getenv \"HELLO\")}} {{.Data.World}}",
|
||||
Template: "{{.Env.HELLO}} {{.World}}",
|
||||
},
|
||||
{
|
||||
Case: "Multiple vars",
|
||||
Expected: "{{.Env.HELLO}} {{.Data.World}} {{.Data.World}}",
|
||||
Expected: "{{(call .Getenv \"HELLO\")}} {{.Data.World}} {{.Data.World}}",
|
||||
Template: "{{.Env.HELLO}} {{.World}} {{.World}}",
|
||||
},
|
||||
{
|
||||
Case: "Multiple vars with spaces",
|
||||
Expected: "{{ .Env.HELLO }} {{ .Data.World }} {{ .Data.World }}",
|
||||
Expected: "{{ (call .Getenv \"HELLO\") }} {{ .Data.World }} {{ .Data.World }}",
|
||||
Template: "{{ .Env.HELLO }} {{ .World }} {{ .World }}",
|
||||
},
|
||||
{
|
||||
|
@ -343,12 +339,19 @@ func TestCleanTemplate(t *testing.T) {
|
|||
Template: `{{.Segments.Git.Repo}}`,
|
||||
},
|
||||
}
|
||||
|
||||
env := &mock.Environment{}
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
Init(env)
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: map[string]any{"OS": "posh"},
|
||||
}
|
||||
tmpl.cleanTemplate()
|
||||
|
||||
tmpl.patchTemplate()
|
||||
assert.Equal(t, tc.Expected, tmpl.Template, tc.Case)
|
||||
}
|
||||
}
|
||||
|
@ -368,16 +371,16 @@ func TestSegmentContains(t *testing.T) {
|
|||
segments.Set("Git", "foo")
|
||||
env.On("DebugF", testify_.Anything, testify_.Anything).Return(nil)
|
||||
env.On("TemplateCache").Return(&cache.Template{
|
||||
Env: make(map[string]string),
|
||||
Segments: segments,
|
||||
})
|
||||
env.On("Flags").Return(&runtime.Flags{})
|
||||
env.On("Shell").Return("foo")
|
||||
|
||||
Init(env)
|
||||
|
||||
for _, tc := range cases {
|
||||
tmpl := &Text{
|
||||
Template: tc.Template,
|
||||
Context: nil,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
text, _ := tmpl.Render()
|
||||
|
|
Loading…
Reference in a new issue