Skip to content

Commit

Permalink
feat(template): add global Version property
Browse files Browse the repository at this point in the history
  • Loading branch information
JanDeDobbeleer committed Feb 27, 2025
1 parent 34d2f84 commit 10e63b2
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 70 deletions.
7 changes: 5 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
"args": [
"prompt",
"print",
"primary",
"right",
"--shell=pwsh",
"--terminal-width=200"
]
],
"env": {
"POSH_THEME": "C:\\Users\\jande\\.posh.omp.jsonc"
}
},
{
"name": "Tooltip",
Expand Down
11 changes: 6 additions & 5 deletions src/cache/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ type Template struct {
SegmentsCache maps.Simple
Segments *maps.Concurrent
Var maps.Simple
ShellVersion string
AbsolutePWD string
PWD string
Folder string
PSWD string
UserName string
HostName string
PWD string
ShellVersion string
Shell string
Folder string
AbsolutePWD string
OS string
Code int
Version string
PromptCount int
SHLVL int
Jobs int
Code int
WSL bool
Root bool
}
Expand Down
10 changes: 5 additions & 5 deletions src/segments/battery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import (

type Battery struct {
base

*battery.Info
Error string
Icon string
battery.Info
}

const (
Expand All @@ -34,15 +33,16 @@ func (b *Battery) Enabled() bool {
return false
}

var err error
b.Info, err = b.env.BatteryState()
info, err := b.env.BatteryState()

if !b.enabledWhileError(err) {
return false
}

b.Info = *info

// case on computer without batteries(no error, empty array)
if err == nil && b.Info == nil {
if err == nil && b.Info.Percentage == 0 {
return false
}

Expand Down
2 changes: 2 additions & 0 deletions src/template/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
"time"

"github.com/jandedobbeleer/oh-my-posh/src/build"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/log"
"github.com/jandedobbeleer/oh-my-posh/src/maps"
Expand Down Expand Up @@ -36,6 +37,7 @@ func loadCache(vars maps.Simple) {
Cache.PromptCount = env.Flags().PromptCount
Cache.Var = make(map[string]any)
Cache.Jobs = env.Flags().JobCount
Cache.Version = build.Version

if vars != nil {
Cache.Var = vars
Expand Down
30 changes: 4 additions & 26 deletions src/template/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,22 @@ const (
)

var (
shell string
env runtime.Environment
knownVariables []string
shell string
env runtime.Environment
knownFields *maps.Concurrent
)

func Init(environment runtime.Environment, vars maps.Simple) {
env = environment
shell = env.Shell()
knownFields = maps.NewConcurrent()

renderPool = sync.Pool{
New: func() any {
return newTextPoolObject()
},
}

knownVariables = []string{
"Root",
"PWD",
"AbsolutePWD",
"PSWD",
"Folder",
"Shell",
"ShellVersion",
"UserName",
"HostName",
"Code",
"Env",
"OS",
"WSL",
"PromptCount",
"Segments",
"SHLVL",
"Templates",
"Var",
"Data",
"Jobs",
}

if Cache != nil {
return
}
Expand Down
74 changes: 46 additions & 28 deletions src/template/text.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/jandedobbeleer/oh-my-posh/src/log"
"github.com/jandedobbeleer/oh-my-posh/src/regex"
)

type Text struct {
Expand All @@ -31,29 +30,6 @@ func (t *Text) Render() (string, error) {
}

func (t *Text) patchTemplate() {
isKnownVariable := func(variable string) bool {
variable = strings.TrimPrefix(variable, ".")
splitted := strings.Split(variable, ".")

if len(splitted) == 0 {
return true
}

variable = splitted[0]
// check if alphanumeric
if !regex.MatchString(`^[a-zA-Z0-9]+$`, variable) {
return true
}

for _, b := range knownVariables {
if variable == b {
return true
}
}

return false
}

fields := make(fields)
fields.init(t.Context)

Expand All @@ -70,10 +46,12 @@ func (t *Text) patchTemplate() {
inTemplate = false
}
}

if !inTemplate {
result += string(char)
continue
}

switch char {
case '.':
var lastChar rune
Expand All @@ -96,9 +74,6 @@ func (t *Text) patchTemplate() {
}

switch {
case !isKnownVariable(property):
// end of a variable, needs to be appended
result += ".Data" + property
case strings.HasPrefix(property, ".Segments") && !strings.HasSuffix(property, ".Contains"):
// as we can't provide a clean way to access the list
// of segments, we need to replace the property with
Expand Down Expand Up @@ -149,10 +124,48 @@ func (f *fields) init(data any) {
val := reflect.TypeOf(data)
switch val.Kind() { //nolint:exhaustive
case reflect.Struct:
name := val.Name()

// ignore the base struct
if name == "base" {
return
}

// check if we already know the fields of this struct
if kf, OK := knownFields.Get(name); OK {
for key := range kf.(fields) {
(*f)[key] = true
}
return
}

// Get struct fields and check embedded types
fieldsNum := val.NumField()
for i := 0; i < fieldsNum; i++ {
(*f)[val.Field(i).Name] = true
field := val.Field(i)
(*f)[field.Name] = true

// If this is an embedded field, get its methods too
if !field.Anonymous {
continue
}

embeddedType := field.Type

// Recursively check if the embedded type is also a struct
if embeddedType.Kind() == reflect.Struct {
f.init(reflect.New(embeddedType).Elem().Interface())
}
}

// Get pointer methods
ptrType := reflect.PointerTo(val)
methodsNum := ptrType.NumMethod()
for i := 0; i < methodsNum; i++ {
(*f)[ptrType.Method(i).Name] = true
}

knownFields.Set(name, *f)
case reflect.Map:
m, ok := data.(map[string]any)
if !ok {
Expand All @@ -168,6 +181,11 @@ func (f *fields) init(data any) {

func (f fields) hasField(field string) bool {
field = strings.TrimPrefix(field, ".")

// get the first part of the field
splitted := strings.Split(field, ".")
field = splitted[0]

_, ok := f[field]
return ok
}
42 changes: 38 additions & 4 deletions src/template/text_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func TestRenderTemplate(t *testing.T) {
type Me struct {
Name string
}

cases := []struct {
Context any
Case string
Expand Down Expand Up @@ -161,6 +162,11 @@ func TestRenderTemplate(t *testing.T) {
Context: tc.Context,
}

env := new(mock.Environment)
env.On("Shell").Return("foo")
Cache = new(cache.Template)
Init(env, nil)

text, err := tmpl.Render()
if tc.ShouldError {
assert.Error(t, err)
Expand Down Expand Up @@ -204,7 +210,7 @@ func TestRenderTemplateEnvVar(t *testing.T) {
},
{Case: "no env var", Expected: "hello world", Template: "{{.Text}} world", Context: struct{ Text string }{Text: "hello"}},
{Case: "map", Expected: "hello world", Template: "{{.Text}} world", Context: map[string]any{"Text": "hello"}},
{Case: "empty map", Expected: " world", Template: "{{.Text}} world", Context: map[string]string{}},
{Case: "empty map", Expected: " world", Template: "{{.Text}} world", Context: map[string]string{}, ShouldError: true},
{
Case: "Struct with duplicate property",
Expected: "posh",
Expand Down Expand Up @@ -335,22 +341,50 @@ func TestPatchTemplate(t *testing.T) {
},
}

env := &mock.Environment{}
env := new(mock.Environment)
env.On("Shell").Return("foo")

Cache = new(cache.Template)
Init(env, nil)

for _, tc := range cases {
tmpl := &Text{
Template: tc.Template,
Context: map[string]any{"OS": "posh"},
Context: map[string]any{
"OS": true,
"World": true,
"WorldTrend": "chaos",
"Working": true,
"Staging": true,
"CPU": true,
},
}

tmpl.patchTemplate()
assert.Equal(t, tc.Expected, tmpl.Template, tc.Case)
}
}

type Foo struct{}

func (f *Foo) Hello() string {
return "hello"
}

func TestPatchTemplateStruct(t *testing.T) {
env := new(mock.Environment)
env.On("Shell").Return("foo")
Cache = new(cache.Template)
Init(env, nil)

tmpl := &Text{
Template: "{{ .Hello }}",
Context: Foo{},
}

tmpl.patchTemplate()
assert.Equal(t, "{{ .Data.Hello }}", tmpl.Template)
}

func TestSegmentContains(t *testing.T) {
cases := []struct {
Case string
Expand Down
1 change: 1 addition & 0 deletions website/docs/configuration/templates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ it with `.$` to reference it directly.
| `.WSL` | `boolean` | in WSL yes/no |
| `.Templates` | `string` | the [templates][templates] result |
| `.PromptCount` | `int` | the prompt counter, increments with 1 for every prompt invocation |
| `.Version` | `string` | the Oh My Posh version |

## Environment variables

Expand Down

0 comments on commit 10e63b2

Please sign in to comment.